pax_global_header00006660000000000000000000000064147770017110014517gustar00rootroot0000000000000052 comment=64b9da1e9f15eeff4ec9d6bc856538db542118f2 jsoncons-1.3.2/000077500000000000000000000000001477700171100133565ustar00rootroot00000000000000jsoncons-1.3.2/.circleci/000077500000000000000000000000001477700171100152115ustar00rootroot00000000000000jsoncons-1.3.2/.circleci/config.yml000066400000000000000000000007011477700171100171770ustar00rootroot00000000000000# Use the latest 2.1 version of CircleCI pipeline process engine. See: https://circleci.com/docs/2.0/configuration-reference version: 2.1 # Use a package of configuration called an orb. orbs: # Declare a dependency on the welcome-orb welcome: circleci/welcome-orb@0.4.1 # Orchestrate or schedule a set of jobs workflows: # Name the workflow "welcome" welcome: # Run the welcome/run job in its own container jobs: - welcome/run jsoncons-1.3.2/.clang-tidy000066400000000000000000000007371477700171100154210ustar00rootroot00000000000000# Copyright 2013-2024 Daniel Parker # Distributed under the Boost license, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # See https://github.com/danielaparker/jsoncons for latest version # Revisit: # fuchsia-virtual-inheritance Checks: 'misc-header-include-cycle, misc-include-cleaner, llvm-header-guard' CheckOptions: - key: hicpp-special-member-functions.AllowSoleDefaultDtor value: 1 WarningsAsErrors: '*' jsoncons-1.3.2/.clang-tidy.bak000066400000000000000000000070051477700171100161500ustar00rootroot00000000000000# Copyright 2013-2024 Daniel Parker # Distributed under the Boost license, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # See https://github.com/danielaparker/jsoncons for latest version # Revisit: # fuchsia-virtual-inheritance Checks: '*, -llvm-else-after-return, -readability-else-after-return, -cppcoreguidelines-avoid-c-arrays, -hicpp-avoid-c-arrays, -modernize-avoid-c-arrays, -fuchsia-virtual-inheritance, -modernize-return-braced-init-list, -readability-avoid-nested-conditional-operator, -google-readability-casting, -bugprone-branch-clone, -hicpp-named-parameter, -readability-named-parameter, -bugprone-throw-keyword-missing, -portability-template-virtual-member-function, -bugprone-use-after-move, -hicpp-invalid-access-moved, -altera-id-dependent-backward-branch, -altera-struct-pack-align, -altera-unroll-loops, -android-cloexec-fopen, -boost-use-ranges, -bugprone-easily-swappable-parameters, -cert-err58-cpp, -concurrency-mt-unsafe, -cppcoreguidelines-avoid-const-or-ref-data-members, -cppcoreguidelines-avoid-do-while, -cppcoreguidelines-avoid-goto, -cppcoreguidelines-avoid-magic-numbers, -cppcoreguidelines-avoid-non-const-global-variables, -cppcoreguidelines-macro-usage, -cppcoreguidelines-pro-bounds-array-to-pointer-decay, -cppcoreguidelines-pro-bounds-constant-array-index, -cppcoreguidelines-pro-bounds-pointer-arithmetic, -cppcoreguidelines-pro-type-reinterpret-cast, -cppcoreguidelines-pro-type-union-access, -cppcoreguidelines-rvalue-reference-param-not-moved, -cppcoreguidelines-virtual-class-destructor, -fuchsia-default-arguments-calls, -fuchsia-default-arguments-declarations, -fuchsia-overloaded-operator, -google-explicit-constructor, -google-readability-function-size, -google-runtime-int, -google-runtime-references, -hicpp-avoid-goto, -hicpp-explicit-conversions, -hicpp-function-size, -hicpp-no-array-decay, -hicpp-no-assembler, -hicpp-signed-bitwise, -hicpp-uppercase-literal-suffix, -llvm-header-guard, -llvm-include-order, -llvmlibc-*, -misc-use-anonymous-namespace, -misc-confusable-identifiers, -misc-include-cleaner, -misc-no-recursion, -misc-non-private-member-variables-in-classes, -modernize-concat-nested-namespaces, -modernize-type-traits, -modernize-use-constraints, -modernize-use-designated-initializers, -modernize-use-integer-sign-comparison, -modernize-use-nodiscard, -modernize-use-ranges, -modernize-use-std-numbers, -modernize-use-trailing-return-type, -performance-enum-size, -readability-function-cognitive-complexity, -readability-function-size, -readability-identifier-length, -readability-magic-numbers, -readability-redundant-access-specifiers, -readability-simplify-boolean-expr, -readability-uppercase-literal-suffix, -readability-hicpp-named-parameter' CheckOptions: - key: hicpp-special-member-functions.AllowSoleDefaultDtor value: 1 WarningsAsErrors: '*' jsoncons-1.3.2/.doozer.json000066400000000000000000000021701477700171100156310ustar00rootroot00000000000000{ "targets": { "centos7-x86_64": { "buildenv": "centos7-x86_64", "builddeps": ["gcc-c++", "make", "wget"], "environment": { "CXXFLAGS": "-std=c++11 -Wall -g3" }, "buildcmd": [ "uname -a", "rpm -q centos-release", "g++ --version", "cd", "wget https://github.com/Kitware/CMake/releases/download/v3.14.0/cmake-3.14.0.tar.gz", "tar xfz cmake-3.14.0.tar.gz", "cd cmake-3.14.0", "./bootstrap", "make -j8", "cd", "cmake-3.14.0/bin/cmake . -DBUILD_TESTS=ON", "cmake-3.14.0/bin/cmake --build . --target unit_tests", "cd test", "./unit_tests;" ] }, "fedora24-x86_64": { "buildenv": "fedora24-x86_64", "builddeps": ["cmake", "make", "gcc gcc-c++"], "environment": { "CXXFLAGS": "-std=c++11 -Wall -g3" }, "buildcmd": [ "uname -a", "cat /etc/fedora-release", "g++ --version", "cmake . -DBUILD_TESTS=ON", "cmake --build . --target unit_tests", "cd test", "./unit_tests;" ] } } } jsoncons-1.3.2/.github/000077500000000000000000000000001477700171100147165ustar00rootroot00000000000000jsoncons-1.3.2/.github/FUNDING.yml000066400000000000000000000001101477700171100165230ustar00rootroot00000000000000github: danielaparker custom: https://paypal.me/jsoncons?locale.x=en_US jsoncons-1.3.2/.github/ISSUE_TEMPLATE/000077500000000000000000000000001477700171100171015ustar00rootroot00000000000000jsoncons-1.3.2/.github/ISSUE_TEMPLATE/bug_report.md000066400000000000000000000010561477700171100215750ustar00rootroot00000000000000--- name: Bug report about: Create a report to help us improve title: '' labels: Bug assignees: '' --- **Describe the bug** **Enumerate the steps to reproduce the bug** **Include a small, self-contained example if possible** **What compiler, architecture, and operating system?** - Compiler: ________ - Architecture (e.g. x86, x64) ____ - Operating system: ________ **What jsoncons library version?** - [ ] Latest release 1.3.2 - [ ] Other release ______ - [ ] master jsoncons-1.3.2/.github/ISSUE_TEMPLATE/config.yml000066400000000000000000000003131477700171100210660ustar00rootroot00000000000000blank_issues_enabled: false contact_links: - name: Discuss url: https://github.com/danielaparker/jsoncons/discussions about: Ask questions and initiate discussions with other community members jsoncons-1.3.2/.github/ISSUE_TEMPLATE/feature_request.md000066400000000000000000000004631477700171100226310ustar00rootroot00000000000000--- name: Feature request about: Propose a new feature for this library title: '' labels: Feature request assignees: '' --- **Describe the proposed feature** **What other libraries (C++ or other) have this feature?** **Include a code fragment with sample data that illustrates the use of this feature** jsoncons-1.3.2/.github/btn_support.PNG000066400000000000000000000062001477700171100176410ustar00rootroot00000000000000PNG  IHDRG̒sRGBgAMA a pHYs$$c IDATx^KYceD0 D ];0MŰw!@V%qY] ;A6gi8&tdַVk>bUSsoiŻ\r~Z\A^x_8L2ʗx#" ? Ewv4B++i5; B'W4 W%fZ0Ǵ f8.+&FVPَJ9s)0;8 P<.&qjØ'Dsnl9;\j]WNACB2\t9i,O(oosZ6D7w1l6y'+'ýb6j'F"N4t-@ >_}H8oN7EP6B>5A2J\4Is?GRMZK <|NG?4Zjb2`5Tsq|{%W%_׫r]h>bSty{ziL+k|!ƆqI.޸2.VlMwO3/3#qǥKWzRw)# \j8ͭ]z/y/5<ӲDvE^ :R(pg6\Di Ҕ!q]SYL$$vt%ŭs餁?I-j#jc\qpz;ڨ6Ȫm>f@Lα[4U;(0K/3Osg&EҒ-5YaQ9fPEa-HӦf|fp" })[C f)ƴ 丏FcyhÐv#Y;KN#Q6q?+/uP!ف%gU岆Muq c'}'*It'?;۬9~^en^_zf Ւj&G5Nלd݋1 #uaSBa>5ڿ{ |+^]lEVkٺHh h.=C[c)eg %d3Am[G\q YƦA\z5&VL(mjE >Qǽ_ĕ^ .kD>޾'hʂ:V&ra횞6fL{=tr'Df5g|kmҮ1s uhQ|Ȭegqr9E4L$09kl ( =?CE#u=R"_qy( '~ WK=bvTgGKvB9sTcM yh S9Eu:({b<<оfZPΉ|S*9yVɸ;nX2#{ !E!EdB?N+$۩͗,J&_L胀^Nc*N@$DY+]C WiibFm` \ݟ )mTYwXZ(FZ:zZԝ-N>OuX p{IBN@˽ e٨&vO銹*E潔6t>9K@WE d&ف\`[c1d5#4=2H؁EEF3mvbk9H?(GcI SGKF4ȟߠŬ Ǘv~|#At[&48GVu_k d}F)m-X37a )񗇜r,Pׯ0.9' HpIk"_yq&s^Ps7 #gZ>yݎ8u$6g{W^yJ:קBqʋF>sL|{%YG+/D>A8%R}3[@I}/&{oAAZH5[H[Y}{W[Z_d)%S<*#8QU DW2Ύ}%~ B W 7[)+!,BA9S 2RA(xRi'"DX[2 dgF<|cR' B++ *i<cskBWR#gg ҡ ? dOewo+" 0 O I^ 5sMQIENDB`jsoncons-1.3.2/.github/dependabot.yml000066400000000000000000000003041477700171100175430ustar00rootroot00000000000000version: 2 updates: # Maintain dependencies for GitHub Actions - package-ecosystem: "github-actions" directory: "/" open-pull-requests-limit: 10 schedule: interval: "weekly" jsoncons-1.3.2/.github/workflows/000077500000000000000000000000001477700171100167535ustar00rootroot00000000000000jsoncons-1.3.2/.github/workflows/cifuzz.yml000066400000000000000000000012751477700171100210150ustar00rootroot00000000000000name: CIFuzz on: [pull_request] jobs: Fuzzing: runs-on: ubuntu-latest steps: - name: Build Fuzzers id: build uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master with: oss-fuzz-project-name: 'jsoncons' dry-run: false language: c++ - name: Run Fuzzers uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master with: oss-fuzz-project-name: 'jsoncons' fuzz-seconds: 600 dry-run: false language: c++ - name: Upload Crash uses: actions/upload-artifact@v4 if: failure() && steps.build.outcome == 'success' with: name: artifacts path: ./out/artifacts jsoncons-1.3.2/.github/workflows/clang-tidy.yml.bak000066400000000000000000000012651477700171100222710ustar00rootroot00000000000000name: clang-tidy on: push: paths-ignore: - 'README.md' - 'CHANGELOG.md' - 'doc/**' pull_request: paths-ignore: - 'README.md' - 'CHANGELOG.md' - 'doc/**' jobs: clang-tidy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: submodules: recursive - run: sudo apt-get install -yq clang-tidy - run: find include/ -name '*.hpp' | xargs -I '{}' clang-tidy --quiet '{}' -- --std=c++17 -Iinclude -Iinclude/jsoncons -Iinclude/jsoncons_ext - run: find test/ -name '*.cpp' | xargs -I '{}' clang-tidy --quiet '{}' -- --std=c++17 -Iinclude -Iinclude/jsoncons -Iinclude/jsoncons_ext -Itest/thirdparty jsoncons-1.3.2/.github/workflows/codeql-analysis.yml000066400000000000000000000036461477700171100225770ustar00rootroot00000000000000name: "Code scanning - action" on: push: branches: [develop, ] pull_request: # The branches below must be a subset of the branches above branches: [develop] schedule: - cron: '0 19 * * 1' permissions: contents: read jobs: CodeQL-Build: permissions: actions: read # for github/codeql-action/init to get workflow details contents: read # for actions/checkout to fetch code security-events: write # for github/codeql-action/autobuild to send a status report runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. fetch-depth: 2 # If this run was triggered by a pull request event, then checkout # the head of the pull request instead of the merge commit. - run: git checkout HEAD^2 if: ${{ github.event_name == 'pull_request' }} # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v3 # Override language selection by uncommenting this and choosing your languages # with: # languages: go, javascript, csharp, python, cpp, java # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild uses: github/codeql-action/autobuild@v3 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines # and modify them (or add more) to build your code if your project # uses a compiled language #- run: | # make bootstrap # make release - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 jsoncons-1.3.2/.github/workflows/codeql.yml000066400000000000000000000026211477700171100207460ustar00rootroot00000000000000name: "Code Scanning - Action" on: pull_request: jobs: CodeQL-Build: # CodeQL runs on ubuntu-latest, windows-latest, and macos-latest runs-on: ubuntu-latest permissions: # required for all workflows security-events: write steps: - name: Checkout repository uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v3 # Override language selection by uncommenting this and choosing your languages # with: # languages: go, javascript, csharp, python, cpp, java # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below). - name: Autobuild uses: github/codeql-action/autobuild@v3 # ℹ️ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun # ✏️ If the Autobuild fails above, remove it and uncomment the following # three lines and modify them (or add more) to build your code if your # project uses a compiled language #- run: | # make bootstrap # make release - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 jsoncons-1.3.2/.github/workflows/macos.yml000066400000000000000000000041071477700171100206020ustar00rootroot00000000000000name: macOS on: [push, pull_request] permissions: contents: read jobs: # xcode_11: # strategy: # fail-fast: false # matrix: # xcode: ['11','12','13'] # runs-on: macos-11 # # steps: # - uses: actions/checkout@v4 # with: # submodules: recursive # - uses: maxim-lobanov/setup-xcode@v1 # with: # xcode-version: ${{ matrix.xcode }} # - name: cmake # run: cmake -S . -B build -DJSONCONS_SANITIZE=ON -DCMAKE_BUILD_TYPE=Debug -DJSONCONS_BUILD_TESTS=On # - name: build # working-directory: build/ # run: cmake --build . # - name: test # working-directory: build/ # run: ctest --output-on-failure # xcode_12: # strategy: # fail-fast: false # matrix: # xcode: ['13','14'] # runs-on: macos-12 # # steps: # - uses: actions/checkout@v4 # with: # submodules: recursive # - uses: maxim-lobanov/setup-xcode@v1 # with: # xcode-version: ${{ matrix.xcode }} # - name: cmake # run: cmake -S . -B build -DJSONCONS_SANITIZE=ON -DCMAKE_BUILD_TYPE=Debug -DJSONCONS_BUILD_TESTS=On # - name: build # working-directory: build/ # run: cmake --build . # - name: test # working-directory: build/ # run: ctest --output-on-failure xcode_2: runs-on: macos-latest steps: - uses: actions/checkout@v4 - name: cmake run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DJSONCONS_BUILD_TESTS=On -DCMAKE_CXX_STANDARD=17 -DCMAKE_CXX_STANDARD_REQUIRED=ON - name: build run: cmake --build build --parallel 10 - name: test run: cd build ; ctest -j 10 --output-on-failure xcode_3: runs-on: macos-latest steps: - uses: actions/checkout@v4 - name: cmake run: cmake -S . -B build -DJSONCONS_SANITIZE=ON -DCMAKE_BUILD_TYPE=Debug -DJSONCONS_BUILD_TESTS=On -DCMAKE_CXX_STANDARD=17 -DCMAKE_CXX_STANDARD_REQUIRED=ON - name: build run: cmake --build build --parallel 10 - name: test run: cd build ; ctest -j 10 --output-on-failure jsoncons-1.3.2/.github/workflows/ubuntu.yml000066400000000000000000000147321477700171100210270ustar00rootroot00000000000000name: Ubuntu on: [push, pull_request] permissions: contents: read jobs: github_20: strategy: fail-fast: false matrix: compiler: - g++-12 build_type: [Debug, Release] runs-on: ubuntu-latest env: CXX: ${{ matrix.compiler }} steps: - uses: actions/checkout@v4 - name: cmake run: cmake -S . -B build -DCMAKE_CXX_STANDARD=20 -DCMAKE_CXX_STANDARD_REQUIRED=ON -DJSONCONS_BUILD_TESTS=On - working-directory: build/ run: cmake --build . --config ubuntu-latest - working-directory: build/ run: ctest -C ubuntu-latest --output-on-failure gcc_build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: install_gcc run: | sudo apt update sudo apt install gcc-10 g++-10 shell: bash - name: cmake run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DJSONCONS_BUILD_TESTS=On env: CC: gcc-10 CXX: g++-10 - working-directory: build/ run: cmake --build . --config ubuntu-latest - working-directory: build/ run: ctest -C ubuntu-latest --output-on-failure gcc_build12: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: install_gcc run: | sudo apt update sudo apt install gcc-11 g++-11 shell: bash - name: cmake run: cmake -S . -B build -DJSONCONS_SANITIZE=ON -DCMAKE_BUILD_TYPE=Debug -DJSONCONS_BUILD_TESTS=On env: CC: gcc-11 CXX: g++-11 - working-directory: build/ run: cmake --build . --config ubuntu-latest - working-directory: build/ run: ctest -C ubuntu-latest --output-on-failure gcc_build_no_deprecated: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: install_gcc run: | sudo apt update sudo apt install gcc-10 g++-10 shell: bash - name: cmake run: cmake -S . -B build -DCXXFLAGS="-DJSONCONS_NO_DEPRECATED" -DCMAKE_BUILD_TYPE=Debug -DJSONCONS_BUILD_TESTS=On env: CC: gcc-10 CXX: g++-10 - working-directory: build/ run: cmake --build . --config ubuntu-latest - working-directory: build/ run: ctest -C ubuntu-latest --output-on-failure gcc_build11b: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: install_gcc run: | sudo apt update sudo apt install g++-11 shell: bash - name: cmake run: cmake -S . -B build -DJSONCONS_SANITIZE=ON -DLLVM_CXX_STD=c++17 -DCMAKE_BUILD_TYPE=Release -DJSONCONS_BUILD_TESTS=On env: CXX: g++-11 - working-directory: build/ run: cmake --build . --config ubuntu-latest - working-directory: build/ run: ctest -C ubuntu-latest --output-on-failure #clang_13_build: # runs-on: ubuntu-latest # # steps: # - uses: actions/checkout@v4 # - name: install_gcc # run: | # sudo apt update # sudo apt install clang-13 # shell: bash # - name: cmake # run: cmake -S . -B build -DJSONCONS_SANITIZE=ON -DCMAKE_BUILD_TYPE=Release -DJSONCONS_BUILD_TESTS=On # env: # CC: clang-13 # CXX: clang++-13 # # - working-directory: build/ # run: cmake --build . --config ubuntu-latest # # - working-directory: build/ # run: ctest -C ubuntu-latest --output-on-failure clang_14_build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: install_gcc run: | sudo apt update sudo apt install clang-14 shell: bash - name: cmake run: cmake -S . -B build -DJSONCONS_SANITIZE=ON -DCMAKE_BUILD_TYPE=Release -DJSONCONS_BUILD_TESTS=On env: CC: clang-14 CXX: clang++-14 - working-directory: build/ run: cmake --build . --config ubuntu-latest - working-directory: build/ run: ctest -C ubuntu-latest --output-on-failure ci_test_compilers_gcc: runs-on: ubuntu-latest strategy: matrix: compiler: ['8','9','10','11','12','latest'] container: gcc:${{ matrix.compiler }} steps: - uses: actions/checkout@v4 - name: Get latest CMake and ninja uses: lukka/get-cmake@v4.0.0 - name: cmake run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DJSONCONS_BUILD_TESTS=On - name: build working-directory: build/ run: cmake --build . - name: test working-directory: build/ run: ctest --output-on-failure ci_test_compilers_gcc2: runs-on: ubuntu-latest strategy: matrix: compiler: ['12','latest'] container: gcc:${{ matrix.compiler }} steps: - uses: actions/checkout@v4 - name: Get latest CMake and ninja uses: lukka/get-cmake@v4.0.0 - name: cmake run: cmake -S . -B build -DJSONCONS_SANITIZE=ON -DCMAKE_BUILD_TYPE=Debug -DJSONCONS_BUILD_TESTS=On - name: build working-directory: build/ run: cmake --build . - name: test working-directory: build/ run: ctest --output-on-failure ci_test_compilers_clang: runs-on: ubuntu-latest strategy: matrix: compiler: ['3.8', '3.9', '4', '5', '6', '7','8','9', '10', '11', '12', '13', '14', '15-bullseye'] container: silkeh/clang:${{ matrix.compiler }} steps: - name: Install unzip and git run: apt-get update ; apt-get install -y unzip git - uses: actions/checkout@v4 - name: Get latest CMake and ninja uses: lukka/get-cmake@v4.0.0 - name: cmake run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DJSONCONS_BUILD_TESTS=On - name: build working-directory: build/ run: cmake --build . - name: test working-directory: build/ run: ctest --output-on-failure ci_test_compilers_clang2: runs-on: ubuntu-latest strategy: matrix: compiler: ['13', '15-bullseye'] container: silkeh/clang:${{ matrix.compiler }} steps: - name: Install unzip and git run: apt-get update ; apt-get install -y unzip git - uses: actions/checkout@v4 - name: Get latest CMake and ninja uses: lukka/get-cmake@v4.0.0 - name: cmake run: cmake -S . -B build -DJSONCONS_SANITIZE=ON -DCMAKE_BUILD_TYPE=Debug -DJSONCONS_BUILD_TESTS=On - name: build working-directory: build/ run: cmake --build . - name: test working-directory: build/ run: ctest --output-on-failure jsoncons-1.3.2/.github/workflows/windows.yml000066400000000000000000000052741477700171100212000ustar00rootroot00000000000000name: Windows on: push: paths-ignore: - 'README.md' - 'doc/**' pull_request: paths-ignore: - 'README.md' - 'doc/**' jobs: vs2022: strategy: fail-fast: false matrix: build_type: [Debug, Release] architecture: [x64, x86] runs-on: windows-latest steps: - uses: actions/checkout@v4 with: submodules: recursive - run: cmake -E make_directory build - shell: bash working-directory: build/ run: cmake $GITHUB_WORKSPACE -G "Visual Studio 17 2022" -DJSONCONS_BUILD_TESTS=On -DCMAKE_CXX_STANDARD=17 -DCMAKE_CXX_STANDARD_REQUIRED=ON - working-directory: build/ run: cmake --build . --config ${{ matrix.build_type }} - working-directory: build/ run: ctest -C ${{ matrix.build_type }} --output-on-failure vs2022-clang: strategy: fail-fast: false matrix: build_type: [Debug, Release] architecture: [x64, x86] runs-on: windows-latest steps: - uses: actions/checkout@v4 with: submodules: recursive - run: cmake -E make_directory build - shell: bash working-directory: build/ run: cmake $GITHUB_WORKSPACE -G "Visual Studio 17 2022" -T ClangCL -DJSONCONS_BUILD_TESTS=On - working-directory: build/ run: cmake --build . --config ${{ matrix.build_type }} - working-directory: build/ run: ctest -C ${{ matrix.build_type }} --output-on-failure vs2019: strategy: fail-fast: false matrix: build_type: [Debug, Release] architecture: [x64, x86] runs-on: windows-2019 steps: - uses: actions/checkout@v4 with: submodules: recursive - run: cmake -E make_directory build - shell: bash working-directory: build/ run: cmake $GITHUB_WORKSPACE -G "Visual Studio 16 2019" -DJSONCONS_BUILD_TESTS=On - working-directory: build/ run: cmake --build . --config ${{ matrix.build_type }} - working-directory: build/ run: ctest -C ${{ matrix.build_type }} --output-on-failure vs2019-clang: strategy: fail-fast: false matrix: build_type: [Debug, Release] architecture: [x64, x86] runs-on: windows-2019 steps: - uses: actions/checkout@v4 with: submodules: recursive - run: cmake -E make_directory build - shell: bash working-directory: build/ run: cmake $GITHUB_WORKSPACE -G "Visual Studio 16 2019" -T ClangCL -DJSONCONS_BUILD_TESTS=On - working-directory: build/ run: cmake --build . --config "${{ matrix.build_type }}" - working-directory: build/ run: ctest --build-config "${{ matrix.build_type }}" --progress --verbose jsoncons-1.3.2/.gitignore000066400000000000000000000012151477700171100153450ustar00rootroot00000000000000**/.vs *.sln *.suo *.sdf *.VC.opendb *.VC.db *.vcxproj.user *.vcxproj.filters **/x64/Debug/ **/x64/Release/ **/Debug/ **/Release/ **/*.vcxproj **/vs2017 **/vs2015 **/vs2013 **/temp **/build *PVS-Studio* examples/output **/tests.suppress examples/build/cmake/build_llvm.sh examples/build/cmake/build_llvm src/jsoncons/json_structures.hpp.orig examples/build/vs2013/ src/jsoncons/json_serializer2.hpp examples/booklist.json examples/booklist2.json examples/build/vs2017/.vs/vs2017/v15/ipch/AutoPCH/2f913b3e9413499/BASICS_EXAMPLES.ipch examples/build/vs2017/.vs/vs2017/v15/ipch/AutoPCH/8571a45cc244269f/EXAMPLES.ipch examples/build/vs2017/vs2017.sln jsoncons-1.3.2/.travis.yml.bak000066400000000000000000000156151477700171100162330ustar00rootroot00000000000000language: cpp dist: xenial sudo: required matrix: include: - os: linux addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-4.8 - libgmp-dev env: COMPILER=gcc VERSION=4.8 CXXFLAGS="-std=c++11" - os: linux addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-4.8 - libgmp-dev env: COMPILER=gcc VERSION=4.8 CXXFLAGS="-std=c++11 -Wnoexcept" - os: linux addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-4.9 - libgmp-dev env: COMPILER=gcc VERSION=4.9 JSONCONS_SANITIZE=1 CXXFLAGS="-std=c++11" - os: linux addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-5 env: COMPILER=gcc VERSION=5 CXXFLAGS="-std=gnu++11" - os: linux addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-6 env: COMPILER=gcc VERSION=6 JSONCONS_SANITIZE=1 - os: linux addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-7 env: COMPILER=gcc VERSION=7 JSONCONS_SANITIZE=1 - os: linux addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-8 env: COMPILER=gcc VERSION=8 JSONCONS_SANITIZE=1 CXXFLAGS="-std=c++17 -Wall -Wextra -Wimplicit-fallthrough -pedantic -Wcast-align -Wcast-qual" - os: linux addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-8 env: COMPILER=gcc VERSION=8 JSONCONS_SANITIZE=1 CXXFLAGS="-std=c++17 -Werror -Wall -Wextra -Wimplicit-fallthrough -pedantic -Wcast-align -Wcast-qual" - os: linux addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-8 env: COMPILER=gcc VERSION=8 JSONCONS_SANITIZE=1 CXXFLAGS="-std=c++17 -DJSONCONS_HAS_STRING_VIEW" - os: linux addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-9 env: COMPILER=gcc VERSION=9 JSONCONS_SANITIZE=1 CXXFLAGS="-std=c++17 -Werror -Wall -Wextra -Wimplicit-fallthrough -pedantic -Wcast-align -Wcast-qual" - os: linux addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-9 env: COMPILER=gcc VERSION=9 JSONCONS_SANITIZE=1 CXXFLAGS="-std=c++17 -Wnoexcept -Werror -Wall -Wextra -Wimplicit-fallthrough -pedantic -Wcast-align -Wcast-qual" - os: linux addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-9 env: COMPILER=gcc VERSION=9 JSONCONS_SANITIZE=1 CXXFLAGS="-std=c++2a -DJSONCONS_HAS_STRING_VIEW" - os: linux addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-8 env: COMPILER=gcc VERSION=8 JSONCONS_SANITIZE=1 CXXFLAGS="-std=gnu++17 -Wall -Wextra -Wimplicit-fallthrough" - os: linux addons: apt: sources: - ubuntu-toolchain-r-test - llvm-toolchain-xenial-4.0 packages: - clang-4.0 - g++-7 env: COMPILER=clang VERSION=4.0 CXXFLAGS="-std=c++11" - os: linux addons: apt: sources: - ubuntu-toolchain-r-test - llvm-toolchain-xenial-5.0 packages: - clang-5.0 - g++-7 env: COMPILER=clang VERSION=5.0 CXXFLAGS="-std=gnu++11" - os: linux addons: apt: sources: - ubuntu-toolchain-r-test - llvm-toolchain-xenial-6.0 packages: - clang-6.0 - g++-7 env: COMPILER=clang VERSION=6.0 JSONCONS_SANITIZE=1 CXXFLAGS="-std=c++11 -Wall -Wextra -Wimplicit-fallthrough" - os: linux addons: apt: sources: - ubuntu-toolchain-r-test - llvm-toolchain-xenial-6.0 packages: - clang-6.0 - g++-7 env: COMPILER=clang VERSION=6.0 JSONCONS_SANITIZE=1 CXXFLAGS="-std=c++11 -Wnoexcept -Wall -Wextra -Wimplicit-fallthrough" - os: linux addons: apt: sources: - ubuntu-toolchain-r-test - llvm-toolchain-xenial-7 packages: - clang-7 - g++-7 env: COMPILER=clang VERSION=7 CXXFLAGS="-DJSONCONS_NO_DEPRECATED" - os: linux addons: apt: sources: - ubuntu-toolchain-r-test - llvm-toolchain-xenial-8 packages: - clang-8 - g++-8 env: COMPILER=clang VERSION=8 CXXFLAGS="-DJSONCONS_NO_DEPRECATED" - os: osx osx_image: xcode9.3 compiler: clang env: CXXFLAGS="-std=c++11" - os: osx osx_image: xcode9.4 compiler: clang env: CXXFLAGS="-std=c++11" - os: osx osx_image: xcode10 compiler: clang env: CXXFLAGS="-std=c++17" - os: osx osx_image: xcode10.1 compiler: clang env: CXXFLAGS="-std=c++14" - os: osx osx_image: xcode10.2 compiler: clang env: CXXFLAGS="-std=c++17" - os: osx osx_image: xcode11.2 compiler: clang env: CXXFLAGS="-std=c++17" - os: osx osx_image: xcode11.2 compiler: clang env: CXXFLAGS="-std=c++17 -Wnoexcept" - os: osx osx_image: xcode12 compiler: clang env: CXXFLAGS="-std=c++14" - os: osx osx_image: xcode12 compiler: clang env: CXXFLAGS="-std=c++17" before_install: - | # Configure build variables if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then if [[ "$COMPILER" == "gcc" ]]; then export CXX=g++-$VERSION CC=gcc-$VERSION; fi if [[ "$COMPILER" == "clang" ]]; then export CXX=clang++-$VERSION CC=clang-$VERSION; fi elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export CXX=clang++ CC=clang; fi install: # get CMake (only for systems with brew - macOS) - | if [[ (-x $(which brew)) ]]; then brew update brew install cmake brew upgrade cmake cmake --version fi - cmake . -DBUILD_TESTS=ON ${CMAKE_OPTIONS}; - make -j2 test_jsoncons - cd tests script: - if [[ "$JSONCONS_VALGRIND" == 1 ]]; then ctest -T memcheck; fi - if [[ "$CROSS_COMPILE" == 1 ]]; then if [[ "$ARM_ARCH_DIR" == "aarch64-linux-gnu" ]]; then qemu-aarch64 -L /usr/aarch64-linux-gnu/ ./test_jsoncons ; else qemu-arm -L /usr/arm-linux-gnueabi/ ./test_jsoncons ; fi else ./test_jsoncons; fi jsoncons-1.3.2/CHANGELOG.md000066400000000000000000004716411477700171100152040ustar00rootroot000000000000001.3.2 ----- - Fixed bug: - Git Issue #607: Fixed issue with `staj_object_view` and `staj_array_view` iterators that got introduced as a consequence of a change in 1.3.1 1.3.1 ----- - Fixed bugs: - Git Issue #601: Removed the space before the suffix in the user-defined literal operators `_json` and `_ojson` - Git Issue #605: Fixed bug when parsing a JMESPath expression that has a function that is passed a binary expression argument, e.g. A || B. - In cursors, after a call to `read_to` following a `begin_object` event, the cursor `event_type()` function returned `staj_event_type::begin_object`, even though the effective state of the cursor had changed to `staj_event_type::end_object`. This is fixed. The state of the cursor after a call to `next` is the same as before. - Fixed an edge case in `basic_csv_parser`, detected by Google fuzz, where the first line in the input file contains an empty line and the `csv_mapping_kind` is `n_rows`. - API Changes: - In JMESPath evaluation, 1.3.0 introduced late binding of variables to an initial (global) scope via parameters. The parameters type has been changed from `std::vector>` to `std::map`. - Added a member function `begin_position()` to `ser_context`. `begin_position()` should be preferred to `position()` when [using filters to update JSON in place](https://github.com/danielaparker/jsoncons/blob/master/examples/src/update_json_in_place_examples.cpp). Currently the two accessors return the same value, but that may change in a future release. - Added macros **JSONCONS_VISITOR_RETURN_TYPE** and **JSONCONS_VISITOR_RETURN** that are #define'd to `bool` and `return true` respectively. For users that have implemented classes that derive from `basic_json_filter`, and that have overridden `visit_xxx` functions, it is recommended to use these macros for the return type and return value rather than `bool` and `return true`. This is for forward compatibility. 1.3.0 ----- - Fixed bugs: - Git Issue #600: Added "-Wnull-dereference" to CI and worked around some false positives. - Git Issue #597: Invalid json schema compiled successfully - Git Issue #595: SIGABRT when serialising unmapped enum value - Fixed a jmespath issue with parenthesized expressions involving projections (wildcard expressions, the flatten operator, slices and filter expressions) where the right parenthesis did not stop the projection. For example, given JSON `{"foo" : [[0, 1], [2, 3]]}`, the JMESPath query `(foo[*])[0]` returned `[0,2]` rather than the correct `[0,1]`. - Fixed a `json_encoder` formatting issue when `array_object_line_splits` option set to `line_split_kind::same_line`. - Implemented new features: - JMESPath Lexical Scoping using the new [let expression](https://github.com/jmespath/jmespath.jep/blob/main/proposals/0018-lexical-scope.md) - JMESPath evaluation now supports late binding of variables to an initial (global) scope via parameters. - New `json_options` members `allow_comments` and `allow_trailing_comma`. These options should be preferred over using an error handler. 1.2.0 ----- - Fixed bugs: - Git Issue #453: jsonpath length function with recursive select argument gives wrong result - Implemented new features: - Git issue #556: Support nested JSON to CSV. Add `flat`, `column_mapping`, and `max_nesting_depth` options to `basic_csv_options` - Git issue #585: Add `raw_tag()` accessor to `basic_cbor_cursor`. Add functions `begin_object_with_tag`, `begin_array_with_tag`, `uint64_value_with_tag` etc. to `basic_cbor_encoder` to support encoding values with raw CBOR tags. - Git issue #574: Support custom JSON Schema error messages with `errorMessage` keyword. Add `enable_custom_error_message` option to `evaluation_options`. 1.1.0 ----- - API Changes - Reverted changes to `basic_json_parser` API introduced in 1.0.0, cf Git issue #576 - Fixed bugs: - Git Issue #554: Made headers self-contained 1.0.0 ----- - API Changes - Non-const `basic_json::operator[const string_view_type& key]` no longer returns a proxy type. The rationale for this change is given in Git Issue #315. The new behavior for the non-const overload of `operator[](const string_view_type& key)` is to return a reference to the value that is associated with `key`, inserting a default constructed value with the key if no such key already exists, which is consistent with the standard library `std::map` behavior. The new behavior for the const overload of `operator[](const string_view_type& key)` is to return a const reference to the value that is associated with `key`, returning a const reference to a default constructed value with static storage duration if no such key already exists. - Until 1.0.0, a buffer of text is supplied to `basic_json_parser` with a call to `update()` followed by a call to `parse_some()`. Once the parser reaches the end of the buffer, additional JSON text can be supplied to the parser with another call to `update()`, followed by another call to `parse_some()`. See [Incremental parsing (until 1.0.0)](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/basic_json_parser.md#incremental-parsing-until-01790). Since 0.179, an initial buffer of text is supplied to the parse with a call to `set_buffer`, and parsing commences with a call to `parse_some`. The parser can be constructed with a user provided chunk reader to obtain additional JSON text as needed. See [Incremental parsing (since 1.0.0)](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/basic_json_parser.md#incremental-parsing-since-01790). - enum `bigint_chars_format` is deprecated and replaced by `bignum_format_kind`. Added `bignum_format` getter and setter functions to `basic_json_options`, and deprecated `bigint_format` getter and setter functions. Changed default `bignum_format` from `bigint_chars_format::base10` to `bignum_format_kind::raw`. Rationale: `bigint_chars_format` was misnamed, as it applied to `bigdec` as well as `bigint` numbers, and defaulting to `bigint_chars_format::base10` produced surprising results for users of our lossless number option. - The URI argument passed to the jsonschema ResolveURI function object now included the fragment part of the URI. - Fixed bugs: - Git Issue #554: [jsonpath] evaluation throws on json containing json_const_pointer - Git PR #560: [jmespath] When there are elements and the sum is indeed zero, avg function should return average value returned instead of a null value. - Git Issue #561: json_string_reader does not work correctly for empty string or string with all blanks - Git Issue #564: Fixed basic_json compare of double and non-numeric string - Git Issue #570: Fixed writing fixed number of map value/value pairs using cbor_encoder and msgpack_encoder - Fixed a number of issues in `uri::resolve`, used in jsonschema, related to abnormal references, particulay ones containing dots in path segments. - Removed deprecated classes and functions: - The jsonschema function `make_schema`, classes `json_validator` and `validation_output`, header file `json_validator.hpp` and example `legacy_jsonschema_examples.cpp`, deprecated in 0.174.0, have been removed. - Enhancements: - Added stream output operator (`<<`) to uri class. - Added `basic_json(json_pointer_arg_t, basic_json* j)` constructor to allow a `basic_json` value to contain a non-owning view of another `basic_json` value. - Added constant `null_arg` so that a null json value can be constructed with ``` json j{jsoncons::null_arg}; ``` - Custom jmespath functions are now supported thanks to PR #560 - jsonschema now understands the 'uri' and 'uri-reference' formats 0.178.0 ------- Defect fixes: - Fixed issue with `jmespath::join function` through PR #546 - Fixed issue with the path for cmake config files through PR #547 - Related to #539, made the basic_json constructor `basic_json(const Allocator&)` consistent with `basic_json(json_object_arg_t, const Allocator& alloc = Allocator())`. - Related to #539, `basic_json` copy construction now applies allocator traits `select_on_container_copy_construction` to the allocator obtained from `other`. For pmr allocators, this gives a default constructed pmr allocator rather than a copy of the allocator in `other`. Enhancements: - Improved the implementation of `basic_json` swap. Previously in some cases it would allocate. - Improved the implementation of `basic_json` copy assignment. Reduced allocations when assigning from array to array and object to object. - Documented the rules for `basic_json` allocators [here](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/json/allocators.md), and added numerous tests for conformance to the rules. - Added missing `basic_json` constructor ``` basic_json(json_array_arg_t, std::size_t count, const basic_json& value, semantic_tag tag = semantic_tag::none, const Allocator& alloc = Allocator()); ``` 0.177.0 ------- Changes - Removed deprecated functions and type names identified in #487 - Reduced the size of some initial `json_parser` allocations to help with #531 Defect fixes - Fixed #530 by making `jmespath_expression::evaluate` const - Fixed #488 related to some standard libraries that don't support strings with stateful allocators. - Fixed issue identified in PR #532 with `basic_json::compare` function 0.176.0 ------- Compiler support - Update to [Supported compilers](https://github.com/danielaparker/jsoncons?tab=readme-ov-file#supported-compilers) documentation to reflect the compilers that are currently in continuous integration testing. - Support for some ancient compilers, in particular g++ 4.8 and 4.9, has been dropped. - Accepted pr #519 to support build with with llvm-toolset-7 on CentOS 7. - We (and users) have seen some compilation errors with tests of `std::scoped_allocator_adaptor` using our sample stateful allocator `FreeListAllocator` in versions of clang predating version 11, and versions of g++ predating version 10. We've therefore excluded these tests when testing with the older compilers. Enhancements - `basic_json` now supports using C++ 17 structured binding, so you can write ``` for (const auto& [key, value] : j.object_range()) { std::cout << key << " => " << value << std::endl; } ``` - Addressed issue #509 of over allocating memory due to alignment constraints through pr #510 jsonschema library defect fixes: - Fixed issue #520 where enabling format validation resulted in a premature abort to validation - Addressed issue #521 so that jsonschema now supports big integers Other defect fixes: - Resolved #518 about CUDA and int128 and float 128 0.175.0 ------- This release contains two breaking changes to recently added features. Change to jsonpath::get function - The return value for `jsonpath::get` has been changed from a pointer to the selected JSON value, or null if not found, to a `std::pair`, where the bool component indicates whether the get operation succeeded. Change to new jsonschema classes and functions introduced in 0.174.0: - The overload of `json_schema::validate` that takes a callback must now be passed a lambda that returns `walk_result::advance` or `walk_result::abort`. This supports early exit from validation. Note that this change does not affect the legacy pre-0.174.0 jsonschema classes and functions (`make_schema`, `json_validator`). Enhancement to jsonschema library: - New `json_schema` member function `walk` for walking through the schema. 0.174.0 ------- Defect fixes: - Fixed issue #499 with `nan_to_str`, `inf_to_str` and `neginf_to_str` Core library enhancements - New `json_options` `line_splits` option that addresses issue #490 jsonpath library enhancements - New function `jsonpath::replace` analagous to `jsonpointer::replace`, but for normalized paths. jsonschema library enhancements - The jsonschema extension now supports Drafts 4, 6, 2019-09 and 2020-12 in addition to Draft 07. - New function `make_json_schema` that returns a representation of a compiled JSON Schema document. - New class `validation_message` - The legacy function `make_schema` and classes `json_validator` and `validation_output` remain for backward compatibility, but have been deprecated. 0.173.4 ------- Defect fixes - Fixed issue #485 where `basic_json` member names did not use `polymorphic_allocator` - Addressed issue #482 by replacing `static_assert` with runtime exception 0.173.3 ------- Defect fixes: - Made all member functions of [jsoncons::range](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/json/range.md) const 0.173.2 ------- - Removed use of deduced return types in jsonpath extension (C++ 14 feature) 0.173.1 ------- - Fixed issue #473 about `bigint` and `-Werror=stringop-overflow` 0.173.0 ------- Defect fixes: - Fixed issue #473 about `bigint` and `-Werror=stringop-overflow` - Fixed jmespath issue #471 about `jmespath::search` and `ojson` with `AddressSanitizer` in macos environment - Fixed jsonpointer issue with `json_pointer::parse` for empty string keys (which had implications for jsonschema `definitions` keyword with empty keys.) - Fixed jsonschema issue with `definitions` keyword with empty keys - Fixed jsonschema issue #474 about JSON Schema maximum keyword error message - Fixed jsonschema issue with `multipleOf` keyword and type integer and `multipleOf` a floating point number - Fixed jsonschema issue with the behavior of `$id` for rebasing in some keywords, particularly `if`, `then`, and `else`. Enhancements: - The `jsonschema::make_schema` functions now support providing a retrieval URI, to initialize the base URI. 0.172.1 ------- Defect fixes: - Fixed issue #470 concerning jsonpath::make_expression with ec broken 0.172.0 ------- Defect fixes: - Fixed issue #469 affecting JSMESPath expressions with terminating CR Enhancements to jsonpath - Added `result_option` `sort_descending`. - Added new classes `basic_json_location`, `basic_path_element`, and `basic_path_node`. - Added a new function `get` for selecting a single JSON value from a JSON document at a location represented by a `json_location`. - Added a new function `remove` for removing a single JSON value from a JSON document at a location represented by a `json_location`. - Added member function `select` to `jsonpath_expression`. - Added member function `select_paths` to `jsonpath_expression`. - Added member function `update` to `jsonpath_expression`, to support update-in-place for compiled JSONPath expressions. Enhancements to jsonpointer: - Added free functions `to_string` and `to_wstring`. - Added `append` function to `basic_json_pointer`. 0.171.1 ------- Defect fixes: - Fixed issue #441 concerning misaligned allocation for string data. - Fixed issue #436 concerning overflow warning. - Changed internal variable names to avoid shadow warnings - Fixed signature of `dump_pretty` #438 - Fixed `basic_json_decode_options` constructor #437 Enhancements: - Improved error messages (with field names) for invalid type mappings when using the `json_type_traits` convenience macros. - Support char8_t and u8string for C++ 20 - Added compare for bigint/bigdec/bigfloat as double or exact text match. This makes JSON Query work if you use `options.lossless_number(true)` for parsing JSON. 0.171.0 ------- Enhancements: - `basic_json` supports allocators that automatically propagate, - `std::pmr::polymorphic_allocator` - `std::scoped_allocator_adaptor` - Defines aliases and alias templates for `basic_json` using polymorphic allocators in the `jsoncons::pmr` namespace. ``` namespace jsoncons { namespace pmr { template using basic_json = jsoncons::basic_json>; using json = basic_json; using wjson = basic_json; using ojson = basic_json; using wojson = basic_json; }} ``` - Added a class `allocator_set` for holding an allocator for persistent data and an allocator for temporary allocations. - Added the ability to pass an `allocator_set` object to functions `basic_json::parse`, `decode_json`, `decode_csv`, `decode_bson`, `decode_cbor`, `decode_msgpack`, `decode_ubjson`, `encode_json`, `encode_csv`, `encode_bson`, `encode_cbor`, `encode_msgpack`, `encode_ubjson`. - Added the ability to set a JSON parse error handler through options (rather than as a separate parameter.) - Added an error handler `allow_trailing_commas` Changes: - For users creating a custom `basic_json` with a user provided `Policy`, the name `string` in `Policy` must be changed to `member_key`. - Non-propagating stateful allocators are no longer supported. Attempting to use a regular stateful allocator will produce a compile error. Regular stateful allocators must be wrapped with [std::scoped_allocator_adaptor](https://en.cppreference.com/w/cpp/memory/scoped_allocator_adaptor) - Until 0.171.0, the `basic_json` functions `try_emplace`, `emplace`, and `emplace_back` allowed an allocator argument, and one was required when using stateful allocators. Since 0.171.0, `try_emplace`, `emplace`, and `emplace_back` must not be passed an allocator argument, because both `std::pmr::polymorphic_allocator` and `std::scoped_allocator_adaptor` use uses-allocator construction. Note: Non-stateful custom allocators are supported as before. - The tag type `result_allocator_arg_t` and constant `result_allocator_arg` have been deprecated. - The `jsonpath::json_replace` function no longer supports an optional `result_options` parameter. - The order preserving versions of `basic_json`, `ojson` and `wojson`, no longer use indexes to support search, but rely on sequential search instead. The feedback from users was that the additional allocations and overhead wasn't worth any gains, particularly as the number of members in JSON objects is typically not large. Defect fixes - Fixed issue danielaparker/jsoncons/#430 with `jsonpath::json_replace` 0.170.2 ------- Defect fixes - Fixed issue with jsonschema default values (introduced in 0.170.0) 0.170.1 ------- Defect fixes: - Fixed issue danielaparker/jsoncons/#418 where use of `std::aligned_storage` produced a diagnostic that it is deprecated in C++2023. - Fixed issue danielaparker/jsoncons/#420 where `to_integer_base16` produced warnings when passed a wide character string. - Fixed issue danielaparker/jsoncons/#391 where parsing JSON resulted in temporary allocations from `std::stable_sort` - Fixed issue danielaparker/jsoncons/#421 where PVS-Studio found vulnerabilities in code. - Fixed issue danielaparker/jsoncons/#425 where `basic_byte_string::assign` and `basic_byte_string::append` failed to compile - Fixed issue danielaparker/jsoncons/#426 where enum keyed maps didn't serialize correctly. 0.170.0 ------- Changed: - Removed static functions `jsonpath_expression::compile`. These have long been superceded with function `make_expression`. Defect fixes: - Fixed issue danielaparker/jsoncons/#416 where `length` operator failed for array of length zero. - Fixed issue danielaparker/jsoncons/#411 where an overeager g++ 12.2.0 compiler reported a spurious `stringop-overflow` warning. - Fixed issue danielaparker/jsoncons/#410 where `jsoncons::jsonpath::json_location::to_string` escaped only single quotes. - Merged PR danielaparker/jsoncons/#406 that fixed multiple float parsing and boolean pretty print issues with wjson. This included reverting a change to use `std::from_chars` in 0.169.0. Enhancements: - The jsonpath library now works with stateful allocators. In particular, the `make_expression`, `json_query` and `json_replace` functions now accept an allocator argument for use in allocating memory during expression compilation and evaluation. - Merged PR danielaparker/jsoncons/#395 that added a `ser_context::end_position()` function. 0.169.0 ------- Defect fixes: - Fixed issue with boost_interprocess examples not working with gcc, contributed by [raplonu](https://github.com/raplonu) - Fixed and enhance basic_json_diagnostics_visitor, contributed by [ecorm](https://github.com/ecorm) - Fixed [Visual Studio 2022 Preview 17.4.0 compilation errors](https://github.com/danielaparker/jsoncons/issues/387) Performance Enhancement: - Use `std::from_chars` for chars to double conversion when supported in GCC and VC. Enhancements: - Added a `size()` accessor function to `basic_staj_event`. If the event type is a `key` or a `string_value` or a `byte_string_value`, returns the size of the key or string or byte string value. If the event type is a `begin_object` or a `begin_array`, returns the size of the object or array if known, otherwise 0. For all other event types, returns 0. - Extended the parsers/cursors/encoder for JSON, CBOR, Msgpack, BSON, CSV, UBJSON so that they are resettable to new sources/sinks, contributed by [ecorm](https://github.com/ecorm) Changes: - For consistency with library naming conventions, the directory `include/jsoncons/json_merge_patch` has been renamed to `include/jsoncons/mergepatch`, the namespace `json_merge_patch` to `mergepatch`, and the include file `json_merge_patch.hpp` to `mergepatch.hpp`. 0.168.7 ------- Defect fixes: - In release 0.167.0, the `csv_options::mapping()` accessor was renamed to `csv_options::mapping_kind()`, and the old name was deprecated but still useable. That release neglected to similarily rename the corresponding mutator, which is now addressed. - Fixed csv parsing issue [Exponential formatted numbers with leading zeros in exponent](https://github.com/danielaparker/jsoncons/issues/365) - Fixed [Issue with assignment of an object_iterator to const_object_iterator using empty object](https://github.com/danielaparker/jsoncons/issues/372). This issue affects some xcode osx users. 0.168.6 ------- Bug Fix: - Fixed an issue with the order preserving `ojson` erase function that takes two iterator arguments. Enhancement: - The `basic_json::erase` function return value, previously void, is now an iterator following the last removed element, ``` array_iterator erase(const_array_iterator pos); object_iterator erase(const_object_iterator pos); array_iterator erase(const_array_iterator first, const_array_iterator last); object_iterator erase(const_object_iterator first, const_object_iterator last); ``` See [Issue \#363](https://github.com/danielaparker/jsoncons/issues/363) 0.168.5 ------- Issues fixed: - Fixed issue #355, "Array move constructor of basic_json copies provided array". 0.168.4 ------- Issues fixed: - Fixed [issue \#352](https://github.com/danielaparker/jsoncons/issues/352) regarding `json_type_traits` macro failure when number of parameters reached 47. Enhancement: Increased maximum number of parameters in `json_type_traits` macros from 50 to 70. 0.168.3 ------- Issues fixed: - Preseve original error messages when decoding into C++ data structures (related to [issue \#345](https://github.com/danielaparker/jsoncons/issues/345)) - Fixed [issue \#348](https://github.com/danielaparker/jsoncons/issues/348)) concerning compilation issue on OSx with C++11 0.168.2 ------- Issues fixed: - Fixed [issue \#343](https://github.com/danielaparker/jsoncons/issues/343) concerning segfault using JMESPath with Apple clang version 12.0.0 and x86_64-apple-darwin19.6.0. - Fixed [issue \#344](https://github.com/danielaparker/jsoncons/issues/344) concerning compile error with gcc on archlinux with `-Werror=nonnull`. 0.168.1 ------- Bugs fixed: - Fixed jsonpath issue of normalized path component not being computed for expression, [issue \#338](https://github.com/danielaparker/jsoncons/issues/338). 0.168.0 ------- Bugs fixed: - Fixed [issue \#335](https://github.com/danielaparker/jsoncons/issues/335). The 0b... notation used in a cbor header file has been replaced with 0x... notation. The 0b... notation used is only standard compliant with C++14 and later, although supported in some C++ 11 compilers. - Fixed issue with csv automatic number detection discovered while investigating [issue \#333](https://github.com/danielaparker/jsoncons/issues/333). Enhancements to jsonpointer extension: - Support construction of a `json_pointer` from a URI fragment representation of a JSON Pointer. - Support stringifying a `json_pointer` to a URI fragment representation with the `to_uri_fragment` function. 0.167.1 ------- Bugs fixed: - Fixed compilation error with clang version 8.0.1, [issue \#328](https://github.com/danielaparker/jsoncons/issues/328). 0.167.0 ------- Bugs fixed: - Fixed issue with a json_cursor hanging if opened with an empty file or string, detected by google/OSS-fuzz. - Fixed issue with the unary minus in a JSONPath filter expression, where an expression such as `$[?-@.key > -42]` would fail to parse. - Fixed issue with private typedef and Intel C++ Compiler via [PR \#327](https://github.com/danielaparker/jsoncons/pull/327) Changes: - In the csv extension, the enum name `mapping_kind` has been renamed to `csv_mapping_kind`, and the `csv_options.mapping` function has been renamed to `csv_options.mapping_kind`. The old names have been deprecated but are still usable. Enhancements: - Added support for JSON Merge Patch. - Added support in JSONPath expressions for '%' (modulus) operator 0.166.0 ------- jsonpath bugs fixed: - Fixed issue with normalized paths produced by JSONPath expressions with filters jsonpath enhancements: - Added support for a parent selector, using the `^' symbol, following [jsonpath-plus](https://www.npmjs.com/package/jsonpath-plus). - Implemented a number of performance optimizations. jsonschema enhancements: - Improved error messages reported when compiling a schema document - Added a check that the "$schema" keyword, if present, is Draft 7. 0.165.0 ------- Enhancements for bson extension: - Added semantic tags float128, id, regex, and code to support bson decode and encode for decimal128, ObjectId, regex, and Javascript code. - Support has been added for ObjectId, regex, decimal128 and the other non-deprecated bson types, as requested in issue [\#321](https://github.com/danielaparker/jsoncons/issues/321). - Parsing now checks that the the number of bytes read for a document, embedded document and array matches the expected total. 0.164.0 ------- Changes to jsonpath: - The values in the `result_options` bitmask have been changed from enum class result_options {value=1, path=2, nodups=4|path, sort=8|path}; (until 0.164.0) to enum class result_options {value=0, nodups=1, sort=2, path=4}; (since 0.164.0) In practice this means that any combination of these values that includes `result_options::value` has the same meaning as before, except that `result_options::value` can now be omitted. And any combination that includes `result_options::path` but not `result_options::value` has the same meaning as before. Enhancements to jsonpath: - Functions now allow expressions to be passed as arguments, e.g. $.books[?(ceil(@.price*100) == 2272)] - User provided custom functions are now supported Changes to json_reader and csv_reader: - The typedefs `json_reader` and `wjson_reader` have been deprecated, but for backwards compatibility they are still supported. They have been replaced by `json_string_reader` and `wjson_string_reader` for string sources, and `json_stream_reader` and `wjson_stream_reader`, for stream sources. - The typedefs `csv_reader` and `wcsv_reader` have been deprecated, but for backwards compatibility they are still supported. They have been replaced by `csv_string_reader` and `wcsv_string_reader` for string sources, and `csv_stream_reader` and `wcsv_stream_reader`, for stream sources. 0.163.3 -------- Bugs fixed: - Fixed a jsonpath issue where the two overloads of json_query and json_replace that took a callback function argument used a deprecated typedef in an SFINAE condition. 0.163.2 -------- Bugs fixed: - Fixed a jmespath issue with reusing compiled expressions, see [\#317](https://github.com/danielaparker/jsoncons/issues/317) 0.163.1 -------- Bugs fixed: - Reversed change made in 0.163.0 to removal of duplicates with the `result_options::nodups`, reverting to previous behaviour (only consider as duplicates nodes with the exact same path starting from the root.) That seems to be the consensus. - Fixed a memory leak in jsoncons::jsonpath::node_set, see [\#314](https://github.com/danielaparker/jsoncons/pull/314), also related, [\#316](https://github.com/danielaparker/jsoncons/issues/316) - Fixed some gcc warnings about non-virtual destructors in the jsonpath, jmespath, and jsonschema extensions by making the destructors protected, see [\#313](https://github.com/danielaparker/jsoncons/pull/313). Added the gcc compiler flag `-Wnon-virtual-dtor` for gcc in the `tests/CMakeLists.txt` file. 0.163.0 -------- Bugs fixed: - Fixed a jsonpath issue with removal of duplicates with the `result_options::nodups` flag in the case of a union with different paths 0.162.3 -------- - Fixed a sign-compare warning in android builds, [\#309](https://github.com/danielaparker/jsoncons/issues/309) 0.162.2 -------- - Fixed a sign-compare warning 0.162.1 -------- - Fixed a [gcc warning with -Wsign-compare](https://github.com/danielaparker/jsoncons/issues/307) - `-Wsign-compare` enabled for gcc test builds - Fixed some PVS-Studio warnings 0.162.0 -------- Enhancements to jsonpointer - The jsonpointer functions `get`, `add`, `add_if_absent`, and `replace` have an additonal overload with a `create_if_missing` parameter. If passed `true`, creates key-object pairs when object keys are missing. Enhancements to jsonpath - Improved syntax checking for JSONPath unions - Simplified function signatures for `make_expression`, `json_query`, and `json_replace`. Changes: - The jsonpointer function `insert` has been deprecated and renamed to `add_if_absent`, for consistency with the other names. 0.161.0 -------- The `jsoncons::jsonpath` extension has been rewritten, see [JSONPath extension revisited](https://github.com/danielaparker/jsoncons/issues/306). Enhancements to JSONPath extension - Added a new function `make_expression` for creating a compiled JSONPath expression for later evaluation. - The `json_query` and `json_replace` functions now take an optional `result_options` parameter that allows duplicate values (i.e. values with the same node paths) to be excluded from results, and for results to be sorted in path order. Changes to `json_query` - The parameter `result_type` has been replaced by a bitmask type `result_options`. For backwards compatability, `result_type` has been typedefed to `result_options`, and the `value` and `path` enumerators are still there. In addition, `result_options` provides options for excluding duplicates from results, and for results to be sorted in path order. - Until 0.161.0, `json_query` was limited to returning an array of results, a copy. With 0.161, `json_query` allows the user to provide a binary callback that is passed two arguments - the path of the item and a const reference to the original item. - Until 0.161.0, `json_replace` allowed the user to provide a unary callback to replace an item in the original JSON with a returned value. This overload is still there, but has been deprecated. With 0.161, `json_replace` allows the user to provide a binary callback that is passed two arguments - the path of the item and a mutable reference to the original item. Changes to supported JSONPath syntax - Previous versions allowed optionally omitting the '$' representing the root of the JSON instance in path selectors. This is no longer allowed. In 0.161.0, all path selectors must start with either '$', if relative to the root of the JSON instance, or '@', if relative to the current node. E.g. `store.book.0` is not allowed, rather, `$store.book.0`. - Previous versions supported union of completely separate paths, e.g. `$..[name.first,address.city]`. 0.161.0 does too, but requires that the relative paths `name.first` and `address.city` start with a '@', so the example becomes `$..[@.name.first,@.address.city]` . - Previous versions supported unquoted names with the square bracket notation, this is no longer allowed. E.g. `$[books]` is not allowed, rather `$['books']` or `$["books"]`. - Previous versions allowed an empty string to be passed as a path argument to `json_query`. This is no longer allowed, a syntax error will be raised. - In 0.161.0, unquoted names in the dot notation are restricted to digits `0-9`, letters `A-Z` and `a-z`, the underscore character `_`, and unicode coded characters that are non-ascii. All others names must be enclosed with single or double quotes. In particular, names with hypens (`-`) must be enclosed with single or double quotes. Enhancements to JMESPath extension - Function arity errors are now raised during compilation of the JMESPath expression rather than during evaluation. 0.160.0 -------- Bugs fixed: - A C++20 change caused a `basic_json` overloaded operator '==' to be ambiguous despite there being a unique best viable function. Fixed. - When parsing MessagePack buffers, lengths were being incorrectly parsed as signed integers. Fixed. Enhancements: - Added jsonschema extension that implements the JSON Schema [Draft 7](https://json-schema.org/specification-links.html#draft-7) specification for validating input JSON, [\#280](https://github.com/danielaparker/jsoncons/issues/280) Changes: - Until 0.160.0, `jsonpointer::flatten`, when applied to an an empty array or empty object, would produce a flattened value of `null` rather than `[]` or `{}`. Since 0.160.0, it will produce `[]` or `{}`. For example, given `{"bar":{},"foo":[]}`, the flattened output was {"/bar":null,"/foo":null}, but is now `{"/bar":{},"/foo":[]}`. `jsonpointer::unflatten` will now return the original object. Deprecated function removed: - The long deprecated `basic_json` function `to_string(const basic_json_encode_options&, char_allocator_type&) const` has been removed (replacement is `dump`). 0.159.0 -------- Bugs fixed: - Fixed clang 11 compile issues [\#284](https://github.com/danielaparker/jsoncons/issues/284) and [\#285](https://github.com/danielaparker/jsoncons/issues/285). Changes: - In the jsonpointer extension, the type names `json_ptr` and `wjson_ptr` have been deprecated and renamed to `json_pointer` and `wjson_pointer`. Enhancements: - The json_pointer operators `/=` and `/` now support integers. - New override for `jsonpath::json_replace` that searches for all values that match a JSONPath expression and replaces them with the result of a given function, see [\#279](https://github.com/danielaparker/jsoncons/pull/279) - New factory function `jmespath::make_expression` to create compiled JMESPath expressions. 0.158.0 -------- Bugs fixed: - Fixed compilation error with gcc 11, [\#276](https://github.com/danielaparker/jsoncons/pull/276) (thanks to Laurent Stacul) Changes: - In 0.157.0, the `_NAME_` convenience macros were augmented to allow an optional `mode` parameter (`JSONCONS_RDWR` or `JSONCONS_RDONLY`) and three optional function object parameters, `match` (value matches expected), `from` (convert from type known to jsoncons) and `into` (convert into type known to jsoncons). In this release - 0.158.0 - the order of the `from` and `into` function object parameters has been reversed. If you've provided `from` and `into` function objects as arguments in your json traits convenience macros, you'll need to reverse their order, or if you've provided just a `from` function argument, you'll need to precede it with `jsoncons::identity()` (or `std::identity()` if C++20). For the rationale for this change, see [\#277](https://github.com/danielaparker/jsoncons/issues/277) - Conversion errors during decode are now reported more consistently as `jsoncons::convert_error`, parsing errors remain `jsoncons::ser_error` (`or std::error_code`) as before. 0.157.2 -------- Warnings fixed: - Fixed C20 deprecated move_iterator access with arrow operator. - Fixed PVS-Studio warnings OSS-Fuzz issues fixed: - Fixed OSS-Fuzz failed throw issue 25891 affecting `decode_ubjson` and potentially other decode functions. This means that decode functions will throw a `ser_error` instead of an `assertion_error` in the presence of certain kinds of bad data. 0.157.1 -------- Bugs fixed: - The macros `JSONCONS_ALL_MEMBER_NAME_TRAITS` and `JSONCONS_N_MEMBER_NAME_TRAITS` failed at compile time when provided with exactly two optional member arguments, `JSONCONS_RDWR` followed by a `Match` function object (other cases were fine.) This has been fixed. Change reverted: - The name change `ser_error` to `codec_error` introduced in 0.157.0 has been reverted back to `ser_error`. Just in case anybody used it, the name `codec_error` has been typedefed to `ser_error`. 0.157.0 -------- Changes: - The name `ser_error` has been deprecated and renamed to `codec_error`. Enhancements: - The `_NAME_` convenience macros now allow an optional `mode` parameter (`JSONCONS_RDWR` or `JSONCONS_RDONLY`) and three function objects, `match` (value matches expected), `from` (convert from type known to jsoncons) and `into` (convert into type known to jsoncons), [\#267](https://github.com/danielaparker/jsoncons/issues/267) 0.156.1 --------- Bugs fixed: - Fixed issue with jsonpath exception raised when querying empty string, [\#270](https://github.com/danielaparker/jsoncons/issues/270) - Included pull request [\#273](https://github.com/danielaparker/jsoncons/pull/273) that fixes an issue with a misnamed macro (`BOOST_HAS_FLOAT128` instead of `JSONCONS_HAS_FLOAT128`) introduced in 0.156.0. 0.156.0 --------- Bugs Fixed: - Fixed issue with JSONCONS_N_MEMBER_NAME_TRAITS macro, [\#263](https://github.com/danielaparker/jsoncons/issues/263) Enhancements: - New `basic_json(json_const_pointer_arg_t, const basic_json*)` constructor to allow `basic_json` values to contain non-owning views of other `basic_json` values. - New `deep_copy` function to make a deep copy of a `basic_json` value that contains non-owning views on other `basic_json` values. - Reduced memory allocations in the jmespath extension using the new `basic_json(json_const_pointer_arg_t, const basic_json*)` constructor. - Support for encoding `std::bitset` into `base16` encoded strings (JSON) and byte strings (binary formats), and decoding `std::bitset` from integer values, byte strings and `base16` encoded strings. - Support 128 bit integer types `__int128` and `unsigned __int128`, if supported on the platform. 0.155.1 -------- Enhancements: - Improved support for `bson_parser` to switch to array parsing when the BSON root object is a document but `decode_bson` needs to convert to an `std::array`, `std::tuple` or `std::pair`. 0.155.0 -------- Changes: - The `semantic_tag` enum value `timestamp` has been deprecated. It has been replaced by `epoch_second`, `epoch_milli` and `epoch_nano`. The deprecated `timestamp` value has been aliased to `epoch_second`. Enhancements: - Allow `bson_parser` to switch to array parsing when the root object is a document but `decode_bson` expects an array. - Added `json_type_traits` support for `std::nullptr_t` - Added `json_type_traits` support for `std::chrono::duration` - Improved memory efficiency of jmespath extension - Added function `json_encode_pretty` as the preferred alternative to the `json_encode` overload with `indenting::indent` argument. - Added `basic_json` member function `dump_pretty` as the preferred alternative to the `dump` overload with `indenting::indent` argument. - Generalized the `basic_json` member function `dump` and the functions `encode_json` and `encode_csv` to write to any back insertable character container. - Generalized the `basic_json` function `parse` and the functions `decode_json` and `decode_csv` to read from any contiguous character sequence. 0.154.3 -------- Bugs fixed: - Fixed g++ compile issue with -Wnoexcept compiler flag, [\#260](https://github.com/danielaparker/jsoncons/issues/260) - Fixed issue with creating a patch to remove array elements using `json_patch::from_diff`, [\#261](https://github.com/danielaparker/jsoncons/issues/261) - Fixed memory leak issue introduced in 0.154.2 0.154.2 -------- Withdrawn 0.154.1 -------- Bugs fixed: - Fixed issue with encode_cbor overload for user type input and output stream, [\#259](https://github.com/danielaparker/jsoncons/issues/259) 0.154.0 -------- Bugs fixed: - Fixed issue with escaping special characters in the `jsonpath::flatten` function [\#255](https://github.com/danielaparker/jsoncons/issues/255) - Added workaround for clang xcode 10 bug in `std::optional` implementation - Fixed bug in `basic_json` less operator with left hand side `uint64_value` and right hand side `int64_value` Changes: - The function name `jsonpointer::insert_or_assign` has been deprecated and renamed to `jsonpointer::add`. Rationale: consistency with JSON Patch names. - Until 0.154.0, the `position()` member function of `ser_context` was defined for JSON name and string events only, and indicated the position of the first character of the name or string in the input. Since 0.154.0, the `position()` member function of `ser_context` is defined for all JSON parse events, and indicates the position of the character at the beginning of the event, e.g. '[' for an array, '{' for an object, and '"' for a string. [\#256](https://github.com/danielaparker/jsoncons/issues/256) Enhancements - Added jmespath extension for [JMESPath](https://jmespath.org/) support, [\#204](https://github.com/danielaparker/jsoncons/issues/204) - Added `json_type_traits` support for `std::variant`, [\#257](https://github.com/danielaparker/jsoncons/issues/257) 0.153.3 -------- Bug fixes: - Fixed a bug in jsonpath array slice when the step component is negative and the start and stop components are omitted, [\#252](https://github.com/danielaparker/jsoncons/issues/252). jsoncons jsonpath slices now have the same semantics as Python slices including for negative steps. - Fixed a bug in jsonpath line/column error reporting when using functions. 0.153.2 -------- Bug fixes: - Fixed a bug in jsonpath array slice when the end argument is negative, [\#250](https://github.com/danielaparker/jsoncons/issues/250) Platform: - Support for QNX Neutrino (thanks to Oleh Derevenko for [\#244](https://github.com/danielaparker/jsoncons/issues/244) and [\#245](https://github.com/danielaparker/jsoncons/pull/248)) 0.153.1 -------- Bug fixes for BSON: - Fixed int32 encoding error in the BSON encoder [\#243](https://github.com/danielaparker/jsoncons/issues/243) - Fixed issue with default binary subtype when not specified, was 0, now 0x80 (user defined.) 0.153.0 -------- Bug fixes: - Fixed decode issue with `json_type_traits` defined for `set`, `unordered_set`, `multiset`, `unordered_multiset` and `forward_list` [\#242](https://github.com/danielaparker/jsoncons/issues/242) - Fixed issue with preserving original CBOR semantic tag for CBOR byte strings associated with an unknown (to jsoncons) tag. Enhancements: - `basic_json::parse`, `decode_json`, `decode_csv`, `decode_bson`, `decode_cbor`, `decode_msgpack`, and `decode_ubjson` now support reading data from a pair of LegacyInputIterators that specify a character or byte sequence. - `byte_string_view` now has an explicit constructor that allows any contiguous byte sequence container. 0.152.0 -------- Bug fixes: - Fixed compile error when building with Android SDK level less than 21 [\#240](https://github.com/danielaparker/jsoncons/pull/240) - Fixed bson encode/decode of binary type (wasn't reading/writing subtype.) Changes: - `basic_json_compressed_encoder` has been deprecated and renamed to `basic_compact_json_encoder`. Rationale: consistency with other names. The typedefs `json_compressed_stream_encoder`, `wjson_compressed_stream_encoder`, `json_compressed_string_encoder`, and `wjson_compressed_string_encoder` have been deprecated and renamed to `compact_json_stream_encoder`, `compact_wjson_stream_encoder`, `compact_json_string_encoder`, and `compact_wjson_string_encoder`. - The factory function `make_array_iterator()` has been replaced by `staj_array()`. - The factory function `make_object_iterator()` has been replaced by `staj_object()`. - The constructors for `json_cursor`, `csv_cursor`, `bson_cursor`, `cbor_cursor`, `msgpack_cursor`, and `ubjson_cursor` that take a filter argument have been deprecated. Instead filters may be applied to a cursor using the pipe syntax, e.g. json_cursor cursor(is); auto filtered_c = cursor | filter1 | filter2; Enhancements: - Generalized `basic_json(byte_string_arg_t, ...` constructor to accomodate any contiguous byte sequence container, which is a contiguous container that has member functions `data()` and `size()`, and member type `value_type` with size exactly 8 bits. Any of the values types `int8_t`, `uint8_t`, `char`, `unsigned char` and `std::byte` (since C++17) are allowed. - Generalized the functions `decode_bson`, `decode_cbor`, `decode_msgpack` and `decode_ubjson` to read from any contiguous byte sequence. - Generalized the `json_visitor` member function `byte_string_value` to accept any contiguous byte sequence argument. In particular this means that `byte_string_value` can be called on an encoder with any bytes sequence argument. - Generalized the functions `encode_bson`, `encode_cbor`, `encode_msgpack` and `encode_ubjson` to write to any back insertable byte container. Any of the values types `int8_t`, `uint8_t`, `char`, `unsigned char` and `std::byte` (since C++17) are allowed. - Generalized the `json_type_traits` for maps to accomodate all key types that themselves have json_type_traits defined [\#241](https://github.com/danielaparker/jsoncons/issues/241) - Unknown CBOR tags preceding a byte string (unknown to jsoncons), MessagePack types associated with the MessagePack ext family, and bson binary subtypes associated with a binary value are now captured. - If in `basic_json` `tag()` == `semantic_tag::ext`, the function `ext_tag()` will return a format specific tag associated with a byte string value. - The `basic_json` constructor with parameter `byte_string_arg_t` now allows constructing a byte string associated with a format specific tag. 0.151.1 -------- Bug fixes: - Fixed `jsoncons::semantic_tag::uri`, `jsoncons::semantic_tag::base64` and `jsoncons::semantic_tag::base64url` applied to text strings incorrectly encoded into CBOR [\238](https://github.com/danielaparker/jsoncons/issues/238) 0.151.0 -------- Bug fixes: - Fixed eternal loop in csv parser [\#220](https://github.com/danielaparker/jsoncons/issues/220) - Fixed JSONPath issue with filter expressions containing regular expressions [\#233](https://github.com/danielaparker/jsoncons/issues/233) - Fixed OSS-Fuzz failed throw issue in CSV parser [\#232](https://github.com/danielaparker/jsoncons/issues/232) - Fixed OSS-Fuzz integer-overflow issue in CSV parser [\#231](https://github.com/danielaparker/jsoncons/issues/231) - Fixed OSS-Fuzz timeout issues [\#230](https://github.com/danielaparker/jsoncons/issues/230) - Fixed UBJSON issue parsing arrays with end markers [\#229](https://github.com/danielaparker/jsoncons/issues/229) - Fixed OSS-Fuzz memory allocation issues [\#228](https://github.com/danielaparker/jsoncons/issues/228) - Fixed OSS-Fuzz stack overflow issues [\#225](https://github.com/danielaparker/jsoncons/issues/225) - OSS-Fuzz failed throw issue in CBOR parser [\#235](https://github.com/danielaparker/jsoncons/issues/235) - Msg pack bin8 wrong format [\#237](https://github.com/danielaparker/jsoncons/issues/237) Changes: - The cbor_option name `enable_typed_arrays` has been deprecated and renamed to `use_typed_arrays`. - `jsonpointer::unflatten_method` has been deprecated and replaced with `jsonpointer::unflatten_options`. - The cursor functions named `read` have been deprecated and renamed to `read_to`. Enhancements: - Added classes bson_options, msgpack_options, and ubjson_options - Until this release, only JSON parsing supported a `max_nesting_depth` option. Since this release, JSON, BSON, CBOR, MessagePack and UBJSON all support a `max_nesting_depth` option for both parsing and serializing. The default is 1024. - UBJSON supports a `max_items` option for parsing and serializing. The default is 16,777,216. 0.150.0 -------- Defects fixed: - Fixed jsonpath issue [Union with spaces](https://cburgmer.github.io/json-path-comparison/results/union_with_spaces.html) - Fixed jsonpath issue [Bracket notation with empty string](https://cburgmer.github.io/json-path-comparison/results/bracket_notation_with_empty_string.html) - Fixed jsonpath issue [Bracket notation with empty string doubled quoted](https://cburgmer.github.io/json-path-comparison/results/bracket_notation_with_empty_string_doubled_quoted.html) Changes: - The names `basic_json_content_handler` and `basic_default_json_content_handler` have been deprecated and renamed to `basic_json_visitor` and `basic_default_json_visitor`. The private visitor functions `do_xxx` have been renamed to `visit_xxx`. This change should be transparent to most users. - The name `staj_event_type::name` has been deprecated and renamed to `staj_event_type::key`. Rationale: consistency with other names. The old name is still supported. - The class `null_ser_context` has been deprecated. For defaults, `ser_context()` is now used in place of `null_ser_context()`. Enhancements: - Added jsonpointer `unflatten` function 0.149.0 -------- Defects fixed: - Fixed vs issue (since 0.148.0) with basic_json constructor disambiguation with a combination of type tag and `std::initializer_list` arguments. Non-breaking change: - For consistency with naming conventions across `json_type_traits` convenience macros, macro names containing `GETTER_CTOR` now contain `CTOR_GETTER`, e.g. `JSONCONS_ALL_GETTER_CTOR_NAME_TRAITS` is now `JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS`. The old names are still supported. Enhancements: - Added jsonpath functions `flatten` and `unflatten` that flatten a json object or array to a single depth object of key-value pairs, and unflatten that object back to the original json. 0.148.0 -------- Changes: - The `json_type_traits` convenience macro names ending in `NAMED_TRAITS` have been deprecated and now end in `NAME_TRAITS`, e.g. the old name `JSONCONS_ALL_GETTER_SETTER_NAMED_TRAITS` is now `JSONCONS_ALL_GETTER_SETTER_NAME_TRAITS`. Rationale: name consistency. - Fixed some deprecated `json_type_traits` convenience macro names. All of the convenience macro names that have ever been deprecated should work. Enhancements: - Added overload with leading `temp_allocator_arg_t` parameter to `encode_json`, `encode_bson`, `encode_csv`, `encode_cbor`, `encode_msgpack` and `encode_ubjson`, which allows the user to supply a custom allocator that serialization will use for temporary work areas. 0.147.0 -------- Fixed bugs: - Fixed an issue with the `jsonpatch_error` class implementation of `what()`, likely related to [issue #212 ](https://github.com/danielaparker/jsoncons/issues/212) Enhancements: - Added support to the convenience macros `JSONCONS_N_GETTER_CTOR_TRAITS` and `JSONCONS_ALL_GETTER_CTOR_NAMED_TRAITS` for-non mandatory members to be omitted altogether from the serialized JSON. These macros had been overlooked when this feature was added to the `_N_` macros in 0.146.0. - Added jsonpointer function `flatten` to flatten a json object or array into a single depth object of JSONPointer-value pairs. - Added overload with leading `temp_allocator_arg_t` parameter to `decode_json`, `decode_bson`, `decode_csv`, `decode_cbor`, `decode_msgpack` and `decode_ubjson`, which allows the user to supply a custom allocator that deserialization will use for temporary work areas. 0.146.1 -------- Fixed issue with `json_type_traits` specializations of `std::shared_ptr` and `std::unique_ptr` when converting from JSON null. 0.146.0 -------- Changes: - The name `rename_object_member_filter` has been deprecated and renamed to `rename_object_key_filter` - The `json_content_handler` public function `name` has been deprecated and renamed to `key`. Rationale: in the future we'll likely support overloads for non-string keys for binary formats - The `json_content_handler` private virtual function `do_name` has been removed and replaced with `do_key`. Rationale: in the future we'll likely support overloads for non-string keys for binary formats Enhancements: - New json_type_traits specialization for `std::shared_ptr` for `T` that is not a polymorphic class, i.e., does not have any virtual functions - New json_type_traits specialization for `std::unique_ptr` for `T` that is not a polymorphic class - For the `_N_` convenience macros that allow some non-mandatory members, the generated traits `to_json` function will exclude altogether empty values for `std::shared_ptr` and `std::unique_ptr` non-mandatory members, as they do currently for `std::optional`. 0.145.2 -------- Defect fixes: - Fixed issue with `json_type_traits` specialization for optional 0.145.1 -------- Bug fixes: - Fixed issue with jsoncons::optional 0.145.0 -------- Bug fixes: - Fixed [compiler warning with clang](https://github.com/danielaparker/jsoncons/issues/214) - Fixed [Missing return in typed_array](https://github.com/danielaparker/jsoncons/issues/213) Name changes: - The `json_type_traits` convenience macro names ending in `_DECL` have been shortened by dropping the `_DECL` suffix, e.g. the old name `JSONCONS_N_MEMBER_TRAITS_DECL` is now `JSONCONS_N_MEMBER_TRAITS`. The old names are still supported. Enhancements: - Includes `json_type_traits` specialization for `std::optional` if C++ 17. `nullopt` values are mapped to JSON null values. - When encoding to JSON, the `json_type_traits` convenience macros will exlude altogether a non-mandatory `std::optional` `nullopt` value from the JSON output. 0.144.0 -------- Bug fixes: Fixed issue [json with preserve_order_policy does not preserve order of elements #210](https://github.com/danielaparker/jsoncons/issues/210) Implemented feature requests: - [208](https://github.com/danielaparker/jsoncons/issues/208) Added member function to `basic_json` ``` template T as(byte_string_arg_t, semantic_tag hint) const; ``` 0.143.2 -------- Bug fix: - Fixed bug in destructor of `typed_array` class Enhancement: - Improved performance of decoding CBOR typed arrays 0.143.1 -------- Bug fix: - 0.143.1 fixs a bug in the jsonpath filter < comparison operator that was introduced in 0.143.0 Enhancements: - `j.as()`, `j.as()` etc. supported for binary, octal and hex string values, in addition to decimal string values. - Includes `json_type_traits` specialization for integer keyed maps, with conversion to/from string keys in a `basic_json`. - The `json_type_traits` specializations for type `T` generated by the convenience macros now include a specialization of `is_json_type_traits_declared` with member constant `value` equal `true`. - New `basic_json` member function `json_type type()` - New `basic_json` member function `get_value_or` that gets a value as type `T` if available, or a default value if not: template T get_value_or(const string_view_type& name, U&& default_value) const; `get_value_or` is the preferred alternative to template T get_with_default(const string_view_type& name, const T& default_value) const Note that `get_value_or` requires that the first template parameter `T` be specified explicitly (unlike `get_with_default`) Changes: - The basic_json `get_with_default(name)` function, which returned a const reference to the value if available and to a json null constant if not, has been deprecated and renamed to `at_or_null(name)`. Rationale: `get_with_default(name)` is more like `at(name)` (both return a const reference) than `get_with_default(name,default_value)` (which returns a value.) - The tag type `bstr_arg_t` has been renamed to `byte_string_arg_t`, and the constant `bstr_arg` to `byte_string_arg`. - The `cbor_content_handler` public member functions `typed_array()` and private virtual functions `do_typed_array()` have been moved to `basic_json_content_handler`. The `do_typed_array()` private virtual functions have been given default implementations. `cbor_content_handler` has been deprecated. - Replaced Martin Moene's span-lite with simpler implementation until `std::span` is available (primarily for typed array interface.) 0.142.0 -------- Defect fixes: - Fixed csv documentation showing the wrong header file includes - Fixed jsonpath issue [json_query() is reordering arrays](https://github.com/danielaparker/jsoncons/issues/200) - Fixed jsonpath issue with recursive descent reported in [Alignment on JSONPath implementations across languages](https://github.com/danielaparker/jsoncons/issues/199) 0.141.0 -------- Name change: - The names `JSONCONS_ALL_PROPERTY_TRAITS_DECL`, `JSONCONS_N_PROPERTY_TRAITS_DECL`, `JSONCONS_TPL_ALL_PROPERTY_TRAITS_DECL` and `JSONCONS_N_PROPERTY_TRAITS_DECL` have been deprecated and renamed to `JSONCONS_ALL_GETTER_SETTER_TRAITS_DECL`, `JSONCONS_N_GETTER_SETTER_TRAITS_DECL`,`JSONCONS_TPL_ALL_GETTER_SETTER_TRAITS_DECL` and `JSONCONS_TPL_N_GETTER_SETTER_TRAITS_DECL`. Rationale: naming consistency. Enhancements: - New tag types `json_object_arg_t`, `json_array_arg_t` and `bstr_arg_t` have been introduced that make it simpler to construct `basic_json` values of objects, arrays and byte strings. 0.140.0 -------- Changes to the `json_type_traits` convenience macros: - In [Issue 190](https://github.com/danielaparker/jsoncons/issues/190), Twan Springeling raised an issue with the macro `JSONCONS_GETTER_CTOR_TRAITS_DECL`, that it did not come with "strict" and "non-strict" versions. In this release we introduce new macros, where `_N_` is mnemonic for the number of mandatory properties provided (possibly zero), and _ALL_ is mnemonic for all properties are mandatory: ```c++ JSONCONS_N_GETTER_CTOR_TRAITS_DECL(class_name,num_mandatory_params, getter_name0, getter_name1,...) // (11) JSONCONS_ALL_GETTER_CTOR_TRAITS_DECL(class_name, getter_name0,getter_name1,...) // (12) JSONCONS_TPL_N_GETTER_CTOR_TRAITS_DECL(num_template_params, class_name,num_mandatory_params, getter_name0,getter_name1,...) // (13) JSONCONS_TPL_ALL_GETTER_CTOR_TRAITS_DECL(num_template_params, class_name, getter_name0,getter_name1,...) // (14) JSONCONS_N_GETTER_CTOR_NAMED_TRAITS_DECL(class_name,num_mandatory_params, (getter_name0,"name0"), (getter_name1,"name1")...) // (15) JSONCONS_ALL_GETTER_CTOR_NAMED_TRAITS_DECL(class_name, (getter_name0,"name0"), (getter_name1,"name1")...) // (16) JSONCONS_TPL_N_GETTER_CTOR_NAMED_TRAITS_DECL(num_template_params, class_name,num_mandatory_params, (getter_name0,"name0"), (getter_name1,"name1")...) // (17) JSONCONS_TPL_ALL_GETTER_CTOR_NAMED_TRAITS_DECL(num_template_params, class_name, (getter_name0,"name0"), (getter_name1,"name1")...) // (18) ``` - When the traits generated by e.g. `JSONCONS_N_GETTER_CTOR_TRAITS_DECL` need to pass an argument to a constructor that is not present in the JSON, they pass a default constructed parameter value. The legacy macros e.g. `JSONCONS_GETTER_CTOR_TRAITS_DECL` remain, and have the same meaning as before, but are deprecated. - With the introduction of the `JSONCONS_POLYMORPHIC_TRAITS_DECL` macro, and the support for polymorhic types, there comes a problem with the "non-strict" macros JSONCONS_MEMBER_TRAITS_DECL, JSONCONS_PROPERTY_TRAITS_DECL, JSONCONS_SETTER_GETTER_TRAITS_DECL, etc., when a class has non-mandatory properties. Type selection is based on the presence of properties, but the `json_type_traits` generated by the non-strict macros don't know which properties are mandatory and which non-mandatory, hence type selection becomes impossible when members are absent in the JSON. For this reason, twelve new `_N_` macros have been introduced to allow you to specify which properties are mandatory (`_N_` is mnemonic for number of mandatory properties): ```c++ JSONCONS_N_MEMBER_TRAITS_DECL(class_name,num_mandatory_params, member_name0,member_name1,...) JSONCONS_TPL_N_MEMBER_TRAITS_DECL(num_template_params, class_name,num_mandatory_params, member_name0,member_name1,...) JSONCONS_N_MEMBER_NAMED_TRAITS_DECL(class_name,num_mandatory_params, (member_name0,"name0"), (member_name1,"name1")...) JSONCONS_TPL_N_MEMBER_NAMED_TRAITS_DECL(num_template_params, class_name,num_mandatory_params, (member_name0,"name0"), (member_name1,"name1")...) JSONCONS_N_GETTER_CTOR_TRAITS_DECL(class_name,num_mandatory_params, getter_name0, getter_name1,...) JSONCONS_TPL_N_GETTER_CTOR_TRAITS_DECL(num_template_params, class_name,num_mandatory_params, getter_name0,getter_name1,...) JSONCONS_N_GETTER_CTOR_NAMED_TRAITS_DECL(class_name,num_mandatory_params, (getter_name0,"name0"), (getter_name1,"name1")...) JSONCONS_TPL_N_GETTER_CTOR_NAMED_TRAITS_DECL(num_template_params, class_name,num_mandatory_params, (getter_name0,"name0"), (getter_name1,"name1")...) JSONCONS_N_PROPERTY_TRAITS_DECL(class_name,get_prefix,set_prefix,num_mandatory_params, property_name0,property_name1,...) JSONCONS_TPL_N_PROPERTY_TRAITS_DECL(num_template_params, class_name,get_prefix,set_prefix,num_mandatory_params, property_name0,property_name1,...) JSONCONS_N_GETTER_SETTER_NAMED_TRAITS_DECL(class_name,num_mandatory_params, (getter_name0,setter_name0,"name0"), (getter_name1,setter_name1,"name1")...) JSONCONS_TPL_N_GETTER_SETTER_NAMED_TRAITS_DECL(num_template_params, class_name,num_mandatory_params, (getter_name0,setter_name0,"name0"), (getter_name1,setter_name1,"name1")...) ``` - The legacy non-strict macros remain, and have the same meaning as before, but are deprecated. - For consistency with the new naming, and to allow the legacy `JSONCONS_GETTER_CTOR_TRAITS_DECL` to keep the same meaning for backwards compatibility, the `_STRICT_` names are deprecated and renamed substituting `_ALL_` for `STRICT`. See [json_type_traits](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/json_type_traits.md) for complete documentation of the convenience macros. 0.139.0 -------- Enhancements: - New convenience macro for generating `json_type_traits` from getter and setter functions that will serialize to the stringified property names, ```c++ JSONCONS_PROPERTY_TRAITS_DECL(class_name,get_prefix,set_prefix, property_name0,property_name1,...) JSONCONS_STRICT_PROPERTY_TRAITS_DECL(class_name,get_prefix,set_prefix, property_name0,property_name1,...) JSONCONS_TPL_PROPERTY_TRAITS_DECL(num_template_params, class_name,get_prefix,set_prefix, property_name0,property_name1,...) JSONCONS_TPL_STRICT_PROPERTY_TRAITS_DECL(num_template_params, class_name,get_prefix,set_prefix, property_name0,property_name1,...) ``` - `JSONCONS_POLYMORPHIC_TRAITS_DECL` now specializes `json_type_traits` for `std::unique_ptr` in addition to `std::shared_ptr`. 0.138.0 -------- Defect fix: - Fixes issue in `csv_parser` parsing a CSV file with `mapping_kind::m_columns`, when parsing a quoted string containing a numeric value, processing it as a number rather than as a string. Changes: - It is no longer neccessay to place a semicolon after `JSONCONS_TYPE_TRAITS_FRIEND` Enhancements: - New convenience macro for generating `json_type_traits` for polymorphic types, based on the presence of properties, ```c++ JSONCONS_POLYMORPHIC_TRAITS_DECL(base_class_name,derived_class_name0,derived_class_name1,...) ``` - The convenience macros `JSONCONS_MEMBER_TRAITS_DECL`, `JSONCONS_STRICT_MEMBER_TRAITS_DECL`, `JSONCONS_TPL_MEMBER_TRAITS_DECL`, `JSONCONS_TPL_STRICT_MEMBER_TRAITS_DECL`, `JSONCONS_MEMBER_TRAITS_NAMED_DECL`, `JSONCONS_STRICT_MEMBER_TRAITS_NAMED_DECL`, `JSONCONS_TPL_MEMBER_TRAITS_NAMED_DECL`, and `JSONCONS_TPL_STRICT_MEMBER_TRAITS_NAMED_DECL` now allow you to have `const` or `static const` data members that are serialized. - `basic_csv_encoder` now supports json values that map to multi-valued fields and json objects where each member is a name-array pair. - `basic_csv_parser` and `basic_csv_encoder` now support nan, infinity, and minus infinity substitution Deprecated `basic_csv_options` functions removed: - basic_csv_options& column_names(const std::vector&) - basic_csv_options& column_defaults(const std::vector& value) - column_types(const std::vector& value) (Instead, use the versions that take comma-delimited strings) 0.137.0 -------- Defect fixes: - Fixes GCC 9.2 warning: ‘class jsoncons::json_exception’ has virtual functions and accessible non-virtual destructor, contributed by KonstantinPlotnikov. Enhancements: - Includes Martin Moene's span-lite to support a C++20-like span in the jsoncons namespace. - Includes enhancements to the CBOR encode and decode classes and functions to support the CBOR extension [Tags for Typed Arrays](https://tools.ietf.org/html/draft-ietf-cbor-array-tags-08). The implementation uses the span class. Changes: - The `json_options` parameter to `precision()` has been changed from `int` to `int8_t` - The `json_options` parameter to `indent_size()` has been changed from `size_t` to `uint8_t` - The `csv_options` parameter to `precision()` has been changed from `int` to `int8_t` - The CSV extension enum name `quote_style_type` has been deprecated and renamed to `quote_style_kind`. - The CSV extension enum name `mapping_type` has been deprecated and renamed to `mapping_kind`. - The `do_` virtual functions in `basic_json_content_handler` have been augmented with a `std::error_code` output parameter, e.g. virtual bool do_begin_object(semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; 0.136.1 -------- Defect fixes: - This version fixes a defect in the `erase` functions for the order preserving `basic_json` specializations, in particular, for `ojson` (issue 188.) 0.136.0 -------- For consistency with other names, the names of the convenience macros below for classes with templates and JSON with given names have been deprecated. JSONCONS_MEMBER_TRAITS_NAMED_DECL JSONCONS_STRICT_MEMBER_TRAITS_NAMED_DECL JSONCONS_TEMPLATE_MEMBER_TRAITS_DECL JSONCONS_STRICT_TEMPLATE_MEMBER_TRAITS_DECL JSONCONS_TEMPLATE_MEMBER_TRAITS_NAMED_DECL JSONCONS_STRICT_TEMPLATE_MEMBER_TRAITS_NAMED_DECL JSONCONS_ENUM_TRAITS_NAMED_DECL JSONCONS_GETTER_CTOR_TRAITS_NAMED_DECL JSONCONS_TEMPLATE_GETTER_CTOR_TRAITS_DECL JSONCONS_TEMPLATE_GETTER_CTOR_TRAITS_NAMED_DECL JSONCONS_GETTER_SETTER_TRAITS_NAMED_DECL JSONCONS_STRICT_GETTER_SETTER_TRAITS_NAMED_DECL JSONCONS_TEMPLATE_GETTER_SETTER_TRAITS_NAMED_DECL JSONCONS_STRICT_TEMPLATE_GETTER_SETTER_TRAITS_NAMED_DECL They have been renamed to JSONCONS_MEMBER_NAMED_TRAITS_DECL JSONCONS_STRICT_MEMBER_NAMED_TRAITS_DECL JSONCONS_TPL_MEMBER_TRAITS_DECL JSONCONS_STRICT_TPL_MEMBER_TRAITS_DECL JSONCONS_TPL_MEMBER_NAMED_TRAITS_DECL JSONCONS_STRICT_TPL_MEMBER_NAMED_TRAITS_DECL JSONCONS_ENUM_NAMED_TRAITS_DECL JSONCONS_GETTER_CTOR_NAMED_TRAITS_DECL JSONCONS_TPL_GETTER_CTOR_TRAITS_DECL JSONCONS_TPL_GETTER_CTOR_NAMED_TRAITS_DECL JSONCONS_GETTER_SETTER_NAMED_TRAITS_DECL JSONCONS_STRICT_GETTER_SETTER_NAMED_TRAITS_DECL JSONCONS_TPL_GETTER_SETTER_NAMED_TRAITS_DECL JSONCONS_STRICT_TPL_GETTER_SETTER_NAMED_TRAITS_DECL See [json_type_traits](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/json_type_traits.md) 0.135.0 -------- New macros that generate the code to specialize `json_type_traits` from the getter and setter functions and serialize to given names: - `JSONCONS_GETTER_SETTER_TRAITS_NAMED_DECL(class_name,(getter_name0,setter_name0,"name0"),(getter_name1,setter_name1,"name1")...)` - `JSONCONS_STRICT_GETTER_SETTER_TRAITS_NAMED_DECL(class_name,(getter_name0,setter_name0,"name0"),(getter_name1,setter_name1,"name1")...) ` - `JSONCONS_TEMPLATE_GETTER_SETTER_TRAITS_NAMED_DECL(num_template_params,class_name,(getter_name0,setter_name0,"name0"),(getter_name1,setter_name1,"name1")...) ` - `JSONCONS_STRICT_TEMPLATE_GETTER_SETTER_TRAITS_NAMED_DECL(num_template_params,class_name,(getter_name0,setter_name0,"name0"),(getter_name1,setter_name1,"name1")...) ` Support for disabling exceptions - Support compilation with exceptions disabled 0.134.0 -------- - Fixed [Compilation issue #178](https://github.com/danielaparker/jsoncons/issues/178). - The name `jsonpointer::address` has been deprecated and renamed to `jsonpointer::json_ptr` - `basic_json::contains` declared `noexcept` - Support stateful result and work allocators in `json_decoder` - Support stateful work allocators in `basic_json_reader`, `basic_json_parser`, `basic_csv_reader` and `basic_csv_parser`. 0.133.0 -------- - Deprecation warnings should now show for all supported versions of GCC and clang - New single argument `basic_json::get_value_with_default`, which has default value `basic_json::null()`, to replace deprecated `basic_json::get`. - `basic_json::get_value_with_default` now returns the default value if a `basic_json` has a null value, previously threw. 0.132.1 -------- - Fixed vs2019 warnings 0.132.0 -------- Changes - The name `JSONCONS_TEMPLATE_STRICT_MEMBER_TRAITS_DECL` has been deprecated and renamed to `JSONCONS_STRICT_TEMPLATE_MEMBER_TRAITS_DECL` - The enum name `jsoncons::chars_format` used in `json_options` and `csv_options` has been deprecated and renamed to `float_chars_format`. - The function name `floating_point_format()` used in `json_options` and `csv_options` has been deprecated and renamed to `float_format`. New macros that serialize to given names (instead of the c++ names) - `JSONCONS_MEMBER_TRAITS_NAMED_DECL(class_name,(member_name0,"name0"),(member_name1,"name1")...)` - `JSONCONS_STRICT_MEMBER_TRAITS_NAMED_DECL(class_name,(member_name0,"name0"),(member_name1,"name1")...)` - `JSONCONS_TEMPLATE_MEMBER_TRAITS_NAMED_DECL(num_template_params,class_name,(member_name0,"name0"),(member_name1,"name1")...)` - `JSONCONS_STRICT_TEMPLATE_MEMBER_TRAITS_NAMED_DECL(num_template_params,class_name,(member_name0,"name0"),(member_name1,"name1")...)` - `JSONCONS_GETTER_CTOR_TRAITS_NAMED_DECL(class_name,(getter_name0,"name0"),(getter_name1,"name1")...) ` - `JSONCONS_ENUM_TRAITS_NAMED_DECL(enum_type_name,(identifier0,"name0"),(identifier1,"name1")...)` Deprecated features removed - Constructor `basic_json(double, const floating_point_options&, semantic_tag)` 0.131.2 -------- Bug fix - Fixed issue with serializing a C++ standard library container class to a binary format, and getting an indefinite length array or map. 0.131.1 -------- Enhancements - New non-member functions `make_array_iterator` and `make_object_iterator` for creating a `staj_array_iterator` and a `staj_object_iterator` (especially for CSV example) 0.131.0 -------- Changes - The `decode_csv` and `encode_csv` functions have been moved from `csv_reader.hpp` and `csv_encoder.hpp` to `csv.hpp`. Rationale: avoid circular reference with new implementation of `decode_csv`. Enhancements - `basic_msgpack_parser` template class rewritten to avoid recursive function calls - `basic_bson_parser` template class rewritten to avoid recursive function calls - New `basic_msgpack_cursor` template class with `msgpack_stream_cursor` and `msgpack_bytes_cursor` typedefs - New `basic_bson_cursor` template class with `bson_stream_cursor` and `bson_bytes_cursor` typedefs - New `basic_csv_cursor` template class with `csv_cursor` and `wcsv_cursor` typedefs Bug fix: - Fixed issue with commented out first line of CSV file and column labels on next line - Fixed issue with parsing BSON arrays 0.130.0 --------------- Bug fix: - Fixed issue with `cbor_cursor` not reporting name events and terminal event Enhancements - New `basic_cbor_cursor` constructor that takes a filter parameter - Rewrote `basic_ubjson_parser` template class to avoid recursive function calls - New `basic_ubjson_cursor` template class with `ubjson_stream_cursor` and `ubjson_bytes_cursor` typedefs 0.129.1 --------------- - Fixed issue with deprecated class used in `decode_bson`, `decode_msgpack`, and `decode_ubjson` 0.129.0 --------------- New features: - Pull parsers for reporting CBOR parse events, cbor_stream_cursor for streams and cbor_bytes_cursor for buffers, have been added. - Added compile-time deprecation warnings Changes: - The long since deprecated `basic_json` member type `null_type` has been removed. Instead, use `jsoncons::null_type`. - The return type of `key_value::key()` has been changed from `string_view_type` to `key_type`. - The classes `staj_filter` and `filtered_staj_reader` have been removed, instead, use a lambda expression in the constructor of `json_pull_reader`. - The names `default_parse_error_handler` and `strict_parse_error_handler` have been deprecated and renamed to `default_json_parsing` and `strict_json_parsing`. Rationale: these apply only to JSON. - The typedef'ed names `json_encoder`, `bson_encoder`, `cbor_encoder`, `csv_encoder`, `cbor_encoder`, `msgpack_encoder`, and `ubjson_encoder` have been deprecated and renamed to `json_stream_encoder`, `bson_stream_encoder`, `cbor_stream_encoder`, `csv_stream_encoder`, `cbor_stream_encoder`, `msgpack_stream_encoder`, and `ubjson_stream_encoder`. Rationale: consistency for type names that are different for stream and string or bytes buffer specializations. 0.128.0 --------------- Changes - `JSONCONS_NONDEFAULT_MEMBER_TRAITS_DECL` macro name deprecated and replaced with `JSONCONS_STRICT_MEMBER_TRAITS_DECL` - basic_json function name `get_semantic_tag()` deprecated and replaced with `tag()` - staj_reader function name `get_semantic_tag()` deprecated and replaced with `tag()` Defect fixes: - This version fixes a defect in the macros `JSONCONS_MEMBER_TRAITS_DECL` etc. which meant that the generated `json_traits_type` specializations were not compatible with `wchar_t` sources and results. - This version fixes a defect when the `operator[](const string_view_type& key)` is applied to a non const `basic_json`, which returns a proxy where the member associated with the key may or may not exist, and an accessor declared `noexcept` is called in the case that it doesn't. In particular, the accessors `is_xxx` and `is` now return `false` in this case. New macros - `JSONCONS_TEMPLATE_MEMBER_TRAITS_DECL(num_template_params,class_name,member_name1,member_name2,...)` - `JSONCONS_TEMPLATE_STRICT_MEMBER_TRAITS_DECL(num_template_params,class_name,member_name1,member_name2,...)` - `JSONCONS_TEMPLATE_GETTER_CTOR_TRAITS_DECL(num_template_params,class_name,getter_name1,getter_name2,...)` `JSONCONS_TEMPLATE_MEMBER_TRAITS_DECL`, `JSONCONS_TEMPLATE_STRICT_MEMBER_TRAITS_DECL` and `JSONCONS_TEMPLATE_GETTER_CTOR_TRAITS_DECL` are for specializing `json_type_traits` for template types. The parameter `num_template_params` gives the number of template parameters. - `JSONCONS_ENUM_TRAITS_DECL(enum_type_name,value1,value2,...)` `JSONCONS_ENUM_TRAITS_DECL` allows you to encode and decode an enum type as a string. 0.127.0 --------------- Changes to staj streaming classes - `json_cursor` no longer has a constructor that accepts a `staj_filter`. Use a `filtered_staj_reader` instead. - The `staj_event` function `as` has been deprecated and renamed to `get`. - The `staj_event` function `accept` has been renamed to `read_to`. Enhancements - New macro `JSONCONS_NONDEFAULT_MEMBER_TRAITS_DECL`, that, when decoding to a C++ object, requires all data members declared for the object to be present in the JSON (or other supported format.) - Types that are specialized in `json_type_traits` are no longer required to have a public default constructor. In particular, types that are specialized using `JSONCONS_MEMBER_TRAITS_DECL` or `JSONCONS_NONDEFAULT_MEMBER_TRAITS_DECL` may have a private default constructor + `JSONCONS_TYPE_TRAITS_FRIEND`, and types that are specialized with `JSONCONS_GETTER_CTOR_TRAITS_DECL` are not required to have a default constructor at all. 0.126.0 --------------- Enhancements - The `json_reader` and `csv_reader` constructors have been generalized to take either a value from which a `jsoncons::string_view` is constructible (e.g. std::string), or a value from which a `source_type` is constructible (e.g. std::istream). - With this enhancement, the convenience typedefs `json_string_reader` and `csv_string_reader` are no longer needed, and have been deprecated. Name change - The name `json_pull_reader` has been deprecated (still works) and renamed to `json_cursor` Changes to bigfloat mapping In previous versions, jsoncons arrays that contained - an int64_t or a uint64_t (defines base-2 exponent) - an int64_t or a uint64_t or a string tagged with `semantic_tag::bigint` (defines the mantissa) and that were tagged with `semantic_tag::bigfloat`, were encoded into CBOR bigfloats. This behaviour has been deprecated. CBOR bigfloats are now decoded into a jsoncons string that consists of the following parts - (optional) minus sign - 0x - nonempty sequence of hexadecimal digits (defines mantissa) - p followed with optional minus or plus sign and nonempty sequence of hexadecimal digits (defines base-2 exponent) and tagged with `semantic_tag::bigfloat` (before they were decoded into a jsoncons array and tagged with `semantic_tag::bigfloat`) jsoncons strings that consist of the following parts - (optional) plus or minus sign - 0x or 0X - nonempty sequence of hexadecimal digits optionally containing a decimal-point character - (optional) p or P followed with optional minus or plus sign and nonempty sequence of decimal digits, and tagged with `semantic_tag::bigfloat` are now encoded into CBOR bignums. 0.125.0 -------- CMake build fix - The CMAKE_BUILD_TYPE variable is now left alone if already set Non-breaking changes to lighten `semantic_tag` names - The `semantic_tag` enum values `big_integer`, `big_decimal`, `big_float` and `date_time` have been deprecated (still work) and renamed to `bigint`, `bigdec`, `bigfloat` and `datetime`. - The `json_content_handler` functions `big_integer_value`, `big_decimal_value`, `date_time_value` and `timestamp_value` have been deprecated (still work.) Calls to these functions should be replaced by calls to `string_value` with `semantic_tag::bigint`, `semantic_tag::bigdec`, and `semantic_tag::datetime`, and by calls to `int64_vaue` with `semantic_tag::timestamp`. - The enum type `big_integer_chars_format` has been deprecated (still works) and renamed to `bigint_chars_format`. - The `json_options` modifier `big_integer_format` has been deprecated (still works) and renamed to `bigint_format`. Non-breaking changes to `ser_context`, `ser_error` and `jsonpath_error` - The function names `line_number` and `column_number` have been deprecated (still work) and renamed to `line` and `column`. 0.124.0 -------- - Fixed bug in `json_encoder` with `pad_inside_array_brackets` and `pad_inside_object_braces` options - Fixed issue with escape character in jsonpath quoted names. - Fixed pedantic level compiler warnings - Added doozer tests for CentOS 7.6 and Fedora release 24 - New macro `JSONCONS_GETTER_CTOR_TRAITS_DECL` that can be used to generate the `json_type_traits` boilerplate from getter functions and a constructor. 0.123.2 -------- defect fix: - Fixed name of JSONCONS_MEMBER_TRAITS_DECL 0.123.1 -------- jsonpath bug fixes: - Fixed bug in construction of normalized paths [#177](https://github.com/danielaparker/jsoncons/issues/177). - Fixed bug in jsonpath recursive descent with filters which could result in too many values being returned 0.123.0 -------- Warning fix: - Removed redundant macro continuation character [#176](https://github.com/danielaparker/jsoncons/pull/176) Non-breaking change to names (old name still works) - The name JSONCONS_TYPE_TRAITS_DECL has been deprecated and changed to JSONCONS_MEMBER_TRAITS_DECL Changes to jsonpath: - jsonpath unions now return distinct values (no duplicates) - a single dot immediately followed by a left bracket now results in an error (illegal JSONPath) Enhancements to jsonpath - Union of completely separate paths are allowed, e.g. $[firstName,address.city] - Names in the dot notation may be single or double quoted Other enhancements: - `basic_json` now supports operators `<`, `<=`, `>`, `>=` 0.122.0 -------- Changes: - The template parameter `CharT` has been removed from the binary encoders `basic_bson_encoder`, `basic_cbor_encoder`, `basic_msgpack_encoder`, and `basic_ubjson_encoder`. Enhancements: - Added macro JSONCONS_TYPE_TRAITS_FRIEND - Generalized the `csv_encode`, `bson_encode`, `cbor_encode`, `msgpack_encode` and `ubjson_encode` functions to convert from any type T that implements `json_type_traits` - Generalized the `csv_decode`, `bson_decode`, `cbor_decode`, `msgpack_decode` and `ubjson_decode` functions to convert to any type T that implements `json_type_traits` 0.121.1 -------- Bug fix: - Fixed issue with cbor_reader only reading tag values 0 through 23 Name change - The name `json::semantic_tag()` has been renamed to `json::get_semantic_tag()` Non-breaking changes (old names still work) - The name `semantic_tag_type` has been deprecated and renamed to `semantic_tag` - The names `json_serializer`, `bson_serializer`, `cbor_serializer`, `csv_serializer`, `msgpack_serializer`, and `ubjson_serializer` have been deprecated and renamed to `json_encoder`, `bson_encoder`, `cbor_encoder`, `csv_encoder`, `msgpack_encoder`, and `ubjson_encoder` - The names `bson_buffer_serializer`, `cbor_buffer_serializer`, `msgpack_buffer_serializer`, and `ubjson_buffer_serializer` have been deprecated and renamed to `bson_bytes_encoder`, `cbor_bytes_encoder`, `msgpack_bytes_encoder`, and `ubjson_bytes_encoder` - The names `bson_buffer_reader`, `cbor_buffer_reader`, `msgpack_buffer_reader`, and `ubjson_buffer_reader` have been deprecated and renamed to `bson_bytes_reader`, `cbor_bytes_reader`, `msgpack_bytes_reader`, and `ubjson_bytes_reader` Enhancements - Cleanup of `encode_json` and `decode_json` functions and increased test coverage - Rewrote cbor_reader to avoid recursive function call - CBOR reader supports [stringref extension to CBOR](http://cbor.schmorp.de/stringref) - New `cbor_options` has `packed_strings` option 0.120.0 -------- Bug fix: - Fixed issue with `j.as()` Non-breaking changes - The name `is_json_type_traits_impl` has been deprecated and renamed to `is_json_type_traits_declared` - The name `serializing_context` has been deprecated and renamed to `ser_context` - The name `serialization_error` has been deprecated and renamed to `ser_error` Enhancements - json `as_byte_string` attempts to decode string values if `semantic_tag_type` is `base64`, `base64url`, or `base16`. - New macro `JSONCONS_TYPE_TRAITS_DECL` that can be used to generate the `json_type_traits` boilerplate for your own types. - New `basic_json` member function `get_allocator` 0.119.1 -------- Bug fix: Fixed issue wjson dump() not formatting booleans correctly #174 0.119.0 -------- Name change: - The name `json_staj_reader` has been deprecated and renamed to `json_pull_reader` Bug fix: - Fixed a bug in json function `empty()` when type is `byte_string`. - Fixed a bug with preserving semantic_tag_type when copying json values of long string type. Changes: - Removed deprecated feature `cbor_view` - CBOR decimal fraction and bigfloat string formatting now consistent with double string formatting Enhancements: - json `to_string()` and `to_double()` now work with CBOR bigfloat - JSONPath operators in filter expressions now work with `big_integer`, `big_decimal`, and `big_float` tagged json values - json `is_number()` function now returns `true` if string value is tagged with `big_integer` or `big_decimal`, or if array value is tagged with `big_float`. - json `as_string()` function now converts arrays tagged with `big_float` to decimal strings - json `as_double()` function now converts arrays tagged with `big_float` to double values 0.118.0 -------- New features - New csv option `lossless_number`. If set to `true`, parse numbers with exponent and fractional parts as strings with semantic tagging `semantic_tag_type::big_decimal` (instead of double.) Defaults to `false`. - A class `jsonpointer::address` has been introduced to make it simpler to construct JSON Pointer addresses Name change - The `json_options` name `dec_to_str` has been deprecated and renamed to `lossless_number`. 0.117.0 -------- Deprecated features: - cbor_view has been deprecated. Rationale: The complexity of supporting and documenting this component exceeded its benefits. New features - New `json_options` option `dec_to_str`. If set to `true`, parse decimal numbers as strings with semantic tagging `semantic_tag_type::big_decimal` instead of double. Defaults to `false`. - The `ojson` (order preserving) implementation now has an index to support binary search for retrieval. - Added `std::string_view` detection - jsoncons-CBOR semantic tagging supported for CBOR tags 32 (uri) Name changes (non-breaking) - The json options name `bignum_chars_format` has been deprecated and replaced with `big_integer_chars_format`. - `big_integer_chars_format::integer` (`bignum_chars_format::integer`) has been deprecated and replaced with `big_integer_chars_format::number` - The `json_options function` `bignum_format` has been deprecated and replaced with `big_integer_format` Changes to floating-point printing - If the platform supports the IEEE 754 standard, jsoncons now uses the Grisu3 algorithm for printing floating-point numbers, falling back to a safe method using C library functions for the estimated 0.5% of floating-point numbers that might be rejected by Grisu3. The Grisu3 implementation follows Florian Loitsch's [grisu3_59_56](https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf) implementation. If the platform does not support the IEEE 754 standard, the fall back method is used. - In previous versions, jsoncons preserved information about the format, precision, and decimal places of the floating-point numbers that it read, and used that information when printing them. With the current strategy, that information is no longer needed. Consequently, the `floating_point_options` parameter in the `do_double_value` and `double_value` functions of the SAX-style interface have been removed. - The `json` functions `precision()` and `decimal_places()` have been deprecated and return 0 (as this information is no longer preserved.) - The constructor `json(double val, uint8_t precision)` has been deprecated. - Note that it is still possible to set precision as a json option when serializing. 0.116.0 -------- New features: - New jsonpath functions `keys` and `tokenize`. - jsoncons-CBOR data item mappings supported for CBOR tags 33 (string base64url) and 34 (string base64) 0.115.0 -------- New features: - bson UTC datetime associated with jsoncons `semantic_tag_type::timestamp` - New traits class `is_json_type_traits_impl` that addresses issues [#133](https://github.com/danielaparker/jsoncons/issues/133) and [#115](https://github.com/danielaparker/jsoncons/issues/115) (duplicates) - Following a proposal from soberich, jsonpath functions on JSONPath expressions are no longer restricted to filter expressions. - New jsonpath functions `sum`, `count`, `avg`, and `prod` - Added `semantic_tag_type::base16`, `semantic_tag_type::base64`, `semantic_tag_type::base64url` Non-breaking changes: - The json constructor that takes a `byte_string` and a `byte_string_chars_format` has been deprecated, use a `semantic_tag_type` to supply an encoding hint for a byte string, if any. - The content handler `byte_string_value` function that takes a `byte_string` and a `byte_string_chars_format` has been deprecated, use a `semantic_tag_type` to supply an encoding hint for a byte string, if any. Changes: - The `byte_string_chars_format` parameter in the content handler `do_byte_string_value` function has been removed, the `semantic_tag_type` parameter is now used to supply an encoding hint for a byte string, if any. 0.114.0 -------- Bug fixes: - On Windows platforms, fixed issue with macro expansion of max when including windows.h (also in 0.113.1) - Fixed compile issue with `j = json::make_array()` (also in 0.113.2) Breaking changes to jsoncons semantic tag type names: - semantic_tag_type::bignum to semantic_tag_type::big_integer - semantic_tag_type::decimal_fraction to semantic_tag_type::big_decimal - semantic_tag_type::epoch_time to semantic_tag_type::timestamp Non-breaking name changes: The following names have been deprecated and renamed (old names still work) - `bignum_value` to `big_integer_value` in `json_content_handler` - `decimal_value` to `big_decimal_value` in `json_content_handler` - `epoch_time_value` to `timestamp_value` in `json_content_handler` - `cbor_bytes_serializer` to `cbor_buffer_serializer` - `msgpack_bytes_serializer` to `msgpack_buffer_serializer` - `json_serializing_options` to `json_options` - `csv_serializing_options` to `csv_options` - `parse_error` to `serialization_error` The rationale for renaming `parse_error` to `serialization_error` is that we need to use error category codes for serializer errors as well as parser errors, so we need a more general name for the exception type. Message Pack enhancements - New `msgpack_serializer` that supports Message Pack bin formats - New `msgpack_parser` that supports Message Pack bin formats - `encode_msgpack` and `decode_msgpack` have been rewritten using `msgpack_serializer` and `msgpack_parser`, and also now support bin formats. New features: - decode from and encode to the [Universal Binary JSON Specification (ubjson)](http://bsonspec.org/) data format - decode from and encode to the [Binary JSON (bson)](http://bsonspec.org/) data format - The cbor, msgpack and ubjson streaming serializers now validate that the expected number of items have been supplied in an object or array of pre-determined length. 0.113.0 --------------- Bug fix - Fixed issue with indefinite length byte strings, text strings, arrays, and maps nested inside other CBOR items (wasn't advancing the input pointer past the "break" indicator.) Changes - __FILE__ and __LINE__ macros removed from JSONCONS_ASSERT if not defined _DEBUG (contributed by zhskyy.) - semantic_tag_type name `decimal` changed to `decimal_fraction` New CBOR feature - CBOR semantic tagging of expected conversion of byte strings to base64, base64url and base16 are preserved and respected in JSON serialization (unless overridden in `json_serializing_options`.) - CBOR semantic tagging of bigfloat preserved with `semantic_tag_type::bigfloat` - CBOR non text string keys converted to strings when decoding to json values Changes to `json_serializing_options` New options - spaces_around_colon (defaults to `space_after`) - spaces_around_comma (defaults to `space_after`) - pad_inside_object_braces (defaults to `false`) - pad_inside_array_brackets (defaults to `false`) - line_length_limit (defaults to '120`) - new_line_chars (for json serialization, defaults to `\n`) `nan_replacement`, `pos_inf_replacement`, and `neg_inf_replacement` are deprecated (still work) These have been replaced by - nan_to_num/nan_to_str - inf_to_num/inf_to_str - neginf_to_num/neginf_to_str (default is `-` followed by inf_to_num/inf_to_str) `nan_to_str`, `inf_to_str` and `neginf_to_str` are also used to substitute back to `nan`, `inf` and `neginf` in the parser. - Long since deprecated options `array_array_block_option`, `array_object_block_option`, `object_object_block_option` and `object_array_block_option` have been removed. - The names `object_array_split_lines`, `object_object_split_lines`, `array_array_split_lines` and `array_object_split_lines` have been deprecated (still work) and renamed to `object_array_line_splits`, `object_object_line_splits`, `array_array_line_splits` and `array_object_line_splits`. Rationale: consistency with `line_split_kind` name. Changes to json_serializer - Previously the constructor of `json_serializer` took an optional argument to indicate whether "indenting" was on. `json_serializer` now always produces indented output, so this argument has been removed. - A new class `json_compressed_serializer` produces compressed json without indenting. The jsoncons functions that perform serialization including `json::dump`, `pretty_print` and the output stream operator are unaffected. 0.112.0 -------- Changes to `json_content_handler` - The function `byte_string_value` no longer supports passing a byte string as handler.byte_string_value({'b','a','r'}); (shown in some of the examples.) Instead use handler.byte_string_value(byte_string({'b','a','r'})); (or a pointer to utf8_t data and a size.) - The function `bignum_value` no longer supports passing a CBOR signum and byte string, `bignum_value` now accepts only a string view. If you have a CBOR signum and byte string, you can use the bignum class to convert it into a string. Name changes (non breaking) - The name `json_stream_reader` has been deprecated and replaced with `json_staj_reader`. - The name `stream_event_type` has been deprecated and replaced with `staj_event_type` - The names `basic_stream_event` (`stream_event`) have been deprecated and replaced with `basic_staj_event` (`staj_event`) - The names `basic_stream_filter` (`stream_filter`) have been deprecated and replaced with `basic_staj_filter` (`staj_filter`) (staj stands for "streaming API for JSON, analagous to StAX in XML) - The `json_parser` function `end_parse` has been deprecated and replaced with `finish_parse`. Enhancements - json double values convert to CBOR float if double to float round trips. - csv_parser `ignore_empty_values` option now applies to `m_columns` style json output. - json_reader and json_staj_reader can be initialized with strings in addition to streams. Extension of semantic tags to other values - The `json_content_handler` functions `do_null_value`, `do_bool_value`, `do_begin_array` and `do_begin_object` have been given the semantic_tag_type parameter. - New tag type `semantic_tag_type::undefined` has been added - The `cbor_parser` encodes a CBOR undefined tag to a json null value with a `semantic_tag_type::undefined` tag, and the `cbor_serializer` maps that combination back to a CBOR undefined tag. Removed: - Long since deprecated `value()` functions have been removed from `json_content_handler` 0.111.1 -------- Enhancements - Improved efficiency of json_decoder - Improved efficiency of json_proxy - Conversion of CBOR decimal fraction to string uses exponential notation if exponent is positive or if the exponent plus the number of digits in the mantissa is negative. Bug fix - Fixed issue with conversion of CBOR decimal fraction to string when mantissa is negative 0.111.0 -------- Bug and warning fixes: - A case where the json parser performed validation on a string before all bytes of the string had been read, and failed if missing part of a multi-byte byte sequence, is fixed. - An issue with reading a bignum with the pull parser `json_stream_reader` (in the case that an integer value overflows) has been fixed. - GCC and clang warnings about switch fall through have been fixed Non-breaking changes: - The functions `json::has_key` and `cbor::has_key` have been deprecated (but still work) and renamed to `json::contains` and `cbor::contains`. Rationale: consistency with C++ 20 associative map `contains` function. - The json function `as_integer()` is now a template function, ```c++ template T as_integer(); ``` where T can be any integral type, signed or unsigned. The default parameter is for backwards compatability, but is a depreated feature, and may be removed in a future version. Prefer j.as(). - The json functions `is_integer()` and `is_uinteger()` have been deprecated and renamed to `is_int64()`, `is_uint64()`. Prefer j.is() and j.is(). - The json function `as_uinteger()` has been deprecated. Prefer j.as(). and `as_uinteger()` have been deprecated and renamed to `is_int64()`, `is_uint64()`, `as_int64()` and `as_uint64()`. Change to pull parser API: - The `stream_filter` function `accept` has been changed to take a `const stream_event&` and a `const serializing_context&`. - `stream_event_type::bignum_value` has been removed. `stream_event` now exposes information about optional semantic tagging through the `semantic_tag()` function. Enhancements: - `j.as()` has been enhanced to return a bignum value if j is an integer, floating point value, or any string that contains an optional minus sign character followed by a sequence of digits. - `j.as()` has been enhanced to support extended integer types that have `std::numeric_limits` specializations. In particular, it supports GCC `__int128` and `unsigned __int128` when code is compiled with `std=gnu++NN`, allowing a `bignum` to be returned as an `__int128` or `unsigned __int128`. (when code is compiled with `-std=c++NN`, `__int128` and `unsigned __int128` do not have `std::numeric_limits` specializations.) New feature: This release accomodate the additional semantics for the CBOR data items date-time (a string), and epoch time (a positive or negative integer or floating point value), and decimal fraction (converted in the jsoncons data model to a string). But first, some of the virtual functions in `json_content_handler` have to be modified to preserve these semantics. Consequently, the function signatures bool do_int64_value(int64_t, const serializing_context&) bool do_uint64_value(uint64_t, const serializing_context&) bool do_double_value(double, const floating_point_options&, const serializing_context&) bool do_string_value(const string_view_type&, const serializing_context&) bool do_byte_string_value(const uint8_t*, size_t, const serializing_context&) have been given an additonal parameter, a `semantic_tag_type`, bool do_int64_value(int64_t, semantic_tag_type, const serializing_context&) bool do_uint64_value(uint64_t, semantic_tag_type, const serializing_context&) bool do_double_value(double, const floating_point_options&, semantic_tag_type, const serializing_context&) bool do_string_value(const string_view_type&, semantic_tag_type, const serializing_context&) bool do_byte_string_value(const uint8_t*, size_t, semantic_tag_type, const serializing_context&) For consistency, the virtual function bool do_bignum_value(const string_view_type&, const serializing_context&) has been removed, and in its place `do_string_value` will be called with semantic_tag_type::bignum_type. For users who have written classes that implement all or part of `json_content_handler`, including extensions to `json_filter`, these are breaking changes. But otherwise users should be unaffected. 0.110.2 -------- Continuous integration: - jsoncons is now cross compiled for ARMv8-A architecture on Travis using clang and executed using the emulator qemu. - UndefinedBehaviorSanitizer (UBSan) is enabled for selected gcc and clang builds. Maintenance: - Removed compiler warnings 0.110.1 -------- Bug fixes contributed by Cebtenzzre - Fixed a case where `as_double()`, `as_integer()` etc on a `basic_json` value led to an infinite recursion when the value was a bignum - Fixed undefined behavior in bignum class 0.110.0 -------- ### New features - A JSON pull parser, `json_stream_reader`, has been added. This required a change to the `json_content_handler` function signatures, the return values has been changed to bool, to indicate whether parsing is to continue. (An earlier version on master was called `json_event_reader`.) - `json_parser` has new member function `stopped()`. - The `json::is` function now supports `is()`, and if your compiler has `std::string_view`, `is()` as well. It returns `true` if the json value is a string, otherwise `false`. - The `json::as` function now supports `as()`, and if your compiler has `std::string_view`, `as()` as well. ### Changes to `json_content_handler` and related streaming classes #### Non-breaking changes These changes apply to users that call the public functions defined by `json_content_handler`, e.g. begin_object, end_object, etc., but are non-breaking because the old function signatures, while deprecated, have been preserved. Going forward, however, users should remove calls to `begin_document`, replace `end_document` with `flush`, and replace `integer_value` and `end_integer_value` with `int64_value` and `uint64_value`. - The public functions defined by `json_content_handler` have been changed to return a bool value, to indicate whether parsing is to continue. - The function names `integer_value` and `uinteger_value` have been changed to `int64_value` and `uint64_value`. - The function names `begin_document` and `end_document` have been deprecated. The deprecated `begin_document` does nothing, and the deprecated `end_document` calls `do_flush`. - The function `flush` has been added, which calls `do_flush`. - The `json` member function `dump_fragment` has been deprecated, as with the dropping of `begin_document` and `end_document`, it is now equivalent to `dump`. - The function `encode_fragment` has been deprecated, as with the dropping of `begin_document` and `end_document`, it is now equivalent to `encode_json`. - The `json_filter` member function `downstream_handler` has been renamed to `destination_handler`. #### Breaking changes These changes will affect users who have written classes that implement all or part of `json_content_handler`, including extensions to `json_filter`. - The virtual functions defined for `json_content_handler`, `do_begin_object`, `do_end_object`, etc. have been changed to return a bool value, to indicate whether serializing or deserializing is to continue. - The virtual functions `do_begin_document` and `do_end_document` have been removed. A virtual function `do_flush` has been added to allow producers of json events to flush whatever they've buffered. - The function names `do_integer_value` and `do_uinteger_value` have been changed to `do_int64_value` and `do_uint64_value`. - The signature of `do_bignum_value` has been changed to ``` bool do_bignum_value(const string_view_type& value, const serializing_context& context) ``` 0.109.0 -------- Enhancements - Added byte string formatting option `byte_string_chars_format::base16` Changes - Scons dropped as a build system for tests and examples, use CMake - Tests no longer depend on boost, boost test framework replaced by Catch2. boost code in tests moved to `examples_boost` directory. - Previously, if `json_parser` encountered an unopened object or array, e.g. "1]", this would cause a JSONCONS_ASSERT failure, resulting in an `std::runtime_error`. This has been changed to cause a `json_parse_errc::unexpected_right_brace` or `json_parse_errc::unexpected_right_bracket` error code. Warning fixes - Eliminated vs2017 level 3 and level 4 warnings 0.108.0 -------- Enhancements - `bignum_chars_format::base64` is supported - The incremental parser `json_parser` has been documented Changes (non-breaking) - Previously, jsonpointer::get returned values (copies) Now, jsonpointer::get returns references if applied to `basic_json`, and values if applied to `cbor_view` - `bignum_chars_format::string` has been deprecated (still works) and replaced with `bignum_chars_format::base10` - `json_parser_errc`, `cbor_parser_errc`, and `csv_parser_errc` have been deprecated (still work) and renamed to `json_parse_errc`, `cbor_parse_errc`, and `csv_parse_errc` 0.107.2 -------- Bug fixes: - Fixed issue with `UINT_MAX` not declared in `bignum.hpp` 0.107.1 -------- Bug fixes: - Fixed issue with cbor_view iterators over indefinite length arrays and maps Enhancements: - csv_serializer recognizes byte strings and bignums. 0.107.0 -------- Enhancements - Support for CBOR bignums - Added json serializing options for formatting CBOR bignums as integer, string, or base64url encoded byte string - Added json serializing options for formatting CBOR bytes strings as base64 or base64url - Enhanced interface for `cbor_view` including `dump`, `is`, and `as` functions Changes - If the json parser encounters an integer overflow, the value is now handled as a bignum rather than a double value. - The `json_content_handler` names `begin_json` and `end_json` have been deprecated and replaced with `begin_document` and `end_document`, and the names `do_begin_json` and `do_end_json` have been removed and replaced with `do_begin_document`, and `do_end_document`. Rationale: meaningfullness across JSON and other data formats including CBOR. Bug fixes: - Fixed bug in base64url encoding of CBOR byte strings - Fixed bug in parsing indefinite length CBOR arrays and maps 0.106.0 -------- Changes - If a fractional number is read in in fixed format, serialization now preserves that fixed format, e.g. if 0.000071 is read in, serialization gives 0.000071 and not 7.1e-05. In previous versions, the floating point format, whether fixed or scientific, was determined by the behavior of snprintf using the g conversion specifier. Bug fix: - Fixed issue with parsing cbor indefinite length arrays and maps Warning fix: - Use memcpy in place of reinterpret_cast in binary data format utility `from_big_endian` Compiler fix: - Fixed issues with g++ 4.8 0.105.0 -------- Enhancements - The CSV extension now supports multi-valued fields separated by subfield delimiters - New functions `decode_json` and `encode_json` convert JSON formatted strings to C++ objects and back. These functions attempt to perform the conversion by streaming using `json_convert_traits`, and if streaming is not supported, fall back to using `json_type_traits`. `decode_json` and `encode_json` will work for all types that have `json_type_traits` defined. - The json::parse functions and the json_parser and json_reader constructors optionally take a json_serializing_options parameter, which allows replacing a string that matches nan_replacement(), pos_inf_replacement(), and neg_inf_replacement(). Changes to Streaming - The `basic_json_input_handler` and `basic_json_output_handler` interfaces have been combined into one class `basic_json_content_handler`. This greatly simplifies the implementation of `basic_json_filter`. Also, the name `parsing_context` has been deprecated and renamed to `serializing_context`, as it now applies to both serializing and deserializing. If you have subclassed `json_filter` or have fed JSON events directlty to a `json_serializer`, you shouldn't have to make any changes. In the less likely case that you've implemented the `basic_json_input_handler` or `basic_json_output_handler` interfaces, you'll need to change that to `json_content_handler`. Other Changes - `serialization_traits` and the related `dump` free functions have been deprecated, as their functionality has been subsumed by `json_convert_traits` and the `encode_json` functions. - The option bool argument to indicate pretty printing in the `json` `dump` functions and the `json_serializer` class has been deprecated. It is replaced by the enum class `indenting` with enumerators `indenting::no_indent` and `indenting::indent`. - The name `serialization_options` has been deprecated (still works) and renamed to `json_serializing_options`. Rationale: naming consistency. - The `json_reader` `max_nesting_depth` getter and setter functions have been deprecated. Use the `json_serializing_options` `max_nesting_depth` getter and setter functions instead. - The name `csv_parameters` has been deprecated (still works) and renamed to `csv_serializing_options`. Rationale: naming consistency. 0.104.0 -------- Changes - `decode_csv` by default now attempts to infer null, true, false, integer and floating point values in the CSV source. In previous versions the default was to read everything as strings, and other types had to be specified explicitly. If the new default behavior is not desired, the `csv_parameters` option `infer_types` can be set to `false`. Column types can still be set explicitly if desired. 0.103.0 -------- Changes - Default `string_view_type` `operator std::basic_string() const` made explicit to be consistent with `std::string_view` - The virtual method `do_double_value` of `json_input_handler` and `json_output_handler` takes a `number_format` parameter Performance improvements - Faster json dump to string (avoids streams) - Faster floating point conversions for linux and MacOSX - Memory allocation decoding larger string values reduced by half - Optimization to json_parser parse_string - Improvements to json_decoder 0.102.1 -------- Bug fix: Fixed an off-by-one error that could lead to an out of bounds read. Reported by mickcollyer (issue #145) 0.102.0 -------- Bug fixes: Fixed issue with how jsonpath filters are applied to arrays in the presence of recursion, resulting in duplicate results. Changes: The signatures of `jsonpointer::get`, `jsonpointer::insert`, `jsonpointer::insert_or_assign`, `jsonpointer::remove` and `jsonpointer::replace` have been changed to be consistent with other functions in the jsoncons library. Each of these functions now has two overloads, one that takes an `std::error_code` parameter and uses it to report errors, and one that throws a `jsonpointer_error` exception to report errors. The function `jsonpatch::patch` has been replaced by `jsonpatch::apply_patch`, which takes a json document, a patch, and a `std::error_code&` to report errors. The function `jsonpatch::diff` has been renamed to `jsonpatch::from_diff` The old signatures for `encode_cbor` and `encode_msgpack` that returned a `std::vector` have been deprecated and replaced by new signatures that have void return values and have an output parameter 'std::vector&'. The rationale for this change is consistency with other functions in the jsoncons library. 0.101.0 -------- Fixes: - Fixes to `string_view` code when `JSONCONS_HAS_STRING_VIEW` is defined in `jsoncons_config.hpp` Changes: - `as_double` throws if `json` value is null (previously returned NaN) Enhancements: - Added convenience functions `decode_csv` and `encode_csv` - Support custom allocaor (currently stateless only) in `json_decoder`, `json_reader`, `csv_reader`, `csv_parameters` 0.100.2 ------- Resolved warnings on GCC Issue #127 0.100.1 ------- Fix for platform issue with vs2017: - Renamed label `minus` to `minus_sign` in `json_parser.hpp` Enhancements: - New classes `byte_string` and `byte_string_view`, to augment support for cbor byte strings in `json` values 0.100.0 ------- Changes: - `template json_traits` replaced with `sorted_policy` - `template o_json_traits` replaced with `preserve_order_policy` - The return type for the json::get_with_default function overload for `const char*` has been changed from `const char*` to `json::string_view_type`, which is assignable to `std::string`. - New functions `byte_string_value` and `do_byte_string_value` have been added to `basic_json_input_handler` and `basic_json_output_handler` - json::is() and json::as() specializations (supported but never documented) have been deprecated - In android specific `string_to_double`, `strtod_l` changed to `strtold_l` Enhancements: - The `json` class and the `decode_cbor` and `encode_cbor` functions now support byte strings A `json` byte string value will, when serialized to JSON, be converted to a base64url string. - `version.hpp` added to `include` directory 0.99.9.2 -------- Bug fixes: - Fixed issue with jsonpatch::diff (fix contributed by Alexander (rog13)) Enhancements: - New class `cbor_view` for accessing packed `cbor` values. A `cbor_view` satisfies the requirements for `jsonpointer::get`. Changes (non breaking) ---------------------- - `jsonpointer::erase` renamed to `jsonpointer::remove`, old name deprecated 0.99.9.1 -------- New features ------------ - JSON Pointer implementation - JSON Patch implementation, includes patch and diff - `json::insert` function for array that inserts values from range [first, last) before pos. Bug fixes - Fixed issue with serialization of json array of objects to csv file Changes (non breaking) ---------------------- - The member function name `json::dump_body` has been deprecated and replaced with `json::dump_fragment`. - The non member function name `dump_body` has been deprecated and replaced with `dump_fragment`. - The class name `rename_name_filter` has been deprecated and replaced with `rename_object_member_filter`. - In the documentation and examples, the existing function `json::insert_or_assign` is now used instead of the still-supported `json::set`. The reason is that `insert_or_assign` follows the naming convention of the C++ standard library. Changes ------- - The recently introduced class `json_stream_traits` has been renamed to `serialization_traits` - Removed template parameter `CharT` from class `basic_parsing_context` and renamed it to `parsing_context` - Removed template parameter `CharT` from class `basic_parse_error_handler` and renamed it to `parse_error_handler` 0.99.8.2 -------- New features - Added `json` functions `push_back` and `insert` for appending values to the end of a `json` array and inserting values at a specifed position Rationale: While these functions provide the same functionality as the existing `json::add` function, they have the advantage of following the naming conventions of the C++ library, and have been given prominence in the examples and documentation (`add` is still supported.) 0.99.8.1 -------- New features - cbor extension supports encoding to and decoding from the cbor binary serialization format. - `json_type_traits` supports `std::valarray` Documentation - Documentation is now in the repository itself. Please see the documentation link in the README.md file Changed - Removed `CharT` template parameter from `json_stream_traits` 0.99.8 ------ Changes - Visual Studio 2013 is no longer supported (jsonpath uses string initilizer lists) - `json_input_handler` overloaded functions value(value,context)` have been deprecated. Instead use `string_value(value,context)`, `integer_value(value,context)`, `uinteger_value(value,context)`, `double_value(value,precision,context)`, `bool_value(value,context)` and `null_value(context)` - `json_output_handler` overloaded functions value(value)` have been deprecated. Instead use `string_value(value)`, `integer_value(value)`, `uinteger_value(value)`, `double_value(value,precision=0)`, `bool_value(value)` and `null_value(context)` - For consistency, the names `jsoncons_ext/msgpack/message_pack.hpp`, `encode_message_pack` and `decode_message_pack` have been deprecated and replaced with `jsoncons_ext/msgpack/msgpack.hpp`, `encode_msgpack` and `decode_msg_pack` Bug fixes - Fixed operator== throws when comparing a string against an empty object - Fixed jsonpath issue with array 'length' (a.length worked but not a['length']) - `msgpack` extension uses intrinsics for determing whether to swap bytes New features - Stream supported C++ values directly to JSON output, governed by `json_stream_traits` - json::is() and json::as() accept template packs, which they forward to the `json_type_traits` `is` and `as` functions. This allows user defined `json_type_traits` implementations to resolve, for instance, a name into a C++ object looked up from a registry. See [Type Extensibility](https://github.com/danielaparker/jsoncons), Example 2. - jsonpath `json_query` now supports returning normalized paths (with optional `return_type::path` parameter) - New jsonpath `max` and `min` aggregate functions over numeric values - New `json::merge` function that inserts another json object's key-value pairs into a json object, if they don't already exist. - New `json::merge_or_update` function that inserts another json object's key-value pairs into a json object, or assigns them if they already exist. 0.99.7.3 -------- - `json_type_traits` supports `std::pair` (convert to/from json array of size 2) - `parse_stream` renamed to `parse` (backwards compatible) - `kvp_type` renamed to `key_value_pair_type` (backwards compatible) - The `_json` and `_ojson` literal operators have been moved to the namespace `jsoncons::literals`. Access to these literals now requires ```c++ using namespace jsoncons::literals; ``` Rationale: avoid name clashes with other `json` libraries - The name `owjson` has been deprecated (still works) and changed to `wojson`. Rationale: naming consistency - Added json array functions `emplace_back` and `emplace`, and json object functions `try_emplace` and `insert_or_assign`, which are analagous to the standard library vector and map functions. 0.99.7.2 -------- Bug fix - A bug was introduced in 0.99.7 causing the values of existing object members to not be changed wiht set or assignment operations. This has been fixed. Change - jsoncons_ext/binary changed to jsoncons_ext/msgpack - namespace jsoncons::binary changed to jsoncons::msgpack 0.99.7.1 -------- - Workarounds in unicode_traits and jsonpath to maintain support for vs2013 - Added `mapping_type::n_rows`, `mapping_type::n_objects`, and `mapping_type::m_columns` options for csv to json 0.99.7 ------ Bug fixes - Issues with precedence in JsonPath filter evaluations have been fixed - An issue with (a - expression) in JsonPath filter evaluations has been fixed New feature - The new binary extension supports encoding to and decoding from the MessagePack binary serialization format. - An extension to JsonPath to allow filter expressions over a single object. - Added support for `*` and `/` operators to jsonpath filter - literal operators _json and _ojson have been introduced Non-breaking changes - The `json` `write` functions have been renamed to `dump`. The old names have been deprecated but still work. - Support for stateful allocators - json function object_range() now returns a pair of RandomAccessIterator (previously BidirectionalIterator) - json operator [size_t i] applied to a json object now returns the ith object (previously threw) Breaking change (if you've implemented your own input and output handlers) In basic_json_input_handler, the virtual functions ```c++ virtual void do_name(const CharT* value, size_t length, const basic_parsing_context& context) virtual void do_string_value(const CharT* value, size_t length, const basic_parsing_context& context) ``` have been changed to ```c++ virtual void do_name(string_view_type val, const basic_parsing_context& context) virtual void do_string_value(string_view_type val, const basic_parsing_context& context) ``` In basic_json_output_handler, the virtual functions ```c++ virtual void do_name(const CharT* value, size_t length) virtual void do_string_value(const CharT* value, size_t length) ``` have been changed to ```c++ virtual void do_name(string_view_type val) virtual void do_string_value(string_view_type val) ``` Removed features: - The jsonx extension has been removed 0.99.5 ------ - Validations added to utf8 and utf16 string parsing to pass all [JSONTestSuite](https://github.com/nst/JSONTestSuite) tests - The name `json_encoder` introduced in 0.99.4 has been changed to `json_decoder`. Rationale: consistencty with common usage (encoding and serialization, decoding and deserialization) 0.99.4a ------- Fixes Issue #101, In json.hpp, line 3376 change "char__type" to "char_type" Fixes Issue #102, include cstring and json_error_category.hpp in json.hpp 0.99.4 ------ Changes - The deprecated class `json::any` has been removed. - The jsoncons `boost` extension has been removed. That extension contained a sample `json_type_traits` specialization for `boost::gregorian::date`, which may still be found in the "Type Extensibility" tutorial. - The member `json_type_traits` member function `assign` has been removed and replaced by `to_json`. if you have implemented your own type specializations, you will also have to change your `assign` function to `to_json`. - `json_type_traits` specializations no longer require the `is_assignable` data member Non-breaking name changes - The names `json_deserializer`,`ojson_deserializer`,`wjson_deserializer`,`owjson_deserializer` have been deprecated (they still work) and replaced by `json_encoder`, `json_encoder`, `json_encoder` and `json_encoder`. - The name `output_format` has been deprecated (still works) and renamed to `serialization_options`. - The name `wojson` has been deprecated (still works) and renamed to `owjson`. - The `json_filter` member function `input_handler` has been deprecated (still works) and renamed to `downstream_handler`. - The name `elements` has been deprecated (still works) and renamed to `owjson`. - The `json` member function `members()` has been deprecated (still works) and renamed to `object_range()`. - The `json` member function `elements()` has been deprecated (still works) and renamed to `array_range()`. - The `json` member_type function `name()` has been deprecated (still works) and renamed to `key()`. Rationale: consistency with more general underlying storage classes. New features - `json_filter` instances can be passed to functions that take a `json_output_handler` argument (previously only a `json_input_handler` argument) - New `jsonpath` function `json_replace` that searches for all values that match a JsonPath expression and replaces them with a specified value. - `json` class has new method `has_key()`, which returns `true` if a `json` value is an object and has a member with that key - New filter class `rename_name` allows search and replace of JSON object names 0.99.3a ------- Changes The `json` initializer-list constructor has been removed, it gives inconsistent results when an initializer has zero elements, or one element of the type being initialized (`json`). Please replace `json j = {1,2,3}` with `json j = json::array{1,2,3}`, and `json j = {{1,2,3},{4,5,6}}` with `json j = json::array{json::array{1,2,3},json::array{4,5,6}}` - Initializer-list constructors are now supported in `json::object` as well as `json::array`, e.g. ```c++ json j = json::object{{"first",1},{"second",json::array{1,2,3}}}; ``` - json::any has been deprecated and will be removed in the future - The json method `to_stream` has been renamed to `write`, the old name is still supported. - `output_format` `object_array_block_option`, `array_array_block_option` functions have been deprecated and replaced by `object_array_split_lines`, `array_array_split_lines` functions. Enhancements - A new method `get_with_default`, with return type that of the default, has been added to `json` - A new template parameter, `JsonTraits`, has been added to the `basic_json` class template. - New instantiations of `basic_json`, `ojson` and `wojson`, have been added for users who wish to preserve the alphabetical sort of parsed json text and to insert new members in arbitrary name order. - Added support for `json` `is`, `as`, constructor, and assignment operator for any sequence container (`std::array`, `std::vector`, `std::deque`, `std::forward_list`, `std::list`) whose values are assignable to JSON types (e.g., ints, doubles, bools, strings, STL containers of same) and for associative containers (`std::set`, `std::multiset`, `std::unordered_set`, `std::unordered_multiset`.) - Added static method `null()` to `json` class to return null value - A new extension jsonx that supports serializing JSON values to [JSONx](http://www.ibm.com/support/knowledgecenter/SS9H2Y_7.5.0/com.ibm.dp.doc/json_jsonx.html) (XML) - json parser will skip `bom` in input if present Fixes: - Fixes to the `jsonpath` extension, including the union operator and applying index operations to string values - Fixes to remove warnings and issues reported by VS2015 with 4-th warnings level, PVS-Studio static analyzer tool, and UBSAN. 0.99.2 ------ - Included workaround for a C++11 issue in GCC 4.8, contributed by Alex Merry - Fixed operator== so that json() == json(json::object()) - Fixed issue with `json` assignment to initializer list - Fixed issue with assignment to empty json object with multiple keys, e.g. json val; val["key1"]["key2"] = 1; 0.99.1 ------ - Fix to json_filter class - Fix to readme_examples 0.99 ---- - Fixes to deprecated json parse functions (deprecated, but still supposed to work) - The Visual C++ specific implementation for reading floating point numbers should have freed a `_locale_t` object, fixed - Added `json_type_traits` specialization to support assignment from non-const strings - When parsing fractional numbers in text, floating point number precision is retained, and made available to serialization to preserve round-trip. The default output precision has been changed from 15 to 16. - Added json `std::initializer_list` constructor for constructing arrays - The deprecated json member constants null, an_object, and an_array have been removed - Microsoft VC++ versions earlier than 2013 are no longer supported 0.98.4 ------ - Fixes issues with compilation with clang 0.98.3 ------ New features - Supports [Stefan Goessner's JsonPath](http://goessner.net/articles/JsonPath/). - json member function `find` added - json member function `count` added - json array range accessor `elements()` added, which supports range-based for loops over json arrays, and replaces `begin_elements` and `end_elements` - json object range accessor `members()` added, which supports range-based for loops over json objects, and replaces `begin_members` and `end_members` - New version of json `add` member function that takes a parameter `array_iterator` - json member function `shrink_to_fit` added API Changes - The json internal representation of signed and unsigned integers has been changed from `long long` and `unsigned long long` to `int64_t` and `uint64_t`. This should not impact you unless you've implemented your own `json_input_handler` or `json_output_handler`, in which case you'll need to change your `json_input_handler` function signatures void do_longlong_value(long long value, const basic_parsing_context& context) override void do_ulonglong_integer_value(unsigned long long value, const basic_parsing_context& context) override to void do_integer_value(int64_t value, const basic_parsing_context& context) override void do_uinteger_value(uint64_t value, const basic_parsing_context& context) override and your `json_output_handler` function signatures from void do_longlong_value(long long value) override void do_ulonglong_integer_value(unsigned long long value) override to void do_integer_value(int64_t value) override void do_uinteger_value(uint64_t value) override - `output_format` drops support for `floatfield` property Non-beaking API Changes - remove_range has been deprecated, use erase(array_iterator first, array_iterator last) instead - remove has been deprecated, use erase(const std::string& name ) instead - `json::parse_string` has been renamed to `json::parse`, `parse_string` is deprecated but still works - `json member function `is_empty` has been renamed to `empty`, `is_empty` is deprecated but still works. Rationale: consistency with C++ containers - json member functions `begin_elements` and `end_elements` have been deprecated, instead use `elements().begin()` and `elements.end()` - json member functions `begin_members` and `end_members` have been deprecated, instead use `members().begin()` and `members.end()` - json member function `has_member` has been deprecated, instead use `count`. Rationale: consistency with C++ containers - json member function `remove_member` has been deprecated, instead use `remove`. Rationale: only member function left with _element or _member suffix - json_parse_exception renamed to parse_error, json_parse_exception typedef to parse_error - json::parse(std::istream& is) renamed to json::parse_stream. json::parse(std::istream is) is deprecated but still works. 0.98.2 Release -------------- - `json` constructor is now templated, so constructors now accept extended types - Following [RFC7159](http://www.ietf.org/rfc/rfc7159.txt), `json_parser` now accepts any JSON value, removing the constraint that it be an object or array. - The member `json_type_traits` member functions `is`, `as`, and `assign` have been changed to static functions. if you have implemented your own type specializations, you will also have to change your `is`, `as` and `assign` functions to be static. - Removed json deprecated functions `custom_data`, `set_custom_data`, `add_custom_data` - `json_reader` member function `max_depth` has been renamed to `max_nesting_depth`, the former name is still supported. - `json` member function `resize_array` has been renamed to `resize`, the former name is still supported. jsoncons supports alternative ways for constructing `null`, `object`, and `array` values. null: json a = jsoncons::null_type(); // Using type constructor json b = json::null_type(); // Using alias json c(json::null); // From static data member prototype object: json a(); // Default is empty object json b = json::object(); // Using type constructor json c(json::an_object); // From static data member prototype array: json a = json::array(); // Using type constructor json b = json::make_array(); // Using factory method json c(json::an_array); // From static data member prototype Since C++ has possible order issues with static data members, the jsoncons examples and documentation have been changed to consistently use the other ways, and `json::null`, `json::an_object` and `json::an_array` have been, while still usable, deprecated. 0.98.1 Release -------------- - Enhances parser for CSV files that outputs JSON, see example below. - Adds `get_result` member function to `json_deserializer`, which returns the json value `v` stored in a `json_deserializer` as `std::move(v)`. The `root()` member function has been deprecated but is still supported. - Adds `is_valid` member function to `json_deserializer` - Enhances json::any class, adds type checks when casting back to original value - Fixes some warning messages 0.98 Release -------------- Bug fixes: - Fixes the noexcept specification (required for Visual Studio 2015 and later.) Fix contributed by Rupert Steel. - Fixes bug with proxy operator== when comparing object member values, such as in val["field"] == json("abc") Enhancements: - Refines error codes and improves error messages - Renames `json_reader` method `read` to `read_next`, reflecting the fact that it supports reading a sequence of JSON texts from a stream. The former name is deprecated but still works. - Adds `json_reader` method `check_done` that throws if there are unconsumed non-whitespace characters after one or more calls to `read_next`. - Adds getter and setter `max_depth` methods to allow setting the maximum JSON parse tree depth if desired, by default it is arbitrarily large (limited by heap memory.) - Modifies `json` static methods `parse_string`, `parse_file`, and `parse` behaviour to throw if there are unconsumed non-whitespace characters after reading one JSON text. Changes to extensions: - Changes the top level namespace for the extensions from `jsoncons_ext` to `jsoncons`, e.g. `jsoncons_ext::csv::csv_reader` becomes `jsoncons::csv::csv_reader` - Modifies csv_reader and csv_serializer so that the constructors are passed parameters in a `csv_parameters` object rather than a `json` object. - Adds more options to csv_reader 0.97.2 Release -------------- - Incorporates test suite files from http://www.json.org/JSON_checker/ into test suite - The `jsoncons` parser accepts all of the JSON_checker files that its supposed to accept. - Failures to reject incorrect exponential notation (e.g. [0e+-1]) have been fixed. - The `jsoncons` parser now rejects all of the JSON_checker files that its supposed to reject except ones with stuff after the end of the document, e.g. ["Extra close"]] (Currently the `jsoncons` parser stops after reading a complete JSON text, and supports reading a sequence of JSON texts.) - Incorporates a fix to operator== on json objects, contributed by Alex Merry 0.97.1 Release -------------- - "Transforming JSON with filters" example fixed - Added a class-specific in-place new to the json class that is implemented in terms of the global version (required to create json objects with placement new operator.) - Reorganized header files, removing unnecessary includes. - Incorporates validation contributed by Alex Merry for ensuring that there is an object or array on parse head. - Incorporates fix contributed by Milan Burda for “Switch case is in protected scope” clang build error 0.97 Release ------------ - Reversion of 0.96 change: The virtual methods `do_float_value`, `do_integer_value`, and `do_unsigned_value` of `json_input_handler` and `json_output_handler` have been restored to `do_double_value`, `do_longlong_value` and `do_ulonglong_value`, and their typedefed parameter types `float_type`, `integer_type`, and `unsigned_type` have been restored to `double`, `long long`, and `unsigned long long`. The rationale for this reversion is that the change doesn't really help to make the software more flexible, and that it's better to leave out the typedefs. There will be future enhancements to support greater numeric precision, but these will not affect the current method signatures. - Fix for "unused variable" warning message 0.96 Release ------------ This release includes breaking changes to interfaces. Going forward, the interfaces are expected to be stable. Breaking changes: - Renamed `error_handler` to `parse_error_handler`. - Renamed namespace `json_parser_error` to `json_parser_errc` - Renamed `value_adapter` to `json_type_traits`, if you have implemented your own type specializations, you will have to rename `value_adapter` also. - Only json arrays now support `operator[](size_t)` to loop over values, this is no longer supported for `json` objects. Use a json object iterator instead. - The virtual methods `do_double_value`, `do_integer_value` and `do_uinteger_value` of `json_input_handler` and `json_output_handler` have been renamed to `do_float_value`, `do_integer_value`, and `do_unsigned_value`, and their parameters have been changed from `double`, `long long`, and `unsigned long long` to typedefs `float_type`, `integer_type`, and `unsigned_type`. The rationale for this change is to allow different configurations for internal number types (reversed in 0.97.) General changes - `json` member function `begin_object` now returns a bidirectional iterator rather than a random access iterator. - Static singleton `instance` methods have been added to `default_parse_error_handler` and `empty_json_input_handler`. - Added to the `json` class overloaded static methods parse, parse_string and parse_file that take a `parse_error_handler` as a parameter. - Added methods `last_char()` and `eof()` to `parsing_context`. - Enhancements to json parsing and json parse event error notification. - Added to `json_input_handler` and `json_output_handler` a non virtual method `value` that takes a null terminated string. - Added methods `is_integer`, `is_unsigned` and `is_float` to `json` to replace `is_longlong`, `is_ulonglong` and `is_double`, which have been deprecated. - Added methods `as_integer`, `as_unsigned` and `as_float` to `json` to replace `is_longlong`, `is_ulonglong` and `is_double`, which have been deprecated. Bug fixes: - Fixed issue with column number reported by json_reader - Where &s[0] and s.length() were passed to methods, &s[0] has been replaced with s.c_str(). While this shouldn't be an issue on most implementations, VS throws an exception in debug modes when the string has length zero. - Fixes two issues in 0.95 reported by Alex Merry that caused errors with GCC: a superfluous typename has been removed in csv_serializer.hpp, and a JSONCONS_NOEXCEPT specifier has been added to the json_error_category_impl name method. - Fixed a number of typename issues in the 0.96 candidate identifed by Ignatov Serguei. - Fixes issues with testsuite cmake and scons reported by Alex Merry and Ignatov Serguei 0.95 ---- Enhancements: - Added template method `any_cast` to `json` class. - The allocator type parameter in basic_json is now supported, it allows you to supply a custom allocator for dynamically allocated, fixed size small objects in the json container. The allocator type is not used for structures including vectors and strings that use large or variable amounts of memory, these always use the default allocators. Non-breaking Change: - `json_filter` method `parent` has been renamed to `input_handler` (old name still works) Breaking change (if you've implemented your own input and output handlers, or if you've passed json events to input and output handlers directly): - The input handler virtual method `name(const std::string& name, const parsing_context& context)` has been changed to `do_name(const char* p, size_t length, const parsing_context& context)` - The output handler virtual method `name(const std::string& name)` has been changed to `do_name(const char* p, size_t length)` - The input handler virtual method `string_value(const std::string& value, const parsing_context& context)` has been changed to `do_string_value(const char* p, size_t length, const parsing_context& context)` - The output handler virtual method `string_value(const std::string& value)` has been changed to `do_string_value(const char* p, size_t length)` The rationale for the method parameter changes is to allow different internal representations of strings but preserve efficiency. - The input and output handler virtual implementation methods begin_json, end_json, begin_object, end_object, begin_array, end_array, name, string_value, longlong_value, ulonglong_value, double_value, bool_value and null_value have been renamed to do_begin_json, do_end_json, do_begin_object, do_end_object, do_begin_array, do_end_array, do_name, do_string_value, do_longlong_value, do_ulonglong_value, do_double_value, do_bool_value and do_null_value and have been made private. - Public non-virtual interface methods begin_json, end_json, begin_object, end_object, begin_array, end_array, name have been added to json_input_handler and json_output_handler. The rationale for these changes is to follow best C++ practices by making the json_input_handler and json_output_handler interfaces public non-virtual and the implementations private virtual. Refer to the documentation and tutorials for details. - The error_handler virtual implementation methods have been renamed to `do_warning` and `do_error`, and made private. Non virtual public interface methods `warning` and `error` have been added. Error handling now leverages `std::error_code` to communicate parser error events in an extendable way. Bug fixes: - Fixed bug in csv_reader 0.94.1 ------ Bug fixes: - Incorporates fix from Alex Merry for comparison of json objects 0.94 ---- Bug fixes - Incorporates contributions from Cory Fields for silencing some compiler warnings - Fixes bug reported by Vitaliy Gusev in json object operator[size_t] - Fixes bug in json is_empty method for empty objects Changes - json constructors that take string, double etc. are now declared explicit (assignments and defaults to get and make_array methods have their own implementation and do not depend on implicit constructors.) - make_multi_array renamed to make_array (old name is still supported) - Previous versions supported any type values through special methods set_custom_data, add_custom_data, and custom_data. This version introduces a new type json::any that wraps any values and works with the usual accessors set, add and as, so the specialized methods are no longer required. Enhancements - json get method with default value now accepts extended types as defaults - json make_array method with default value now accepts extended types as defaults New extensions - Added jsoncons_ext/boost/type_extensions.hpp to collect extensions traits for boost types, in particular, for boost::gregorian dates. 0.93 Release ------------ New features - Supports wide character strings and streams with wjson, wjson_reader etc. Assumes UTF16 encoding if sizeof(wchar_t)=2 and UTF32 encoding if sizeof(wchar_t)=4. - The empty class null_type is added to the jsoncons namespace, it replaces the member type json::null_type (json::null_type is typedefed to jsoncons::null_type for backward compatibility.) Defect fixes: - The ascii character 0x7f (del) was not being considered a control character to be escaped, this is fixed. - Fixed two issues with serialization when the output format property escape_all_non_ascii is enabled. One, the individual bytes were being checked if they were non ascii, rather than first converting to a codepoint. Two, continuations weren't being handled when decoding. 0.92a Release ------------- Includes contributed updates for valid compilation and execution in gcc and clang environments 0.92 Release ------------ Breaking change (but only if you have subclassed json_input_handler or json_output_handler) - For consistency with other names, the input and output handler methods new to 0.91 - value_string, value_double, value_longlong, value_ulonglong and value_bool - have been renamed to string_value, double_value, longlong_value, ulonglong_value and bool_value. Non breaking changes (previous features are deprecated but still work) - name_value_pair has been renamed to member_type (typedefed to previous name.) - as_string(output_format format) has been deprecated, use the existing to_string(output_format format) instead Enhancements: - json now has extensibilty, you can access and modify json values with new types, see the tutorial Extensibility Preparation for allocator support: - The basic_json and related classes now have an Storage template parameter, which is currently just a placeholder, but will later provide a hook to allow users to control how json storage is allocated. This addition is transparent to users of the json and related classes. 0.91 Release ------------ This release should be largely backwards compatible with 0.90 and 0.83 with two exceptions: 1. If you have used object iterators, you will need to replace uses of std::pair with name_value_pair, in particular, first becomes name() and second becomes value(). 2. If you have subclassed json_input_handler, json_output_handler, or json_filter, and have implemented value(const std::string& ..., value(double ..., etc., you will need to modify the names to value_string(const std::string& ..., value_double(double ... (no changes if you are feeding existing implementations.) The changes are - Replaced std::pair with name_value_pair that has accessors name() and value() - In json_input_handler and json_output_handler, allowed for overrides of the value methods by making them non-virtual and adding virtual methods value_string, value_double, value_longlong, value_ulonglong, and value_bool Other new features: - Changed implementation of is and as, the current implementation should be user extensible - make_multi_array makes a multidimensional array with the number of dimensions specified as a template parameter. Replaces make_2d_array and make_3d_array, which are now deprecated. - Added support for is> and as> - Removed JSONCONS_NO_CXX11_RVALUE_REFERENCES, compiler must support move semantics Incorporates a number of contributions from Pedro Larroy and the developers of the clearskies_core project: - build system for posix systems - GCC to list of supported compilers - Android fix - fixed virtual destructors missing in json_input_handler, json_output_handler and parsing_context - fixed const_iterator should be iterator in json_object implementation To clean up the interface and avoid too much duplicated functionality, we've deprecated some json methods (but they still work) make_array Use json val(json::an_array) or json::make_multi_array<1>(...) instead (but make_array will continue to work) make_2d_array make_3d_array Use make_multi_array<2> and make_multi_array<3> instead as_vector Use as> etc. instead as_int as_uint as_char Use as, as, and as instead Release 0.90a ------------- Fixed issue affecting clang compile Release 0.90 ------------ This release should be fully backwards compatible with 0.83. Includes performance enhancements to json_reader and json_deserializer Fixes issues with column numbers reported with exceptions Incorporates a number of patches contributed by Marc Chevrier: - Fixed issue with set member on json object when a member with that name already exists - clang port - cmake build files for examples and test suite - json template method is for examining the types of json values - json template method as for accessing json values 0.83 ------------ Optimizations (very unlikely to break earlier code) - get(const std::name& name) const now returns const json& if keyed value exists, otherwise a const reference to json::null - get(const std::string& name, const json& default_val) const now returns const json (actually a const proxy that evaluates to json if read) Bug fixes - Line number not incremented within multiline comment - fixed Deprecated features removed - Removed deprecated output_format properties (too much bagage to carry around) 0.82a ------------- - The const version of the json operator[](const std::string& name) didn't need to return a proxy, the return value has been changed to const json& (this change is transparent to the user.) - get(const std::name& name) has been changed to return a copy (rather than a reference), and json::null if there is no member with that name (rather than throw.) This way both get methods return default values if no keyed value exists. - non-const and const methods json& at(const std::name& name) have been added to replace the old single argument get method. These have the same behavior as the corresponding operator[] functions, but the non-const at is more efficient. 0.81 ------------ - Added accessor and modifier methods floatfield to output_format to provide a supported way to set the floatfield format flag to fixed or scientific with a specified number of decimal places (this can be done in older versions, but only with deprecated methods.) - The default constructor now constructs an empty object (rather than a null object.) While this is a change, it's unlikely to break exisitng code (all test cases passed without modification.) This means that instead of json obj(json::an_object); obj["field"] = "field"; you can simply write json obj; obj["field"] = "field"; The former notation is still supported, though. - Added a version of 'resize_array' to json that resizes the array to n elements and initializes them to a specified value. - Added a version of the static method json::make_array that takes no arguments and makes an empty json array Note that json arr(json::an_array); is equivalent to json arr = json::make_array(); and json arr(json::an_array); arr.resize_array(10,0.0); is equivalent to json arr = json::make_array(10,0.0); For consistency the json::make_array notation is now favored in the documentation. 0.71 ------------- - Added resize_array method to json for resizing json arrays - Fixed issue with remove_range method (templated code failed to compile if calling this method.) - Added remove_member method to remove a member from a json object - Fixed issue with multiline line comments, added test case - Fixed issue with adding custom data to a json array using add_custom_data, added examples. 0.70 ------------- - Since 0.50, jsoncons has used snprintf for default serialization of double values to string values. This can result in invalid json output when running on a locale like German or Spanish. The period character (‘.’) is now always used as the decimal point, non English locales are ignored. - The output_format methods that support alternative floating point formatting, e.g. fixed, have been deprecated. - Added a template method as_vector to the json class. If a json value is an array and conversion is possible to the template type, returns a std::vector of that type, otherwise throws an std::exception. Specializations are provided for std::string, bool, char, int, unsigned int, long, unsigned long, long long, unsigned long long, and double. For example std::string s("[0,1,2,3]"); json val = json::parse_string(s); std::vector v = val.as_vector(); - Undeprecated the json member function precision 0.60b ------------- This release (0.60b) is fully backwards compatible with 0.50. A change introduced with 0.60 has been reversed. 0.60 introduced an alternative method of constructing a json arrray or object with an initial default constructor, a bug with this was fixed in 0.60a, but this feature and related documentation has been removed because it added complexity but no real value. ### Enhancements - Added swap member function to json - Added add and add_custom_data overrides to json that take an index value, for adding a new element at the specified index and shifting all elements currently at or above that index to the right. - Added capacity member functions to json ### 0.60 extensions - csv_serializer has been added to the csv extension 0.50 ------------ This release is fully backwards compatible with 0.4*, and mostly backwards compatible to 0.32 apart from the two name changes in 0.41 Bug fixes - When reading the escaped characters "\\b", "\\f", "\\r" and "\\t" appearing in json strings, json_reader was replacing them with the linefeed character, this has been fixed. Deprecated - Deprecated modifiers precision and fixed_decimal_places from output_format. Use set_floating_point_format instead. - Deprecated constructor that takes indenting parameter from output_format. For pretty printing with indenting, use the pretty_print function or pass the indenting parameter in json_serializer. Changes - When serializing floating point values to a stream, previous versions defaulted to default floating point precision with a precision of 16. This has been changed to truncate trailing zeros but keep one if immediately after a decimal point. New features - For line reporting in parser error messages, json_reader now recognizes \\r\\n, \\n alone or \\r alone (\\r alone is new.) - Added set_floating_point_format methods to output_format to give more control over floating point notation. Non functional enhancements - json_reader now estimates the minimum capacity for arrays and objects, and reports that information for the begin_array and begin_object events. This greatly reduces reallocations. 0.42 ------------ - Fixed another bug with multi line /**/ comments - Minor fixes to reporting line and column number of errors - Added fixed_decimal_places setter to output_format - Added version of as_string to json that takes output_format as a parameter - Reorganization of test cases and examples in source tree 0.41 ------------ - Added non-member overload swap(json& a, json& b) - Fixed bug with multi line /**/ comments - Added begin_json and end_json methods to json_output_handler - json_deserializer should now satisfy basic exception safety (no leak guarantee) - Moved csv_reader.hpp to jsoncons_ext/csv directory - Changed csv_reader namespace to jsoncons::csv - json::parse_file no longer reads the entire file into memory before parsing (it now uses json_reader default buffering) 0.40 ------------ - json_listener renamed to json_input_handler - json_writer renamed to json_output_handler - Added json_filter class - json get method that takes default argument now returns a value rather than a reference - Issue in csv_reader related to get method issue fixed - Issue with const json operator[] fixed - Added as_char method to json - Improved exception safety, some opportunites for memory leaks in the presence of exceptions removed 0.33 ------------ Added reserve method to json Added static make_3d_array method to json json_reader now configured for buffered reading Added csv_reader class for reading CSV files and producing JSON events Fixed bug with explicitly passing output_format in pretty_print. 0.32 ------------ Added remove_range method, operator== and operator!= to proxy and json objects Added static methods make_array and make_2d_array to json 0.31 ------------ error_handler method content_error renamed to error Added error_code to warning, error and fatal_error methods of error_handler 0.30 ------------ json_in_stream renamed to json_listener json_out_stream renamed to json_writer Added buffer accessor method to parsing_context 0.20 ------------ Added parsing_context class for providing information about the element being parsed. error_handler methods take message and parsing_context parameters json_in_stream handlers take parsing_context parameter 0.19 ------------ Added error_handler class for json_reader Made json_exception a base class for all json exceptions Added root() method to json_deserializer to get a reference to the json value Removed swap_root() method from json_deserializer 0.18 ------------ Renamed serialize() class method to to_stream() in json Custom data serialization supported through template function specialization of serialize (reverses change in 0.17) 0.17 ------------ Added is_custom() method to json and proxy get_custom() method renamed to custom_data() in json and proxy Added clear() method to json and proxy set_member() method renamed to set() set_custom() method renamed to set_custom_data() push_back() method renamed to add() in json and proxy Added add_custom_data method() in json and proxy Custom data serialization supported through template class specialization of custom_serialization (replaces template function specialization of serialize) 0.16 ------------ Change to json_out_stream and json_serializer: void value(const custom_data& value) removed. Free function serialize replaces free function to_stream for serializing custom data. pretty print tidied up for nested arrays 0.15 ------------ Made eof() method on json_reader public, to support reading multiple JSON objects from a stream. 0.14 ------------ Added pretty_print class Renamed json_stream_writer to json_serializer, implements pure virtual class json_out_stream Renamed json_stream_listener to json_deserializer implements pure virtual class json_in_stream Renamed json_parser to json_reader, parse to read. Changed indenting so object and array members start on new line. Added support for storing user data in json object, and serializing to JSON. 0.13 ------------ Replaced simple_string union member with json_string that wraps std::basic_string name() and value() event handler methods on basic_json_stream_writer take const std::basic_string& rather than const Char* and length. 0.12 ------------ Implemented operator<< for json::proxy Added to_stream methods to json::proxy 0.11 ------------ Added members to json_parser to access and modify the buffer capacity Added checks when parsing integer values to determine overflow for long long and unsigned long long, and if overflow, parse them as doubles. jsoncons-1.3.2/CMakeLists.txt000066400000000000000000000057241477700171100161260ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.5) project(jsoncons CXX) set(JSONCONS_PROJECT_DIR ${PROJECT_SOURCE_DIR}) set(JSONCONS_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) # Versioning # ========== file(STRINGS "${JSONCONS_INCLUDE_DIR}/jsoncons/config/version.hpp" jsoncons_version_defines REGEX "#define JSONCONS_VERSION_(MAJOR|MINOR|PATCH)") foreach(ver ${jsoncons_version_defines}) if(ver MATCHES "#define JSONCONS_VERSION_(MAJOR|MINOR|PATCH) +([^ ]+)$") set(JSONCONS_VERSION_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}" CACHE INTERNAL "") endif() endforeach() set(${PROJECT_NAME}_VERSION ${JSONCONS_VERSION_MAJOR}.${JSONCONS_VERSION_MINOR}.${JSONCONS_VERSION_PATCH}) message(STATUS "jsoncons v${${PROJECT_NAME}_VERSION}") # Build # ===== add_library(jsoncons INTERFACE) target_include_directories(jsoncons INTERFACE $ $) OPTION(JSONCONS_BUILD_TESTS "jsoncons test suite" ON) if(JSONCONS_BUILD_TESTS) include(CTest) enable_testing() add_subdirectory(test) endif() # Installation # ============ include(GNUInstallDirs) include(CMakePackageConfigHelpers) install(TARGETS jsoncons EXPORT ${PROJECT_NAME}-targets) # Makes the project importable from the build directory export(EXPORT ${PROJECT_NAME}-targets FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake") install(DIRECTORY ${JSONCONS_INCLUDE_DIR}/jsoncons ${JSONCONS_INCLUDE_DIR}/jsoncons_ext DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) # GNUInstallDirs "DATADIR" wrong here; CMake search path wants "share". set(JSONCONS_CMAKECONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" CACHE STRING "install path for jsonconsConfig.cmake") configure_package_config_file(cmake/Config.cmake "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" INSTALL_DESTINATION ${JSONCONS_CMAKECONFIG_INSTALL_DIR}) # jsoncons is header-only and does not depend on the architecture. if (${CMAKE_VERSION} VERSION_LESS "3.14.0") write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake VERSION ${${PROJECT_NAME}_VERSION} COMPATIBILITY AnyNewerVersion) else () write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake VERSION ${${PROJECT_NAME}_VERSION} COMPATIBILITY AnyNewerVersion ARCH_INDEPENDENT) endif () install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake DESTINATION ${JSONCONS_CMAKECONFIG_INSTALL_DIR}) install(EXPORT ${PROJECT_NAME}-targets FILE ${PROJECT_NAME}Targets.cmake DESTINATION ${JSONCONS_CMAKECONFIG_INSTALL_DIR}) jsoncons-1.3.2/LICENSE000066400000000000000000000030141477700171100143610ustar00rootroot00000000000000// Copyright Daniel Parker 2013 - 2020. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE or copy at // http://www.boost.org/LICENSE_1_0.txt) Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. jsoncons-1.3.2/README.md000066400000000000000000000754611477700171100146520ustar00rootroot00000000000000# JSONCONS jsoncons is a C++, header-only library for constructing [JSON](http://www.json.org) and JSON-like data formats such as [CBOR](http://cbor.io/). For each supported data format, it enables you to work with the data in a number of ways: - As a variant-like, allocator-aware, data structure, [basic_json](doc/ref/corelib/basic_json.md) - As a strongly typed C++ data structure that implements [json_type_traits](doc/ref/corelib/json_type_traits.md) - With cursor-level access to a stream of parse events, somewhat analogous to StAX pull parsing and push serializing in the XML world. Compared to other JSON libraries, jsoncons has been designed to handle very large JSON texts. At its heart are SAX-style parsers and serializers. It supports reading an entire JSON text in memory in a variant-like structure. But it also supports efficient access to the underlying data using StAX-style pull parsing and push serializing. And it supports incremental parsing into a user's preferred form, using information about user types provided by specializations of [json_type_traits](doc/ref/corelib/json_type_traits.md). The [jsoncons data model](doc/ref/corelib/data-model.md) supports the familiar JSON types - nulls, booleans, numbers, strings, arrays, objects - plus byte strings. In addition, jsoncons supports semantic tagging of datetimes, epoch times, big integers, big decimals, big floats and binary encodings. This allows it to preserve these type semantics when parsing JSON-like data formats such as CBOR that have them. jsoncons is distributed under the [Boost Software License](http://www.boost.org/users/license.html). jsoncons is free but welcomes support to sustain its development. If you find this library helpful, please consider making a [one time donation](https://paypal.me/jsoncons?locale.x=en_US) or becoming a [:heart: sponsor](https://github.com/sponsors/danielaparker). As the `jsoncons` library has evolved, names have sometimes changed. To ease transition, jsoncons deprecates the old names but continues to support many of them. The deprecated names can be suppressed by defining the macro `JSONCONS_NO_DEPRECATED`, and doing so is recommended for new code. ## Extensions - [bson](doc/ref/bson/bson.md) implements decode from and encode to the [Binary JSON](http://bsonspec.org/) data format. - [cbor](doc/ref/cbor/cbor.md) implements decode from and encode to the IETF standard [Concise Binary Object Representation](http://cbor.io/) data format. In addition it supports tags for [stringref](http://cbor.schmorp.de/stringref) and tags for [typed arrays](https://tools.ietf.org/html/rfc8746). - [csv](doc/ref/csv/csv.md) implements decode from and encode to CSV files. - [jmespath](doc/ref/jmespath/jmespath.md) implements [JMESPath](https://jmespath.org/), a query language for transforming JSON documents into other JSON documents. - [jsonpatch](doc/ref/jsonpatch/jsonpatch.md) implements the IETF standard [JavaScript Object Notation (JSON) Patch](https://tools.ietf.org/html/rfc6902) - [mergepatch](doc/ref/mergepatch/mergepatch.md) implements the IETF standard [JSON Merge Patch](https://datatracker.ietf.org/doc/html/rfc7386) - [jsonpath](doc/ref/jsonpath/jsonpath.md) implements [Stefan Goessner's JSONPath](http://goessner.net/articles/JsonPath/). It also supports search and replace using JSONPath expressions. - [jsonpointer](doc/ref/jsonpointer/jsonpointer.md) implements the IETF standard [JavaScript Object Notation (JSON) Pointer](https://tools.ietf.org/html/rfc6901) - [jsonschema](doc/ref/jsonschema/jsonschema.md) implements Drafts 4, 6, 7, 2019-9 and 2020-12 of the [JSON Schema Specification](https://json-schema.org/specification) (since 0.174.0) - [msgpack](doc/ref/msgpack/msgpack.md) implements decode from and encode to the [MessagePack](http://msgpack.org/index.html) data format. - [ubjson](doc/ref/ubjson/ubjson.md) implements decode from and encode to the [Universal Binary JSON Specification](http://ubjson.org/) data format. ## What users say _"Apache Kvrocks consistently utilizes jsoncons to offer support for JSON data structures to users. We find the development experience with jsoncons outstanding!"_ _"I have been using your library in my native language – R – and have created an R package making it easy for (a) JMESpath and JSONpath queries on JSON strings or R objects and (b) for other R developers to link to your library."_ _"I’m using your library for an external interface to pass data, as well as using the conversions from csv to json, which are really helpful for converting data for use in javascript"_ _"Verified that, for my needs in JSON and CBOR, it is working perfectly"_ _"the JSONPath feature of this library, it's great"_ _"We use JMESPath implementation quite extensively"_ _"We love your JSON Schema validator. We are using it in ER/Studio our data modelling tool to parse JSON Schema files so we can create entity relations models from them."_ _"the serialization lib of choice with its beautiful mappings and ease of use"_ _"really good"_ _"awesome project"_ _"very solid and very dependable"_ _"my team loves it"_ _"Your repo rocks!!!!!"_ ## Mentions on the web [Get started with HealthImaging image sets and image frames using an AWS SDK](https://docs.aws.amazon.com/healthimaging/latest/devguide/example_medical-imaging_Scenario_ImageSetsAndFrames_section.html) [RubyGems.org](https://rubygems.org/gems/jsoncons/versions/0.1.3?locale=en)   [rjsoncons](https://mtmorgan.github.io/rjsoncons/)   [CoppeliaSim](https://manual.coppeliarobotics.com/en/zmqRemoteApiOverview.htm) ## Get jsoncons You can use the [vcpkg](https://github.com/Microsoft/vcpkg) platform library manager to install the [jsoncons package](https://github.com/microsoft/vcpkg/tree/master/ports/jsoncons). Or, download the [latest release](https://github.com/danielaparker/jsoncons/releases) and unpack the zip file. Copy the directory `include/jsoncons` to your `include` directory. If you wish to use extensions, copy `include/jsoncons_ext` as well. Or, download the latest code on [main](https://github.com/danielaparker/jsoncons/archive/main.zip). ## How to use it - [Quick guide](http://danielaparker.github.io/jsoncons) - [Examples](doc/Examples.md) - [Reference](doc/Reference.md) - [Ask questions and suggest ideas for new features](https://github.com/danielaparker/jsoncons/discussions) The library requires a C++ Compiler with C++11 support. In addition the library defines `jsoncons::endian`, `jsoncons::basic_string_view`, `jsoncons::optional`, and `jsoncons::span`, which will be typedefed to their standard library equivalents if detected. Otherwise they will be typedefed to internal, C++11 compatible, implementations. The library uses exceptions and in some cases [std::error_code](https://en.cppreference.com/w/cpp/error/error_code)'s to report errors. Apart from `jsoncons::assertion_error`, all jsoncons exception classes implement the [jsoncons::json_error](doc/ref/corelib/json_error.md) interface. If exceptions are disabled or if the compile time macro `JSONCONS_NO_EXCEPTIONS` is defined, throws become calls to `std::terminate`. ## Benchmarks [json_benchmarks](https://github.com/danielaparker/json_benchmarks) provides some measurements about how `jsoncons` compares to other `json` libraries. - [JSONTestSuite and JSON_checker test suites](https://danielaparker.github.io/json_benchmarks/) - [Performance benchmarks with text and integers](https://github.com/danielaparker/json_benchmarks/blob/master/report/performance.md) - [Performance benchmarks with text and doubles](https://github.com/danielaparker/json_benchmarks/blob/master/report/performance_fp.md) [JSONPath Comparison](https://cburgmer.github.io/json-path-comparison/) shows how jsoncons JsonPath compares with other implementations ## Examples [Working with JSON data](#E1) [Working with CBOR data](#E2)
### Working with JSON data For the examples below you need to include some header files and initialize a string of JSON data: ```cpp #include #include #include using namespace jsoncons; // for convenience std::string data = R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90, "generated": 1514862245 } ] } )"; ``` jsoncons allows you to work with the data in a number of ways: - As a variant-like data structure, [basic_json](doc/ref/corelib/basic_json.md) - As a strongly typed C++ data structure that implements [json_type_traits](doc/ref/corelib/json_type_traits.md) - With [cursor-level access](doc/ref/corelib/basic_json_cursor.md) to a stream of parse events #### As a variant-like data structure ```cpp int main() { // Parse the string of data into a json value json j = json::parse(data); // Does object member reputons exist? std::cout << "(1) " << std::boolalpha << j.contains("reputons") << "\n\n"; // Get a reference to reputons array const json& v = j["reputons"]; // Iterate over reputons array std::cout << "(2)\n"; for (const auto& item : v.array_range()) { // Access rated as string and rating as double std::cout << item["rated"].as() << ", " << item["rating"].as() << "\n"; } std::cout << "\n"; // Select all "rated" with JSONPath std::cout << "(3)\n"; json result = jsonpath::json_query(j,"$..rated"); std::cout << pretty_print(result) << "\n\n"; // Serialize back to JSON std::cout << "(4)\n" << pretty_print(j) << "\n\n"; } ``` Output: ``` (1) true (2) Marilyn C, 0.9 (3) [ "Marilyn C" ] (4) { "application": "hiking", "reputons": [ { "assertion": "advanced", "generated": 1514862245, "rated": "Marilyn C", "rater": "HikingAsylum", "rating": 0.9 } ] } ``` #### As a strongly typed C++ data structure jsoncons supports transforming JSON texts into C++ data structures. The functions [decode_json](doc/ref/corelib/decode_json.md) and [encode_json](doc/ref/corelib/encode_json.md) convert strings or streams of JSON data to C++ data structures and back. Decode and encode work for all C++ classes that have [json_type_traits](doc/ref/corelib/json_type_traits.md) defined. jsoncons already supports many types in the standard library, and your own types will be supported too if you specialize `json_type_traits` in the `jsoncons` namespace. ```cpp namespace ns { enum class hiking_experience {beginner,intermediate,advanced}; class hiking_reputon { std::string rater_; hiking_experience assertion_; std::string rated_; double rating_; std::optional generated_; // assumes C++17, if not use jsoncons::optional std::optional expires_; public: hiking_reputon(const std::string& rater, hiking_experience assertion, const std::string& rated, double rating, const std::optional& generated = std::optional(), const std::optional& expires = std::optional()) : rater_(rater), assertion_(assertion), rated_(rated), rating_(rating), generated_(generated), expires_(expires) { } const std::string& rater() const {return rater_;} hiking_experience assertion() const {return assertion_;} const std::string& rated() const {return rated_;} double rating() const {return rating_;} std::optional generated() const {return generated_;} std::optional expires() const {return expires_;} friend bool operator==(const hiking_reputon& lhs, const hiking_reputon& rhs) { return lhs.rater_ == rhs.rater_ && lhs.assertion_ == rhs.assertion_ && lhs.rated_ == rhs.rated_ && lhs.rating_ == rhs.rating_ && lhs.confidence_ == rhs.confidence_ && lhs.expires_ == rhs.expires_; } friend bool operator!=(const hiking_reputon& lhs, const hiking_reputon& rhs) { return !(lhs == rhs); }; }; class hiking_reputation { std::string application_; std::vector reputons_; public: hiking_reputation(const std::string& application, const std::vector& reputons) : application_(application), reputons_(reputons) {} const std::string& application() const { return application_;} const std::vector& reputons() const { return reputons_;} }; } // namespace ns // Declare the traits. Specify which data members need to be serialized. JSONCONS_ENUM_TRAITS(ns::hiking_experience, beginner, intermediate, advanced) // First four members listed are mandatory, generated and expires are optional JSONCONS_N_CTOR_GETTER_TRAITS(ns::hiking_reputon, 4, rater, assertion, rated, rating, generated, expires) // All members are mandatory JSONCONS_ALL_CTOR_GETTER_TRAITS(ns::hiking_reputation, application, reputons) int main() { // Decode the string of data into a c++ structure ns::hiking_reputation v = decode_json(data); // Iterate over reputons array value std::cout << "(1)\n"; for (const auto& item : v.reputons()) { std::cout << item.rated() << ", " << item.rating(); if (item.generated()) { std::cout << ", " << (*item.generated()).count(); } std::cout << "\n"; } // Encode the c++ structure into a string std::string s; encode_json(v, s, indenting::indent); std::cout << "(2)\n"; std::cout << s << "\n"; } ``` Output: ``` (1) Marilyn C, 0.9, 1514862245 (2) { "application": "hiking", "reputons": [ { "assertion": "advanced", "generated": 1514862245, "rated": "Marilyn C", "rater": "HikingAsylum", "rating": 0.9 } ] } ``` This example makes use of the convenience macros `JSONCONS_ENUM_TRAITS`, `JSONCONS_N_CTOR_GETTER_TRAITS`, and `JSONCONS_ALL_CTOR_GETTER_TRAITS` to specialize the [json_type_traits](doc/ref/corelib/json_type_traits.md) for the enum type `ns::hiking_experience`, the class `ns::hiking_reputon` (with some non-mandatory members), and the class `ns::hiking_reputation` (with all mandatory members.) The macro `JSONCONS_ENUM_TRAITS` generates the code from the enum identifiers, and the macros `JSONCONS_N_CTOR_GETTER_TRAITS` and `JSONCONS_ALL_CTOR_GETTER_TRAITS` generate the code from the get functions and a constructor. These macro declarations must be placed outside any namespace blocks. See [examples](doc/Examples.md#G0) for other ways of specializing `json_type_traits`. #### With cursor-level access A typical pull parsing application will repeatedly process the `current()` event and call `next()` to advance to the next event, until `done()` returns `true`. ```cpp int main() { json_string_cursor cursor(data); for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::end_array: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::begin_object: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::end_object: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::key: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::string_value: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::null_value: std::cout << event.event_type() << "\n"; break; case staj_event_type::bool_value: std::cout << event.event_type() << ": " << std::boolalpha << event.get() << "\n"; break; case staj_event_type::int64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::double_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; default: std::cout << "Unhandled event type: " << event.event_type() << " " << "\n"; break; } } } ``` Output: ``` begin_object key: application string_value: hiking key: reputons begin_array begin_object key: rater string_value: HikingAsylum key: assertion string_value: advanced key: rated string_value: Marilyn C key: rating double_value: 0.9 key: generated uint64_value: 1514862245 end_object end_array end_object ``` You can apply a filter to a cursor using the pipe syntax (e.g., `cursor | filter1 | filter2 | ...`) ```cpp int main() { std::string name; auto filter = [&](const staj_event& ev, const ser_context&) -> bool { if (ev.event_type() == staj_event_type::key) { name = ev.get(); return false; } if (name == "rated") { name.clear(); return true; } return false; }; json_string_cursor cursor(data); auto filtered_c = cursor | filter; for (; !filtered_c.done(); filtered_c.next()) { const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::string_value: // Or std::string_view, if C++17 std::cout << event.event_type() << ": " << event.get() << "\n"; break; default: std::cout << "Unhandled event type\n"; break; } } } ``` Output: ``` Marilyn C ```
### Working with CBOR data For the examples below you need to include some header files and initialize a buffer of CBOR data: ```cpp #include #include #include #include #include using namespace jsoncons; // for convenience const std::vector data = { 0x9f, // Start indefinte length array 0x83, // Array of length 3 0x63, // String value of length 3 0x66,0x6f,0x6f, // "foo" 0x44, // Byte string value of length 4 0x50,0x75,0x73,0x73, // 'P''u''s''s' 0xc5, // Tag 5 (bigfloat) 0x82, // Array of length 2 0x20, // -1 0x03, // 3 0x83, // Another array of length 3 0x63, // String value of length 3 0x62,0x61,0x72, // "bar" 0xd6, // Expected conversion to base64 0x44, // Byte string value of length 4 0x50,0x75,0x73,0x73, // 'P''u''s''s' 0xc4, // Tag 4 (decimal fraction) 0x82, // Array of length 2 0x38, // Negative integer of length 1 0x1c, // -29 0xc2, // Tag 2 (positive bignum) 0x4d, // Byte string value of length 13 0x01,0x8e,0xe9,0x0f,0xf6,0xc3,0x73,0xe0,0xee,0x4e,0x3f,0x0a,0xd2, 0xff // "break" }; ``` jsoncons allows you to work with the CBOR data similarly to JSON data: - As a variant-like data structure, [basic_json](doc/ref/corelib/basic_json.md) - As a strongly typed C++ data structure that implements [json_type_traits](doc/ref/corelib/json_type_traits.md) - With [cursor-level access](doc/ref/cbor/basic_cbor_cursor.md) to a stream of parse events #### As a variant-like data structure ```cpp int main() { // Parse the CBOR data into a json value json j = cbor::decode_cbor(data); // Pretty print std::cout << "(1)\n" << pretty_print(j) << "\n\n"; // Iterate over rows std::cout << "(2)\n"; for (const auto& row : j.array_range()) { std::cout << row[1].as() << " (" << row[1].tag() << ")\n"; } std::cout << "\n"; // Select the third column with JSONPath std::cout << "(3)\n"; json result = jsonpath::json_query(j,"$[*][2]"); std::cout << pretty_print(result) << "\n\n"; // Serialize back to CBOR std::vector buffer; cbor::encode_cbor(j, buffer); std::cout << "(4)\n" << byte_string_view(buffer) << "\n\n"; } ``` Output: ``` (1) [ ["foo", "UHVzcw", "0x3p-1"], ["bar", "UHVzcw==", "1.23456789012345678901234567890"] ] (2) 50,75,73,73 (n/a) 50,75,73,73 (base64) (3) [ "0x3p-1", "1.23456789012345678901234567890" ] (4) 82,83,63,66,6f,6f,44,50,75,73,73,c5,82,20,03,83,63,62,61,72,d6,44,50,75,73,73,c4,82,38,1c,c2,4d,01,8e,e9,0f,f6,c3,73,e0,ee,4e,3f,0a,d2 ``` #### As a strongly typed C++ data structure ```cpp int main() { // Parse the string of data into a std::vector> value auto val = cbor::decode_cbor>>(data); std::cout << "(1)\n"; for (const auto& row : val) { std::cout << std::get<0>(row) << ", " << std::get<1>(row) << ", " << std::get<2>(row) << "\n"; } std::cout << "\n"; // Serialize back to CBOR std::vector buffer; cbor::encode_cbor(val, buffer); std::cout << "(2)\n" << byte_string_view(buffer) << "\n\n"; } ``` Output: ``` (1) foo, 50,75,73,73, 0x3p-1 bar, 50,75,73,73, 1.23456789012345678901234567890 (2) 82,9f,63,66,6f,6f,44,50,75,73,73,66,30,78,33,70,2d,31,ff,9f,63,62,61,72,44,50,75,73,73,78,1f,31,2e,32,33,34,35,36,37,38,39,30,31,32,33,34,35,36,37,38,39,30,31,32,33,34,35,36,37,38,39,30,ff ``` Note that when decoding the bigfloat and decimal fraction into a `std::string`, we lose the semantic information that the variant like data structure preserved with a tag, so serializing back to CBOR produces a text string. #### With cursor-level access A typical pull parsing application will repeatedly process the `current()` event and call `next()` to advance to the next event, until `done()` returns `true`. ```cpp int main() { cbor::cbor_bytes_cursor cursor(data); for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::end_array: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::begin_object: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::end_object: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::key: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::string_value: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::byte_string_value: std::cout << event.event_type() << ": " << event.get>() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::null_value: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::bool_value: std::cout << event.event_type() << ": " << std::boolalpha << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::int64_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::half_value: case staj_event_type::double_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; default: std::cout << "Unhandled event type " << event.event_type() << " " << "(" << event.tag() << ")\n"; break; } } } ``` Output: ``` begin_array (n/a) begin_array (n/a) string_value: foo (n/a) byte_string_value: 50,75,73,73 (n/a) string_value: 0x3p-1 (bigfloat) end_array (n/a) begin_array (n/a) string_value: bar (n/a) byte_string_value: 50,75,73,73 (base64) string_value: 1.23456789012345678901234567890 (bigdec) end_array (n/a) end_array (n/a) ``` You can apply a filter to a cursor using the pipe syntax, ```cpp int main() { auto filter = [&](const staj_event& ev, const ser_context&) -> bool { return (ev.tag() == semantic_tag::bigdec) || (ev.tag() == semantic_tag::bigfloat); }; cbor::cbor_bytes_cursor cursor(data); auto filtered_c = cursor | filter; for (; !filtered_c.done(); filtered_c.next()) { const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::string_value: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; default: std::cout << "Unhandled event type " << event.event_type() << " " << "(" << event.tag() << ")\n"; break; } } } ``` Output: ``` string_value: 0x3p-1 (bigfloat) string_value: 1.23456789012345678901234567890 (bigdec) ``` ## Supported compilers jsoncons requires a compiler with minimally C++11 support. It is tested in continuous integration on [Github Actions](https://github.com/danielaparker/jsoncons/actions) and [circleci](https://app.circleci.com/pipelines/circleci/EFpnYcrBiZEvYvns3VF4vT). [UndefinedBehaviorSanitizer (UBSan)](http://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) diagnostics are enabled for selected gcc and clang builds. Since v0.151.0, it is integrated with [Google OSS-fuzz](https://github.com/google/oss-fuzz), with coverage for all parsers and encoders. | Compiler | Version | Standard | Architecture | Operating System | CI Service | |-------------------------|------------------------------------|--------------|--------------|------------------|----------------| | Visual Studio | vs2019 | default | x86, x64 | Windows 11 | GitHub Actions | | | vs2022 | default | x86, x64 | Windows 11 | GitHub Actions | | Visual Studio - clang | vs2019 | default | x86, x64 | Windows 11 | GitHub Actions | | | vs2022 | default | x86, x64 | Windows 11 | GitHub Actions | | g++ | 6, 7, 8, 9, 10, 11, 12 | default | x64 | Ubuntu | circleci | | g++ | 12 | c++20 | x64 | Ubuntu | GitHub Actions | | clang | 3.9, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 | default | x64 | Ubuntu | circleci | | clang | 14 | c++20 | x64 | Ubuntu | GitHub Actions | | clang xcode | 11, 12, 13 | default | x64 | OSX 11 | GitHub Actions | | clang xcode | 13, 14 | default | x64 | OSX 12 | GitHub Actions | ## Building the test suite and examples with CMake [CMake](https://cmake.org/) is a cross-platform build tool that generates makefiles and solutions for the compiler environment of your choice. On Windows you can download a [Windows Installer package](https://cmake.org/download/). On Linux it is usually available as a package, e.g., on Ubuntu, ``` sudo apt-get install cmake ``` Once cmake is installed, you can build and run the unit tests from the jsoncons directory, On Windows: ``` > mkdir build > cd build > cmake .. -DJSONCONS_BUILD_TESTS=On > cmake --build . > ctest -C Debug --output-on-failure ``` On UNIX: ``` $ mkdir build $ cd build $ cmake .. -DJSONCONS_BUILD_TESTS=On $ cmake --build . $ ctest --output-on-failure ``` ## Acknowledgements jsoncons uses the PVS-Studio static analyzer, provided free for open source projects. A big thanks to the comp.lang.c++ community for help with implementation details. The jsoncons platform dependent binary configuration draws on to the excellent MIT licensed [tinycbor](https://github.com/intel/tinycbor). Thanks to Milo Yip, author of [RapidJSON](http://rapidjson.org/), for raising the quality of JSON libraries across the board, by publishing [the benchmarks](https://github.com/miloyip/nativejson-benchmark), and contacting this project (among others) to share the results. The jsoncons implementation of the Grisu3 algorithm for printing floating-point numbers follows Florian Loitsch's MIT licensed [grisu3_59_56 implementation](http://florian.loitsch.com/publications), with minor modifications. The macro `JSONCONS_ALL_MEMBER_TRAITS` follows the approach taken by Martin York's [ThorsSerializer](https://github.com/Loki-Astari/ThorsSerializer) The jsoncons implementations of BSON decimal128 to and from string, and ObjectId to and from string, are based on the Apache 2 licensed [libbson](https://github.com/mongodb/mongo-c-driver/tree/master/src/libbson). Special thanks to our [contributors](https://github.com/danielaparker/jsoncons/blob/master/acknowledgements.md) jsoncons-1.3.2/Roadmap.md000066400000000000000000000005151477700171100152640ustar00rootroot00000000000000# Roadmap ### Soon Version 1.0.0 (we've been leading up to this since 2013.) ### Post 1.0.0 - Implement [Concise data definition language (CDDL)](https://tools.ietf.org/html/draft-ietf-cbor-cddl-08) for validating JSON and JSON-like binary formats - Support more error recovery and introduce optional `lenient_error_handler`. jsoncons-1.3.2/acknowledgements.md000066400000000000000000000117041477700171100172350ustar00rootroot00000000000000A big thanks to the following individuals for contributing: - Andrew Hutko (early code review) - [Marc Chevrier](https://github.com/MarkaPola) (contributed clang port, build files, json is and as methods, and make_array template implementation.) - [Pedro Larroy](https://github.com/larroy) and the developers of the clearskies_core project (contributed build system for posix systems, adding GCC to list of supported compilers, bug fixes, Android fix) - [Cory Fields](https://github.com/theuni) for fixing warnings about unused variables - [Vitaliy Gusev](https://github.com/gusev-vitaliy) (reported error in json object operator[size_t i]) - [Alex Merry](https://github.com/amerry) Reported errors with "typename" keyword experienced with gcc and provided workaround for gcc 4.8 regex issues. Fixed float128 feature macro names #273. - [Ignatov Serguei](https://github.com/sergign60) (reported issues experienced with gcc for 0.95 and 0.96 candidate and helped fix them) - [Milan Burda](https://github.com/miniak) for fix for clang build error - [Peter Tissen](https://github.com/Bigpet), for reporting and suggesting a fix for get(name,default_value) - [Tom Bass](https://github.com/tbass) for assistance with clang build errors - [Andrey Alifanov](https://github.com/AndreyAlifanov) and [Amit Naik](https://github.com/amitnaik1) for failing test cases for JSON Path - [Yuri Plaksyuk](https://github.com/yplaksyuk) for contributing an extension to JsonPath to allow filter expressions over a single object. - [Nikolay Amiantov](https://github.com/abbradar) for fixing compilation errors and warnings by GCC and Clang, adding read support for std::array and, most appreciated, adding Travis CI configuration. - [jakalx](https://github.com/jakalx) contributed fix for operator== throws when comparing a string against an empty object - [Alexander](https://github.com/rog13) for contributing fix to jsonpatch::diff - [Stefano Sinigardi](https://github.com/cenit) for contributing workaround for vs2017 platform issue - [xezon](https://github.com/danielaparker/jsoncons/pull/140) for proposing decode_csv and encode_csv functions, the ignore_empty_lines option, fixes to mismatched allocator types, and fixes and improvements in string_view code. Also for contributing a refactoring of the basic_json variant as a union. - Vojtech Fried for contributing patches to JSONCONS_DEFINE_LITERAL and to json::as_string to remove warnings - [Joshua Pritikin](https://github.com/jpritikin), for reporting gcc ubsan runtime warnings about load of misaligned addresses, and verifying fix - [Tobias Hermann](https://github.com/Dobiasd), for reporting issue with `UINT_MAX` not declared in `bigint.hpp`, and proposing fix. - [Cebtenzzre](https://github.com/Cebtenzzre), for finding and fixing an issue with conversions on a basic_json value leading to an infinite recursion when the value is a bignum, and for fixing undefined behavior in the bignum class. - [massimo morara](https://github.com/massimomorara) for reporting numerous issues - [Alexander B](https://github.com/bas524), for uncovering a bug in how json_parser validated UTF-8 strings. - [zhskyy](https://github.com/zhskyy), for contributing __FILE__ and __LINE__ macros removed from JSONCONS_ASSERT if not defined _DEBUG. - [soberich](https://github.com/soberich), for contributing the jsonpath sum and prod functions, and a proposal for aggregation functions that work outside a filter. - [patternoia](https://github.com/patternoia) for fixing the installation script to include copying the jsoncons_ext directory into the installation place - [mikewallis](https://github.com/mikewallis) for removing redundant macro continuation character in JSONCONS_TYPE_TRAITS - [KonstantinPlotnikov](https://github.com/KonstantinPlotnikov) for fixing GCC 9.2 warning: class jsoncons::json_exception has virtual functions and accessible non-virtual destructor - [patternoia](https://github.com/patternoia), [Twan Springeling](https://github.com/Hippid), [Leroy.H.Y](https://github.com/lhy0403) and [Rodrigo Broggi](https://github.com/rbroggi) for providing feedback and helpful suggestions regarding the `json_type_traits` convenience macros. - [dvzubarev](https://github.com/dvzubarev) for contributing suggestions for improving the `encode_traits` implementation. - [David Korczynski](https://github.com/DavidKorczynski) for integrating jsoncons into OSS-fuzz and contributing fuzzers - [Sebi](https://github.com/PapeCoding) for [\#243](https://github.com/danielaparker/jsoncons/issues/243) to fix BSON encoding error - [Oleh Derevenko](https://github.com/oleh-derevenko) for [\#244](https://github.com/danielaparker/jsoncons/issues/244) and [\#245](https://github.com/danielaparker/jsoncons/pull/248) to make jsoncons work on QNX Neutrino target. - [Laurent Stacul](https://github.com/stac47) Fixed compilation error with gcc 11 #276 - [wbangna](https://github.com/wbangna) Contributed [\#279](https://github.com/danielaparker/jsoncons/pull/279) jsoncons-1.3.2/cmake/000077500000000000000000000000001477700171100144365ustar00rootroot00000000000000jsoncons-1.3.2/cmake/Config.cmake000066400000000000000000000007101477700171100166430ustar00rootroot00000000000000# jsoncons cmake module # This module sets the following variables in your project:: # # jsoncons_FOUND - true if jsoncons found on the system # jsoncons_INCLUDE_DIRS - the directory containing jsoncons headers # jsoncons_LIBRARY - empty @PACKAGE_INIT@ if(NOT TARGET @PROJECT_NAME@) include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") get_target_property(@PROJECT_NAME@_INCLUDE_DIRS jsoncons INTERFACE_INCLUDE_DIRECTORIES) endif() jsoncons-1.3.2/doc/000077500000000000000000000000001477700171100141235ustar00rootroot00000000000000jsoncons-1.3.2/doc/Examples.md000066400000000000000000003055041477700171100162320ustar00rootroot00000000000000# Examples ### Parse and decode [Parse JSON from a string](#A1) [Parse JSON from a file](#A2) [Read JSON Lines](#A10) [Query JSON Lines in Parallel with JMESPath](#A13) [Parse JSON from an iterator range](#A11) [Parse numbers without loosing precision](#A8) [Validate JSON without incurring parse exceptions](#A3) [How to allow comments? How not to?](#A4) [Set a maximum nesting depth](#A5) [Prevent the alphabetic sort of the outputted JSON, retaining the original insertion order](#A6) [Parse a JSON text using a polymorphic_allocator (since 0.171.0)](#A12) [Decode a JSON text using stateful result and work allocators](#A9) ### Encode [Encode a json value to a string](#B1) [Encode Chinese characters](#B5) [Encode a json value to a stream](#B2) [Escape all non-ascii characters](#B3) [Replace the representation of NaN, Inf and -Inf when serializing. And when reading in again.](#B4) ### Stream [Write some JSON (push)](#I6) [Read some JSON (pull)](#I1) [Filter the event stream](#I2) [Pull nested objects into a basic_json](#I3) [Iterate over basic_json items](#I4) [Iterate over strongly typed items](#I5) ### Decode JSON to C++ data structures, encode C++ data structures to JSON [Serialize with the C++ member names of the class](#G2) [Serialize with provided names using the `_NAME_` macros](#G3) [Mapping to C++ data structures with and without defaults allowed](#G4) [Specialize json_type_traits explicitly](#G1) [Serialize non-mandatory std::optional values using the convenience macros](#G5) [An example with std::shared_ptr and std::unique_ptr](#G6) [Serialize a templated class with the `_TPL_` macros](#G7) [An example using JSONCONS_ENUM_TRAITS and JSONCONS_ALL_CTOR_GETTER_TRAITS](#G8) [Serialize a polymorphic type based on the presence of members](#G9) [Ensuring type selection is possible](#G10) [Decode to a polymorphic type based on a type marker (since 0.157.0)](#G14) [An example with std::variant](#G11) [Type selection and std::variant](#G12) [Decode to a std::variant based on a type marker (since 0.158.0)](#G15) [Convert JSON numbers to/from boost multiprecision numbers](#G13) ### Construct [Construct a json object](#C1) [Insert a value into a location after creating objects when missing object keys](#C3) [Construct a json array](#C2) [Construct a json byte string](#C6) [Construct a multidimensional json array](#C7) [Construct a json array that contains non-owning references to other json values (since 0.156.0)](#C8) ### Access [Use string_view to access the actual memory that's being used to hold a string](#E1) [Given a string in a json object that represents a decimal number, assign it to a double](#E2) [Retrieve a big integer that's been parsed as a string](#E3) [Look up a key, if found, return the value converted to type T, otherwise, return a default value of type T](#E4) [Retrieve a value in a hierarchy of JSON objects](#E5) [Retrieve a json value as a byte string](#E6) ### Iterate [Iterate over a json array](#D1) [Iterate over a json object](#D2) ### Modify [Insert a new value in an array at a specific position](#J1) [Merge two json objects](#J2) [Erase an object with a specified key from an array](#J3) [Iterating an array and erasing elements](#J4) [Iterating an object and erasing members](#J5) ### Flatten and unflatten [Flatten a json object with numberish keys to JSON Pointer/value pairs](#H1) [Flatten a json object to JSONPath/value pairs](#H2) ### Search and Replace [Search for and repace an object member key](#F1) [Search for and replace a value](#F2) [Update JSON in place](#F3) ### Parse and decode
#### Parse JSON from a string ``` std::string s = R"({"first":1,"second":2,"fourth":3,"fifth":4})"; json j = json::parse(s); ``` or ```cpp using namespace jsoncons::literals; json j = R"( { "StartDate" : "2017-03-01", "MaturityDate" : "2020-12-30" } )"_json; ``` See [basic_json::parse](ref/json/parse.md).
#### Parse JSON from a file ``` std::ifstream is("myfile.json"); json j = json::parse(is); ``` See [basic_json::parse](ref/json/parse.md).
#### Read JSON Lines This example is from [JSON Lines Examples](https://jsonlines.org/examples/). Data: ``` ["Name", "Session", "Score", "Completed"] ["Gilbert", "2013", 24, true] ["Alexa", "2013", 29, true] ["May", "2012B", 14, false] ["Deloise", "2012A", 19, true] ``` ```cpp std::ifstream is("path_to_data"); json_decoder decoder; json_stream_reader reader(is, decoder); while (!reader.eof()) { reader.read_next(); // until 1.0.0 //if (!reader.eof()) //{ // json j = decoder.get_result(); // std::cout << j << '\n'; //} // since 1.0.0 json j = decoder.get_result(); std::cout << j << '\n'; } ``` Output: ``` ["Name","Session","Score","Completed"] ["Gilbert","2013",24,true] ["Alexa","2013",29,true] ["May","2012B",14,false] ``` See [JSON Lines](https://jsonlines.org/).
#### Query JSON Lines in Parallel with JMESPath ``` cpp #include "jsoncons_ext/jmespath/jmespath.hpp" #include #include #include // microsoft PPL library int main(int argc, char* argv[]) { std::vector lines = {{ R"({"name": "Seattle", "state" : "WA"})", R"({ "name": "New York", "state" : "NY" })", R"({ "name": "Bellevue", "state" : "WA" })", R"({ "name": "Olympia", "state" : "WA" })" }}; auto expr = jsoncons::jmespath::make_expression( R"([@][?state=='WA'].name)"); concurrency::concurrent_vector result; auto f = [&](const std::string& line) { const auto j = jsoncons::json::parse(line); const auto r = expr.evaluate(j); if (!r.empty()) result.push_back(r.at(0).as()); }; std::for_each(std::execution::par, lines.begin(), lines.end(), f); for (const auto& s : result) { std::cout << s << "\n"; } } ``` Output: ``` Seattle Bellevue Olympia ```
#### Parse JSON from an iterator range ```cpp #include class MyIterator { const char* p_; public: using iterator_category = std::input_iterator_tag; using value_type = char; using difference_type = std::ptrdiff_t; using pointer = const char*; using reference = const char&; MyIterator(const char* p) : p_(p) { } reference operator*() const { return *p_; } pointer operator->() const { return p_; } MyIterator& operator++() { ++p_; return *this; } MyIterator operator++(int) { MyIterator temp(*this); ++*this; return temp; } bool operator!=(const MyIterator& rhs) const { return p_ != rhs.p_; } }; int main() { char source[] = {'[','\"', 'f','o','o','\"',',','\"', 'b','a','r','\"',']'}; MyIterator first(source); MyIterator last(source + sizeof(source)); json j = json::parse(first, last); std::cout << j << "\n\n"; } ``` Output: ```json ["foo","bar"] ``` See [basic_json::parse](ref/json/parse.md).
#### Parse numbers without loosing precision By default, jsoncons parses a number with an exponent or fractional part into a double precision floating point number. If you wish, you can keep the number as a string with semantic tagging `bigdec`, using the `lossless_number` option. You can then put it into a `float`, `double`, a boost multiprecision number, or whatever other type you want. ```cpp #include int main() { std::string s = R"( { "a" : 12.00, "b" : 1.23456789012345678901234567890 } )"; // Default json j = json::parse(s); std::cout.precision(15); // Access as string std::cout << "(1) a: " << j["a"].as() << ", b: " << j["b"].as() << "\n"; // Access as double std::cout << "(2) a: " << j["a"].as() << ", b: " << j["b"].as() << "\n\n"; // Using lossless_number option auto options = json_options{} .lossless_number(true); json j2 = json::parse(s, options); // Access as string std::cout << "(3) a: " << j2["a"].as() << ", b: " << j2["b"].as() << "\n"; // Access as double std::cout << "(4) a: " << j2["a"].as() << ", b: " << j2["b"].as() << "\n\n"; } ``` Output: ``` (1) a: 12.0, b: 1.2345678901234567 (2) a: 12, b: 1.23456789012346 (3) a: 12.00, b: 1.23456789012345678901234567890 (4) a: 12, b: 1.23456789012346 ```
#### Validate JSON without incurring parse exceptions ```cpp std::string s = R"( { "StartDate" : "2017-03-01", "MaturityDate" "2020-12-30" } )"; //json_reader reader(s); // (until 0.164.0) json_string_reader reader(s); // (since 0.164.0) // or, // std::stringstream is(s); // json_reader reader(is); // (until 0.164.0) // json_stream_reader reader(is); // (since 0.164.0) std::error_code ec; reader.read(ec); if (ec) { std::cout << ec.message() << " on line " << reader.line() << " and column " << reader.column() << '\n'; } ``` Output: ``` Expected name separator ':' on line 4 and column 20 ```
#### How to allow comments? How not to? jsoncons, by default, accepts and ignores C-style comments ```cpp std::string s = R"( { // Single line comments /* Multi line comments */ } )"; // Default json j = json::parse(s); std::cout << "(1) " << j << '\n'; // Strict try { // until 0.170.0 auto j1 = jsoncons::json::parse(s, jsoncons::strict_json_parsing()); // since 0.171.0 auto options = json_options{} .err_handler(jsoncons::strict_json_parsing()); auto j2 = jsoncons::json::parse(s, options); // since 1.3.0 auto options = json_options{} .allow_comments(false); auto j3 = jsoncons::json::parse(s, options); } catch (const ser_error& e) { std::cout << "(2) " << e.what() << '\n'; } ``` Output: ``` (1) {} (2) Illegal comment at line 3 and column 10 ```
#### Set a maximum nesting depth Like this, ```cpp std::string s = "[[[[[[[[[[[[[[[[[[[[[\"Too deep\"]]]]]]]]]]]]]]]]]]]]]"; try { auto options = json_options{} .max_nesting_depth(20); json j = json::parse(s, options); } catch (const ser_error& e) { std::cout << e.what() << '\n'; } ``` Output: ``` Maximum JSON depth exceeded at line 1 and column 21 ```
#### Prevent the alphabetic sort of the outputted JSON, retaining the original insertion order Use `ojson` instead of `json` (or `wojson` instead of `wjson`) to retain the original insertion order. ```cpp ojson j = ojson::parse(R"( { "street_number" : "100", "street_name" : "Queen St W", "city" : "Toronto", "country" : "Canada" } )"); std::cout << "(1)\n" << pretty_print(j) << '\n'; // Insert "postal_code" at end j.insert_or_assign("postal_code", "M5H 2N2"); std::cout << "(2)\n" << pretty_print(j) << '\n'; // Insert "province" before "country" auto it = j.find("country"); j.insert_or_assign(it,"province","Ontario"); std::cout << "(3)\n" << pretty_print(j) << '\n'; ``` Output: ``` (1) { "street_number": "100", "street_name": "Queen St W", "city": "Toronto", "country": "Canada" } (2) { "street_number": "100", "street_name": "Queen St W", "city": "Toronto", "country": "Canada", "postal_code": "M5H 2N2" } (3) { "street_number": "100", "street_name": "Queen St W", "city": "Toronto", "province": "Ontario", "country": "Canada", "postal_code": "M5H 2N2" } ```
### Parse a JSON text using a polymorphic_allocator (since 0.171.0) ```cpp using pmr_json = jsoncons::pmr::json; char buffer[1024] = {}; // a small buffer on the stack std::pmr::monotonic_buffer_resource pool{std::data(buffer), std::size(buffer)}; std::pmr::polymorphic_allocator alloc(&pool); std::string json_text = R"( { "street_number" : "100", "street_name" : "Queen St W", "city" : "Toronto", "country" : "Canada" } )"; auto doc = pmr_json::parse(combine_allocators(alloc), json_text, json_options{}); std::cout << pretty_print(doc) << "\n\n"; ```
### Decode a JSON text using stateful result and work allocators ```cpp // Given allocator my_alloc with a single-argument constructor my_alloc(int), // use my_alloc(1) to allocate basic_json memory, my_alloc(2) to allocate // working memory used by json_decoder, and my_alloc(3) to allocate // working memory used by basic_json_reader. using my_json = basic_json; // until 0.171.0 using my_json = basic_json>; // since 0.171.0 std::ifstream is("book_catalog.json"); json_decoder decoder(my_alloc(1),my_alloc(2)); basic_json_reader,my_alloc> reader(is, decoder, my_alloc(3)); reader.read(); my_json j = decoder.get_result(); std::cout << pretty_print(j) << "\n"; ``` ### Encode
#### Encode a json value to a string ``` std::string s; j.dump(s); // compressed j.dump(s, indenting::indent); // pretty print ```
#### Encode Chinese characters For all versions of jsoncons: ``` jsoncons::json j; std::string s = (const char*)u8"你好"; j.try_emplace("hello", s); assert(j["hello"].as() == s); std::string json_string; j.dump(json_string); ``` Since 0.171.0, and assuming C++ 20: ``` jsoncons::json j; std::u8string s = u8"你好"; j.try_emplace("hello", s); assert(j["hello"].as() == s); std::string json_string; j.dump(json_string); ```
#### Encode a json value to a stream ``` j.dump(std::cout); // compressed j.dump(std::cout, indenting::indent); // pretty print ``` or ``` std::cout << j << '\n'; // compressed std::cout << pretty_print(j) << '\n'; // pretty print ```
#### Escape all non-ascii characters ``` auto options = json_options{} .escape_all_non_ascii(true); j.dump(std::cout, options); // compact j.dump(std::cout, options, indenting::indent); // pretty print ``` or ``` std::cout << print(j, options) << '\n'; // compressed std::cout << pretty_print(j, options) << '\n'; // pretty print ```
#### Replace the representation of NaN, Inf and -Inf when serializing. And when reading in again. Set the serializing options for `nan` and `inf` to distinct string values. ```cpp json j; j["field1"] = std::sqrt(-1.0); j["field2"] = 1.79e308 * 1000; j["field3"] = -1.79e308 * 1000; auto options = json_options{} .nan_to_str("NaN") .inf_to_str("Inf"); std::ostringstream os; os << pretty_print(j, options); std::cout << "(1)\n" << os.str() << '\n'; json j2 = json::parse(os.str(),options); std::cout << "\n(2) " << j2["field1"].as() << '\n'; std::cout << "(3) " << j2["field2"].as() << '\n'; std::cout << "(4) " << j2["field3"].as() << '\n'; std::cout << "\n(5)\n" << pretty_print(j2,options) << '\n'; ``` Output: ```json (1) { "field1": "NaN", "field2": "Inf", "field3": "-Inf" } (2) nan (3) inf (4) -inf (5) { "field1": "NaN", "field2": "Inf", "field3": "-Inf" } ``` ### Stream
#### Write some JSON (push) ```cpp #include #include #include #include int main() { std::ofstream os("./output/book_catalog.json", std::ios_base::out | std::ios_base::trunc); assert(os); compact_json_stream_encoder encoder(os); // no indent encoder.begin_array(); encoder.begin_object(); encoder.key("author"); encoder.string_value("Haruki Murakami"); encoder.key("title"); encoder.string_value("Hard-Boiled Wonderland and the End of the World"); encoder.key("price"); encoder.double_value(18.9); encoder.end_object(); encoder.begin_object(); encoder.key("author"); encoder.string_value("Graham Greene"); encoder.key("title"); encoder.string_value("The Comedians"); encoder.key("price"); encoder.double_value(15.74); encoder.end_object(); encoder.end_array(); encoder.flush(); os.close(); // Read the JSON and write it prettified to std::cout json_stream_encoder writer(std::cout); // indent std::ifstream is("./output/book_catalog.json"); assert(is); //json_reader reader(is, writer); // (until 0.164.0) json_stream_reader reader(is, writer); // (since 0.164.0) reader.read(); std::cout << "\n\n"; } ``` Output: ``` [ { "author": "Haruki Murakami", "title": "Hard-Boiled Wonderland and the End of the World", "price": 18.9 }, { "author": "Graham Greene", "title": "The Comedians", "price": 15.74 } ] ```
#### Read some JSON (pull) A typical pull parsing application will repeatedly process the `current()` event and call `next()` to advance to the next event, until `done()` returns `true`. ```cpp #include #include int main() { std::ifstream is("./output/book_catalog.json"); json_stream_cursor cursor(is); for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::end_array: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::begin_object: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::end_object: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::key: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::string_value: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::null_value: std::cout << event.event_type() << "\n"; break; case staj_event_type::bool_value: std::cout << event.event_type() << ": " << std::boolalpha << event.get() << "\n"; break; case staj_event_type::int64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::double_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; default: std::cout << "Unhandled event type: " << event.event_type() << " " << "\n"; break; } } } ``` Output: ``` begin_array begin_object key: author string_value: Haruki Murakami key: title string_value: Hard-Boiled Wonderland and the End of the World key: price double_value: 18.9 end_object begin_object key: author string_value: Graham Greene key: title string_value: The Comedians key: price double_value: 15.74 end_object end_array ```
#### Filter the event stream You can apply a filter to a cursor using the pipe syntax (e.g., `cursor | filter1 | filter2 | ...`) ```cpp #include #include // Filter out all events except names of authors int main() { bool author_next = false; auto filter = [&](const staj_event& event, const ser_context&) -> bool { if (event.event_type() == staj_event_type::key && event.get() == "author") { author_next = true; return false; } if (author_next) { author_next = false; return true; } return false; }; std::ifstream is("./output/book_catalog.json"); json_stream_cursor cursor(is); auto filtered_c = cursor | filter; for (; !filtered_c.done(); filtered_c.next()) { const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::string_value: std::cout << event.get() << "\n"; break; default: std::cout << "Unhandled event type: " << event.event_type() << " " << "\n"; break; } } } ``` Output: ``` Haruki Murakami Graham Greene ```
#### Pull nested objects into a basic_json When positioned on a `begin_object` event, the `read_to` function can pull a complete object representing the events from `begin_object` to `end_object`, and when positioned on a `begin_array` event, a complete array representing the events from `begin_array` ro `end_array`. ```cpp #include // json_decoder and json #include int main() { std::ifstream is("./output/book_catalog.json"); json_stream_cursor cursor(is); json_decoder decoder; for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: { std::cout << event.event_type() << " " << "\n"; break; } case staj_event_type::end_array: { std::cout << event.event_type() << " " << "\n"; break; } case staj_event_type::begin_object: { std::cout << event.event_type() << " " << "\n"; cursor.read_to(decoder); json j = decoder.get_result(); std::cout << pretty_print(j) << "\n"; break; } default: { std::cout << "Unhandled event type: " << event.event_type() << " " << "\n"; break; } } } } ``` Output: ``` begin_array begin_object { "author": "Haruki Murakami", "price": 18.9, "title": "Hard-Boiled Wonderland and the End of the World" } begin_object { "author": "Graham Greene", "price": 15.74, "title": "The Comedians" } end_array ``` See [basic_json_cursor](ref/basic_json_cursor.md)
#### Iterate over basic_json items ```cpp #include #include int main() { std::ifstream is("./output/book_catalog.json"); json_stream_cursor cursor(is); auto view = staj_array(cursor); for (const auto& j : view) { std::cout << pretty_print(j) << "\n"; } } ``` Output: ``` { "author": "Haruki Murakami", "price": 18.9, "title": "Hard-Boiled Wonderland and the End of the World" } { "author": "Graham Greene", "price": 15.74, "title": "The Comedians" } ``` See [staj_array_iterator](ref/staj_array_iterator.md)
#### Iterate over strongly typed items ```cpp #include #include namespace ns { struct book { std::string author; std::string title; double price; }; } // namespace ns JSONCONS_ALL_MEMBER_TRAITS(ns::book,author,title,price) int main() { std::ifstream is("./output/book_catalog.json"); json_stream_cursor cursor(is); auto view = staj_array(cursor); for (const auto& book : view) { std::cout << book.author << ", " << book.title << "\n"; } } ``` Output: ``` Haruki Murakami, Hard-Boiled Wonderland and the End of the World Graham Greene, The Comedians ``` See [staj_array_iterator](ref/staj_array_iterator.md)
### Decode JSON to C++ data structures, encode C++ data structures to JSON
#### Serialize with the C++ member names of the class ```cpp #include namespace ns { enum class BookCategory {fiction,biography}; inline std::ostream& operator<<(std::ostream& os, const BookCategory& category) { switch (category) { case BookCategory::fiction: os << "fiction, "; break; case BookCategory::biography: os << "biography, "; break; } return os; } // #1 Class with public member data and default constructor struct Book1 { BookCategory category; std::string author; std::string title; double price; }; // #2 Class with private member data and default constructor class Book2 { BookCategory category; std::string author; std::string title; double price; Book2() = default; JSONCONS_TYPE_TRAITS_FRIEND public: BookCategory get_category() const {return category;} const std::string& get_author() const {return author;} const std::string& get_title() const{return title;} double get_price() const{return price;} }; // #3 Class with getters and initializing constructor class Book3 { BookCategory category_; std::string author_; std::string title_; double price_; public: Book3(BookCategory category, const std::string& author, const std::string& title, double price) : category_(category), author_(author), title_(title), price_(price) { } BookCategory category() const {return category_;} const std::string& author() const{return author_;} const std::string& title() const{return title_;} double price() const{return price_;} }; // #4 Class with getters and setters class Book4 { BookCategory category_; std::string author_; std::string title_; double price_; public: Book4() : price_(0) { } Book4(BookCategory category, const std::string& author, const std::string& title, double price) : category_(category), author_(author), title_(title), price_(price) { } BookCategory get_category() const { return category_; } void set_category(BookCategory value) { category_ = value; } const std::string& get_author() const { return author_; } void set_author(const std::string& value) { author_ = value; } const std::string& get_title() const { return title_; } void set_title(const std::string& value) { title_ = value; } double get_price() const { return price_; } void set_price(double value) { price_ = value; } }; } // namespace ns // Declare the traits at global scope JSONCONS_ENUM_TRAITS(ns::BookCategory,fiction,biography) JSONCONS_ALL_MEMBER_TRAITS(ns::Book1,category,author,title,price) JSONCONS_ALL_MEMBER_TRAITS(ns::Book2,category,author,title,price) JSONCONS_ALL_CTOR_GETTER_TRAITS(ns::Book3,category,author,title,price) JSONCONS_ALL_GETTER_SETTER_TRAITS(ns::Book4,get_,set_,category,author,title,price) using namespace jsoncons; // for convenience int main() { const std::string input = R"( [ { "category" : "fiction", "author" : "Haruki Murakami", "title" : "Kafka on the Shore", "price" : 25.17 }, { "category" : "biography", "author" : "Robert A. Caro", "title" : "The Path to Power: The Years of Lyndon Johnson I", "price" : 16.99 } ] )"; std::cout << "(1)\n\n"; auto books1 = decode_json>(input); for (const auto& item : books1) { std::cout << item.category << ", " << item.author << ", " << item.title << ", " << item.price << "\n"; } std::cout << "\n"; encode_json(books1, std::cout, indenting::indent); std::cout << "\n\n"; std::cout << "(2)\n\n"; auto books2 = decode_json>(input); for (const auto& item : books2) { std::cout << item.get_category() << ", " << item.get_author() << ", " << item.get_title() << ", " << item.get_price() << "\n"; } std::cout << "\n"; encode_json(books2, std::cout, indenting::indent); std::cout << "\n\n"; std::cout << "(3)\n\n"; auto books3 = decode_json>(input); for (const auto& item : books3) { std::cout << item.category() << ", " << item.author() << ", " << item.title() << ", " << item.price() << "\n"; } std::cout << "\n"; encode_json(books3, std::cout, indenting::indent); std::cout << "\n\n"; std::cout << "(4)\n\n"; auto books4 = decode_json>(input); for (const auto& item : books4) { std::cout << item.get_category() << ", " << item.get_author() << ", " << item.get_title() << ", " << item.get_price() << "\n"; } std::cout << "\n"; encode_json(books4, std::cout, indenting::indent); std::cout << "\n\n"; } ``` Output: ``` (1) fiction, Haruki Murakami, Kafka on the Shore, 25.170000 biography, Robert A. Caro, The Path to Power: The Years of Lyndon Johnson I, 16.990000 [ { "author": "Haruki Murakami", "category": "fiction", "price": 25.17, "title": "Kafka on the Shore" }, { "author": "Robert A. Caro", "category": "biography", "price": 16.99, "title": "The Path to Power: The Years of Lyndon Johnson I" } ] ``` The output for (2), (3) and (4) is the same.
#### Serialize with provided names using the `_NAME_` macros ```cpp #include namespace ns { enum class BookCategory {fiction,biography}; inline std::ostream& operator<<(std::ostream& os, const BookCategory& category) { switch (category) { case BookCategory::fiction: os << "fiction, "; break; case BookCategory::biography: os << "biography, "; break; } return os; } // #1 Class with public member data and default constructor struct Book1 { BookCategory category; std::string author; std::string title; double price; }; // #2 Class with private member data and default constructor class Book2 { BookCategory category_; std::string author_; std::string title_; double price_; Book2() = default; JSONCONS_TYPE_TRAITS_FRIEND public: BookCategory category() const {return category_;} const std::string& author() const {return author_;} const std::string& title() const{return title_;} double price() const{return price_;} }; // #3 Class with getters and initializing constructor class Book3 { BookCategory category_; std::string author_; std::string title_; double price_; public: Book3(BookCategory category, const std::string& author, const std::string& title, double price) : category_(category), author_(author), title_(title), price_(price) { } BookCategory category() const {return category_;} const std::string& author() const{return author_;} const std::string& title() const{return title_;} double price() const{return price_;} }; // #4 Class with getters, setters and default constructor class Book4 { BookCategory category_; std::string author_; std::string title_; double price_; public: BookCategory getCategory() const {return category_;} void setCategory(const BookCategory& value) {category_ = value;} const std::string& getAuthor() const {return author_;} void setAuthor(const std::string& value) {author_ = value;} const std::string& getTitle() const {return title_;} void setTitle(const std::string& value) {title_ = value;} double getPrice() const {return price_;} void setPrice(double value) {price_ = value;} }; } // namespace ns // Declare the traits at global scope JSONCONS_ENUM_NAME_TRAITS(ns::BookCategory,(fiction,"Fiction"),(biography,"Biography")) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::Book1,(category,"Category"),(author,"Author"), (title,"Title"),(price,"Price")) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::Book2,(category_,"Category"),(author_,"Author"), (title_,"Title"),(price_,"Price")) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Book3,(category,"Category"),(author,"Author"), (title,"Title"),(price,"Price")) JSONCONS_ALL_GETTER_SETTER_NAME_TRAITS(ns::Book4,(getCategory,setCategory,"Category"), (getAuthor,setAuthor,"Author"), (getTitle,setTitle,"Title"), (getPrice,setPrice,"Price")) using namespace jsoncons; // for convenience int main() { const std::string input = R"( [ { "Category" : "Fiction", "Author" : "Haruki Murakami", "Title" : "Kafka on the Shore", "Price" : 25.17 }, { "Category" : "Biography", "Author" : "Robert A. Caro", "Title" : "The Path to Power: The Years of Lyndon Johnson I", "Price" : 16.99 } ] )"; std::cout << "(1)\n\n"; auto books1 = decode_json>(input); for (const auto& item : books1) { std::cout << item.category << ", " << item.author << ", " << item.title << ", " << item.price << "\n"; } std::cout << "\n"; encode_json(books1, std::cout, indenting::indent); std::cout << "\n\n"; std::cout << "(2)\n\n"; auto books2 = decode_json>(input); for (const auto& item : books2) { std::cout << item.category() << ", " << item.author() << ", " << item.title() << ", " << item.price() << "\n"; } std::cout << "\n"; encode_json(books2, std::cout, indenting::indent); std::cout << "\n\n"; std::cout << "(3)\n\n"; auto books3 = decode_json>(input); for (const auto& item : books3) { std::cout << item.category() << ", " << item.author() << ", " << item.title() << ", " << item.price() << "\n"; } std::cout << "\n"; encode_json(books3, std::cout, indenting::indent); std::cout << "\n\n"; std::cout << "(4)\n\n"; auto books4 = decode_json>(input); for (const auto& item : books4) { std::cout << item.getCategory() << ", " << item.getAuthor() << ", " << item.getTitle() << ", " << item.getPrice() << "\n"; } std::cout << "\n"; encode_json(books4, std::cout, indenting::indent); std::cout << "\n\n"; } ``` Output: ``` (1) fiction, Haruki Murakami, Kafka on the Shore, 25.170000 biography, Robert A. Caro, The Path to Power: The Years of Lyndon Johnson I, 16.990000 [ { "Author": "Haruki Murakami", "Category": "Fiction", "Price": 25.17, "Title": "Kafka on the Shore" }, { "Author": "Robert A. Caro", "Category": "Biography", "Price": 16.99, "Title": "The Path to Power: The Years of Lyndon Johnson I" } ] ``` The output for (2), (3) and (4) is the same.
#### Mapping to C++ data structures with and without defaults allowed `JSONCONS_N_MEMBER_TRAITS` and `JSONCONS_ALL_MEMBER_TRAITS` both generate the code to specialize `json_type_traits` from member data. The difference is that `JSONCONS_N_MEMBER_TRAITS` does not require all member names to be present in the JSON data, while `JSONCONS_ALL_MEMBER_TRAITS` does. More generaly, the qualifier _N_ in the macro name indicates that only a specified number of members must be present in the JSON. ```cpp #include #include #include #include namespace ns { class Person { public: Person(const std::string& name, const std::string& surname, const std::string& ssn, unsigned int age) : name(name), surname(surname), ssn(ssn), age(age) { } private: // Make json_type_traits specializations friends to give accesses to private members JSONCONS_TYPE_TRAITS_FRIEND Person() : age(0) {} std::string name; std::string surname; std::string ssn; unsigned int age; }; } // namespace ns // Declare the traits. Specify which data members need to be serialized, and how many are mandatory. JSONCONS_N_MEMBER_TRAITS(ns::Person, 2, name, surname, ssn, age) int main() { try { // Incomplete JSON data: field ssn missing std::string data = R"({"name":"Rod","surname":"Bro","age":30})"; auto person = jsoncons::decode_json(data); std::string s; jsoncons::encode_json(person, s, indenting::indent); std::cout << s << "\n"; } catch (const std::exception& e) { std::cout << e.what() << ""; } } ``` Output: ``` { "age": 30, "name": "Rod", "ssn": "", "surname": "Bro" } ``` If all members of the JSON data must be present, use ``` JSONCONS_ALL_MEMBER_TRAITS(ns::Person, name, surname, ssn, age) ``` instead. This will cause a [jsoncons::conv_error](ref/conv_error.md) to be thrown with the message ``` Key not found: 'ssn' ```
#### Specialize json_type_traits explicitly jsoncons supports conversion between JSON text and C++ data structures. The functions [decode_json](ref/decode_json.md) and [encode_json](ref/encode_json.md) convert JSON formatted strings or streams to C++ data structures and back. Decode and encode work for all C++ classes that have [json_type_traits](ref/json_type_traits.md) defined. jsoncons already supports many types in the standard library, and your own types will be supported too if you specialize `json_type_traits` in the `jsoncons` namespace. ```cpp #include #include #include #include namespace ns { struct book { std::string author; std::string title; double price; }; } // namespace ns namespace jsoncons { template struct json_type_traits { using allocator_type = Json::allocator_type; static bool is(const Json& j) noexcept { return j.is_object() && j.contains("author") && j.contains("title") && j.contains("price"); } static ns::book as(const Json& j) { ns::book val; val.author = j.at("author").template as(); val.title = j.at("title").template as(); val.price = j.at("price").template as(); return val; } static Json to_json(const ns::book& val, allocator_type allocator=allocator_type()) { Json j(allocator); j.try_emplace("author", val.author); j.try_emplace("title", val.title); j.try_emplace("price", val.price); return j; } }; } // namespace jsoncons ``` To save typing and enhance readability, the jsoncons library defines macros, so you could also write ```cpp JSONCONS_ALL_MEMBER_TRAITS(ns::book, author, title, price) ``` which expands to the code above. ```cpp using namespace jsoncons; // for convenience int main() { const std::string s = R"( [ { "author" : "Haruki Murakami", "title" : "Kafka on the Shore", "price" : 25.17 }, { "author" : "Charles Bukowski", "title" : "Pulp", "price" : 22.48 } ] )"; std::vector book_list = decode_json>(s); std::cout << "(1)\n"; for (const auto& item : book_list) { std::cout << item.author << ", " << item.title << ", " << item.price << "\n"; } std::cout << "\n(2)\n"; encode_json(book_list, std::cout, indenting::indent); std::cout << "\n\n"; } ``` Output: ``` (1) Haruki Murakami, Kafka on the Shore, 25.17 Charles Bukowski, Pulp, 22.48 (2) [ { "author": "Haruki Murakami", "price": 25.17, "title": "Kafka on the Shore" }, { "author": "Charles Bukowski", "price": 22.48, "title": "Pulp" } ] ```
#### Serialize non-mandatory std::optional values using the convenience macros The jsoncons library includes a [json_type_traits](ref/json_type_traits.md) specialization for `jsoncons::optional` if `T` is also specialized. `jsoncons::optional` is aliased to [std::optional](https://en.cppreference.com/w/cpp/utility/optional) if jsoncons detects the presence of C++17, or if `JSONCONS_HAS_STD_OPTIONAL` is defined. An empty `jsoncons::optional` value correspond to JSON null. This example assumes C++17 language support (otherwise substitute `jsoncons::optional`.) Macro names include qualifiers `_ALL_` or `_N_` to indicate that the generated traits require all members be present in the JSON, or a specified number be present. For non-mandatory members, the generated traits `to_json` function will exclude altogether empty values for `std::optional`. ```cpp #include #include namespace ns { class MetaDataReplyTest { public: MetaDataReplyTest() : description() { } const std::string& GetStatus() const { return status; } const std::string& GetPayload() const { return payload; } const std::optional& GetDescription() const { return description; } private: JSONCONS_TYPE_TRAITS_FRIEND std::string status; std::string payload; std::optional description; }; } JSONCONS_N_MEMBER_TRAITS(ns::MetaDataReplyTest, 2, status, payload, description) using namespace jsoncons; int main() { std::string input1 = R"({ "status": "OK", "payload": "Modified", "description": "TEST" })"; std::string input2 = R"({ "status": "OK", "payload": "Modified" })"; auto val1 = decode_json(input1); assert(val1.GetStatus() == "OK"); assert(val1.GetPayload() == "Modified"); assert(val1.GetDescription()); assert(val1.GetDescription() == "TEST"); auto val2 = decode_json(input2); assert(val2.GetStatus() == "OK"); assert(val2.GetPayload() == "Modified"); assert(!val2.GetDescription()); std::string output1; std::string output2; encode_json(val2, output2, indenting::indent); encode_json(val1, output1, indenting::indent); std::cout << "(1)\n"; std::cout << output1 << "\n\n"; std::cout << "(2)\n"; std::cout << output2 << "\n\n"; } ``` Output: ``` (1) { "description": "TEST", "payload": "Modified", "status": "OK" } (2) { "payload": "Modified", "status": "OK" } ```
#### An example with std::shared_ptr and std::unique_ptr The jsoncons library includes [json_type_traits](ref/json_type_traits.md) specializations for `std::shared_ptr` and `std::unique_ptr` if `T` is not a [polymorphic class](https://en.cppreference.com/w/cpp/language/object#Polymorphic_objects), i.e., does not have any virtual functions, and if `T` is also specialized. Empty `std::shared_ptr` and `std::unique_ptr` values correspond to JSON null. In addition, users can implement `json_type_traits` for `std::shared_ptr` and `std::unique_ptr` with polymorphic classes using the convenience macro `JSONCONS_POLYMORPHIC_TRAITS`, or by specializing `json_type_traits` explicitly. The convenience macros whose names include the qualifier `_N_` do not require all members to be present in the JSON. For these, the generated traits `to_json` function will exclude altogether empty values for `std::shared_ptr` and `std::unique_ptr`. ```cpp namespace ns { struct smart_pointer_test { std::shared_ptr field1; std::unique_ptr field2; std::shared_ptr field3; std::unique_ptr field4; std::shared_ptr field5; std::unique_ptr field6; std::shared_ptr field7; std::unique_ptr field8; }; } // namespace ns // Declare the traits, first 4 members mandatory, last 4 non-mandatory JSONCONS_N_MEMBER_TRAITS(ns::smart_pointer_test,4,field1,field2,field3,field4,field5,field6,field7,field8) int main() { ns::smart_pointer_test val; val.field1 = std::make_shared("Field 1"); val.field2 = jsoncons::make_unique("Field 2"); val.field3 = std::shared_ptr(nullptr); val.field4 = std::unique_ptr(nullptr); val.field5 = std::make_shared("Field 5"); val.field6 = jsoncons::make_unique("Field 6"); val.field7 = std::shared_ptr(nullptr); val.field8 = std::unique_ptr(nullptr); std::string buf; encode_json(val, buf, indenting::indent); std::cout << buf << "\n"; auto other = decode_json(buf); assert(*other.field1 == *val.field1); assert(*other.field2 == *val.field2); assert(!other.field3); assert(!other.field4); assert(*other.field5 == *val.field5); assert(*other.field6 == *val.field6); assert(!other.field7); assert(!other.field8); } ``` Output: ``` { "field1": "Field 1", "field2": "Field 2", "field3": null, "field4": null, "field5": "Field 5", "field6": "Field 6" } ```
#### Serialize a templated class with the `_TPL_` macros ```cpp #include #include namespace ns { template struct TemplatedStruct { T1 aT1; T2 aT2; friend bool operator==(const TemplatedStruct& lhs, const TemplatedStruct& rhs) { return lhs.aT1 == rhs.aT1 && lhs.aT2 == rhs.aT2; } friend bool operator!=(const TemplatedStruct& lhs, const TemplatedStruct& rhs) { return !(lhs == rhs); } }; } // namespace ns // Declare the traits. Specify the number of template parameters and which data members need to be serialized. JSONCONS_TPL_ALL_MEMBER_TRAITS(2,ns::TemplatedStruct,aT1,aT2) using namespace jsoncons; // for convenience int main() { using value_type = ns::TemplatedStruct; value_type val{1, L"sss"}; std::wstring s; encode_json(val, s); auto val2 = decode_json(s); assert(val2 == val); } ```
#### An example using JSONCONS_ENUM_TRAITS and JSONCONS_ALL_CTOR_GETTER_TRAITS This example makes use of the convenience macros `JSONCONS_ENUM_TRAITS` and `JSONCONS_ALL_CTOR_GETTER_TRAITS` to specialize the [json_type_traits](ref/json_type_traits.md) for the enum type `ns::hiking_experience` and the classes `ns::hiking_reputon` and `ns::hiking_reputation`. The macro `JSONCONS_ENUM_TRAITS` generates the code from the enum values, and the macro `JSONCONS_ALL_CTOR_GETTER_TRAITS` generates the code from the get functions and a constructor. These macro declarations must be placed outside any namespace blocks. ```cpp namespace ns { enum class hiking_experience {beginner,intermediate,advanced}; class hiking_reputon { std::string rater_; hiking_experience assertion_; std::string rated_; double rating_; std::optional generated_; // assumes C++17, if not use jsoncons::optional std::optional expires_; public: hiking_reputon(const std::string& rater, hiking_experience assertion, const std::string& rated, double rating, const std::optional& generated = std::optional(), const std::optional& expires = std::optional()) : rater_(rater), assertion_(assertion), rated_(rated), rating_(rating), generated_(generated), expires_(expires) { } const std::string& rater() const {return rater_;} hiking_experience assertion() const {return assertion_;} const std::string& rated() const {return rated_;} double rating() const {return rating_;} std::optional generated() const {return generated_;} std::optional expires() const {return expires_;} friend bool operator==(const hiking_reputon& lhs, const hiking_reputon& rhs) { return lhs.rater_ == rhs.rater_ && lhs.assertion_ == rhs.assertion_ && lhs.rated_ == rhs.rated_ && lhs.rating_ == rhs.rating_ && lhs.confidence_ == rhs.confidence_ && lhs.expires_ == rhs.expires_; } friend bool operator!=(const hiking_reputon& lhs, const hiking_reputon& rhs) { return !(lhs == rhs); }; }; class hiking_reputation { std::string application_; std::vector reputons_; public: hiking_reputation(const std::string& application, const std::vector& reputons) : application_(application), reputons_(reputons) {} const std::string& application() const { return application_;} const std::vector& reputons() const { return reputons_;} }; } // namespace ns // Declare the traits. Specify which data members need to be serialized. JSONCONS_ENUM_TRAITS(ns::hiking_experience, beginner, intermediate, advanced) // First four members listed are mandatory, generated and expires are optional JSONCONS_N_CTOR_GETTER_TRAITS(ns::hiking_reputon, 4, rater, assertion, rated, rating, generated, expires) // All members are mandatory JSONCONS_ALL_CTOR_GETTER_TRAITS(ns::hiking_reputation, application, reputons) int main() { // Decode the string of data into a c++ structure ns::hiking_reputation v = decode_json(data); // Iterate over reputons array value std::cout << "(1)\n"; for (const auto& item : v.reputons()) { std::cout << item.rated() << ", " << item.rating(); if (item.generated()) { std::cout << ", " << (*item.generated()).count(); } std::cout << "\n"; } // Encode the c++ structure into a string std::string s; encode_json(v, s, indenting::indent); std::cout << "(2)\n"; std::cout << s << "\n"; } ``` Output: ``` (1) Marilyn C, 0.9, 1514862245 (2) { "application": "hiking", "reputons": [ { "assertion": "advanced", "generated": 1514862245, "rated": "Marilyn C", "rater": "HikingAsylum", "rating": 0.9 } ] } ```
#### Serialize a polymorphic type based on the presence of members This example uses the convenience macro `JSONCONS_N_CTOR_GETTER_TRAITS` to generate the [json_type_traits](ref/json_type_traits.md) boilerplate for the `HourlyEmployee` and `CommissionedEmployee` derived classes, and `JSONCONS_POLYMORPHIC_TRAITS` to generate the `json_type_traits` boilerplate for `std::shared_ptr` and `std::unique_ptr`. The type selection strategy is based on the presence of mandatory members, in particular, to the `firstName`, `lastName`, and `wage` members of an `HourlyEmployee`, and to the `firstName`, `lastName`, `baseSalary`, and `commission` members of a `CommissionedEmployee`. Non-mandatory members are not considered for the purpose of type selection. ```cpp #include #include #include #include using namespace jsoncons; namespace ns { class Employee { std::string firstName_; std::string lastName_; public: Employee(const std::string& firstName, const std::string& lastName) : firstName_(firstName), lastName_(lastName) { } virtual ~Employee() noexcept = default; virtual double calculatePay() const = 0; const std::string& firstName() const {return firstName_;} const std::string& lastName() const {return lastName_;} }; class HourlyEmployee : public Employee { double wage_; unsigned hours_; public: HourlyEmployee(const std::string& firstName, const std::string& lastName, double wage, unsigned hours) : Employee(firstName, lastName), wage_(wage), hours_(hours) { } double wage() const {return wage_;} unsigned hours() const {return hours_;} double calculatePay() const override { return wage_*hours_; } }; class CommissionedEmployee : public Employee { double baseSalary_; double commission_; unsigned sales_; public: CommissionedEmployee(const std::string& firstName, const std::string& lastName, double baseSalary, double commission, unsigned sales) : Employee(firstName, lastName), baseSalary_(baseSalary), commission_(commission), sales_(sales) { } double baseSalary() const { return baseSalary_; } double commission() const { return commission_; } unsigned sales() const { return sales_; } double calculatePay() const override { return baseSalary_ + commission_*sales_; } }; } // namespace ns JSONCONS_N_CTOR_GETTER_TRAITS(ns::HourlyEmployee, 3, firstName, lastName, wage, hours) JSONCONS_N_CTOR_GETTER_TRAITS(ns::CommissionedEmployee, 4, firstName, lastName, baseSalary, commission, sales) JSONCONS_POLYMORPHIC_TRAITS(ns::Employee, ns::HourlyEmployee, ns::CommissionedEmployee) int main() { std::string input = R"( [ { "firstName": "John", "hours": 1000, "lastName": "Smith", "wage": 40.0 }, { "baseSalary": 30000.0, "commission": 0.25, "firstName": "Jane", "lastName": "Doe", "sales": 1000 } ] )"; auto v = decode_json>>(input); std::cout << "(1)\n"; for (const auto& p : v) { std::cout << p->firstName() << " " << p->lastName() << ", " << p->calculatePay() << "\n"; } std::cout << "\n(2)\n"; encode_json(v, std::cout, indenting::indent); std::cout << "\n\n(3)\n"; json j(v); std::cout << pretty_print(j) << "\n\n"; } ``` Output: ``` (1) John Smith, 40000 Jane Doe, 30250 (2) [ { "firstName": "John", "hours": 1000, "lastName": "Smith", "wage": 40.0 }, { "baseSalary": 30000.0, "commission": 0.25, "firstName": "Jane", "lastName": "Doe", "sales": 1000 } ] (3) [ { "firstName": "John", "hours": 1000, "lastName": "Smith", "wage": 40.0 }, { "baseSalary": 30000.0, "commission": 0.25, "firstName": "Jane", "lastName": "Doe", "sales": 1000 } ] ```
#### Ensuring type selection is possible When deserializing a polymorphic type, jsoncons needs to know how to convert a json value to the proper derived class. In the Employee example above, the type selection strategy is based on the presence of mandatory members in the derived classes. If derived classes cannot be distinguished in this way, you can introduce extra members. The convenience macros `JSONCONS_N_MEMBER_TRAITS`, `JSONCONS_ALL_MEMBER_TRAITS`, `JSONCONS_TPL_N_MEMBER_TRAITS`, `JSONCONS_TPL_ALL_MEMBER_TRAITS`, `JSONCONS_N_MEMBER_NAME_TRAITS`, `JSONCONS_ALL_MEMBER_NAME_TRAITS`, `JSONCONS_TPL_N_MEMBER_NAME_TRAITS`, and `JSONCONS_TPL_ALL_MEMBER_NAME_TRAITS` allow you to have `const` or `static const` data members that are serialized and that particpate in the type selection strategy during deserialization. ```cpp namespace ns { class Foo { public: virtual ~Foo() noexcept = default; }; class Bar : public Foo { static const bool bar = true; JSONCONS_TYPE_TRAITS_FRIEND }; class Baz : public Foo { static const bool baz = true; JSONCONS_TYPE_TRAITS_FRIEND }; } // ns JSONCONS_N_MEMBER_TRAITS(ns::Bar,1,bar) JSONCONS_N_MEMBER_TRAITS(ns::Baz,1,baz) JSONCONS_POLYMORPHIC_TRAITS(ns::Foo, ns::Bar, ns::Baz) int main() { std::vector> u; u.emplace_back(new ns::Bar()); u.emplace_back(new ns::Baz()); std::string buffer; encode_json(u, buffer); std::cout << "(1)\n" << buffer << "\n\n"; auto v = decode_json>>(buffer); std::cout << "(2)\n"; for (const auto& ptr : v) { if (dynamic_cast(ptr.get())) { std::cout << "A bar\n"; } else if (dynamic_cast(ptr.get())) { std::cout << "A baz\n"; } } } ``` Output: ``` (1) [{"bar":true},{"baz":true}] (2) A bar A baz ```
#### Decode to a polymorphic type based on a type marker (since 0.157.0) ```cpp namespace ns { class Shape { public: virtual ~Shape() = default; virtual double area() const = 0; }; class Rectangle : public Shape { double height_; double width_; public: Rectangle(double height, double width) : height_(height), width_(width) { } const std::string& type() const { static const std::string type_ = "rectangle"; return type_; } double height() const { return height_; } double width() const { return width_; } double area() const override { return height_ * width_; } }; class Triangle : public Shape { double height_; double width_; public: Triangle(double height, double width) : height_(height), width_(width) { } const std::string& type() const { static const std::string type_ = "triangle"; return type_; } double height() const { return height_; } double width() const { return width_; } double area() const override { return (height_ * width_)/2.0; } }; class Circle : public Shape { double radius_; public: Circle(double radius) : radius_(radius) { } const std::string& type() const { static const std::string type_ = "circle"; return type_; } double radius() const { return radius_; } double area() const override { constexpr double pi = 3.14159265358979323846; return pi*radius_*radius_; } }; } // ns JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Rectangle, (type,"type",JSONCONS_RDONLY,[](const std::string& type) noexcept{return type == "rectangle";}), (height, "height"), (width, "width") ) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Triangle, (type,"type", JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "triangle";}), (height, "height"), (width, "width") ) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Circle, (type,"type", JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "circle";}), (radius, "radius") ) JSONCONS_POLYMORPHIC_TRAITS(ns::Shape,ns::Rectangle,ns::Triangle,ns::Circle) int main() { std::string input = R"( [ {"type" : "rectangle", "width" : 2.0, "height" : 1.5 }, {"type" : "triangle", "width" : 4.0, "height" : 2.0 }, {"type" : "circle", "radius" : 1.0 } ] )"; auto shapes = jsoncons::decode_json>>(input); std::cout << "(1)\n"; for (const auto& shape : shapes) { std::cout << typeid(*shape.get()).name() << " area: " << shape->area() << "\n"; } std::string output; jsoncons::encode_json(shapes, output, indenting::indent); std::cout << "\n(2)\n" << output << "\n"; } ``` Output: ``` (1) class `ns::Rectangle area: 3.0000000 class `ns::Triangle area: 4.0000000 class `ns::Circle area: 3.1415927 (2) [ { "height": 1.5, "type": "rectangle", "width": 2.0 }, { "height": 2.0, "type": "triangle", "width": 4.0 }, { "radius": 1.0, "type": "circle" } ] ``` This example maps a `type()` getter to a "type" data member in the JSON. However, we can also achieve this without using a `type()` getter at all. Compare with the very similar example [decode to a std::variant based on a type marker](#G15)
#### An example with std::variant This example assumes C++17 language support and jsoncons v0.154.0 or later. ```cpp #include namespace ns { enum class Color {yellow, red, green, blue}; inline std::ostream& operator<<(std::ostream& os, Color val) { switch (val) { case Color::yellow: os << "yellow"; break; case Color::red: os << "red"; break; case Color::green: os << "green"; break; case Color::blue: os << "blue"; break; } return os; } class Fruit { private: JSONCONS_TYPE_TRAITS_FRIEND std::string name_; Color color_; public: friend std::ostream& operator<<(std::ostream& os, const Fruit& val) { os << "name: " << val.name_ << ", color: " << val.color_ << "\n"; return os; } }; class Fabric { private: JSONCONS_TYPE_TRAITS_FRIEND int size_; std::string material_; public: friend std::ostream& operator<<(std::ostream& os, const Fabric& val) { os << "size: " << val.size_ << ", material: " << val.material_ << "\n"; return os; } }; class Basket { private: JSONCONS_TYPE_TRAITS_FRIEND std::string owner_; std::vector> items_; public: std::string owner() const { return owner_; } std::vector> items() const { return items_; } }; } // ns } // namespace JSONCONS_ENUM_NAME_TRAITS(ns::Color, (yellow, "YELLOW"), (red, "RED"), (green, "GREEN"), (blue, "BLUE")) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::Fruit, (name_, "name"), (color_, "color")) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::Fabric, (size_, "size"), (material_, "material")) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::Basket, (owner_, "owner"), (items_, "items")) int main() { std::string input = R"( { "owner": "Rodrigo", "items": [ { "name": "banana", "color": "YELLOW" }, { "size": 40, "material": "wool" }, { "name": "apple", "color": "RED" }, { "size": 40, "material": "cotton" } ] } )"; ns::Basket basket = jsoncons::decode_json(input); std::cout << basket.owner() << "\n\n"; std::cout << "(1)\n"; for (const auto& var : basket.items()) { std::visit([](auto&& arg) { using T = std::decay_t; if constexpr (std::is_same_v) std::cout << "Fruit " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "Fabric " << arg << '\n'; }, var); } std::string output; jsoncons::encode_json(basket, output, indenting::indent); std::cout << "(2)\n" << output << "\n\n"; } ``` Output: ``` Rodrigo (1) Fruit name: banana, color: yellow Fabric size: 28, material: wool Fruit name: apple, color: red Fabric size: 28, material: cotton (2) { "items": [ { "color": "YELLOW", "name": "banana" }, { "material": "wool", "size": 40 }, { "color": "RED", "name": "apple" }, { "material": "cotton", "size": 40 } ], "owner": "Rodrigo" } ```
#### Type selection and std::variant For classes supported through the convenience macros, e.g. `Fruit` and `Fabric` from the previous example, the type selection strategy is the same as for polymorphic types, and is based on the presence of mandatory members in the classes. More generally, the type selection strategy is based on the `json_type_traits::is(const Json& j)` function, checking each type in the variant from left to right, and stopping when `json_type_traits::is(j)` returns `true`. Now consider ```cpp #include namespace ns { enum class Color {yellow, red, green, blue}; } // ns JSONCONS_ENUM_NAME_TRAITS(ns::Color, (yellow, "YELLOW"), (red, "RED"), (green, "GREEN"), (blue, "BLUE")) int main() { using variant_type = std::variant; std::vector vars = {100, 10.1, false, std::string("Hello World"), ns::Color::yellow}; std::string buffer; jsoncons::encode_json(vars, buffer, indenting::indent); std::cout << "(1)\n" << buffer << "\n\n"; auto vars2 = jsoncons::decode_json>(buffer); auto visitor = [](auto&& arg) { using T = std::decay_t; if constexpr (std::is_same_v) std::cout << "int " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "double " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "bool " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "std::string " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "ns::Color " << arg << '\n'; }; std::cout << "(2)\n"; for (const auto& item : vars2) { std::visit(visitor, item); } std::cout << "\n"; } ``` Output: ``` (1) [ 100, 10.1, false, "Hello World", "YELLOW" ] (2) int 100 double 10.1 bool false std::string Hello World std::string YELLOW ``` Encode is fine. But when decoding, jsoncons checks if the JSON string "YELLOW" is a `std::string` before it checks whether it is an `ns::Color`, and since the answer is yes, it is stored in the variant as a `std::string`. But if we switch the order of `ns::Color` and `std::string` in the variant definition, viz. ```cpp using variant_type = std::variant; ``` strings containing the text "YELLOW", "RED", "GREEN", or "BLUE" are detected to be `ns::Color`, and the others `std::string`. And the output becomes ``` (1) [ 100, 10.1, false, "Hello World", "YELLOW" ] (2) int 100 double 10.1 bool false std::string Hello World ns::Color yellow ``` So: types that are more constrained should appear to the left of types that are less constrained.
#### Decode to a std::variant based on a type marker (since 0.158.0) This example is very similar to [decode to a polymorphic type based on a type marker](#G14), and in fact the json traits defined for that example would do for `std::variant` as well. But here we add a wrinkle by omitting the `type()` function in the `Rectangle`, `Triangle` and `Circle` classes. More generally, we show how to augment the JSON output with name/value pairs that are not present in the class definitions, and to perform type selection with them. ```cpp #include namespace ns { class Rectangle { double height_; double width_; public: Rectangle(double height, double width) : height_(height), width_(width) { } double height() const { return height_; } double width() const { return width_; } double area() const { return height_ * width_; } }; class Triangle { double height_; double width_; public: Triangle(double height, double width) : height_(height), width_(width) { } double height() const { return height_; } double width() const { return width_; } double area() const { return (height_ * width_)/2.0; } }; class Circle { double radius_; public: Circle(double radius) : radius_(radius) { } double radius() const { return radius_; } double area() const { constexpr double pi = 3.14159265358979323846; return pi*radius_*radius_; } }; inline constexpr auto rectangle_marker = [](double) noexcept {return "rectangle"; }; inline constexpr auto triangle_marker = [](double) noexcept {return "triangle";}; inline constexpr auto circle_marker = [](double) noexcept {return "circle";}; } // namespace ns JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Rectangle, (height,"type",JSONCONS_RDONLY, [](const std::string& type) noexcept{return type == "rectangle";}, ns::rectangle_marker), (height, "height"), (width, "width") ) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Triangle, (height,"type", JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "triangle";}, ns::triangle_marker), (height, "height"), (width, "width") ) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Circle, (radius,"type", JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "circle";}, ns::circle_marker), (radius, "radius") ) int main() { using shapes_t = std::variant; std::string input = R"( [ {"type" : "rectangle", "width" : 2.0, "height" : 1.5 }, {"type" : "triangle", "width" : 4.0, "height" : 2.0 }, {"type" : "circle", "radius" : 1.0 } ] )"; auto shapes = jsoncons::decode_json>(input); auto visitor = [](auto&& shape) { using T = std::decay_t; if constexpr (std::is_same_v) std::cout << "rectangle area: " << shape.area() << '\n'; else if constexpr (std::is_same_v) std::cout << "triangle area: " << shape.area() << '\n'; else if constexpr (std::is_same_v) std::cout << "circle area: " << shape.area() << '\n'; }; std::cout << "(1)\n"; for (const auto& shape : shapes) { std::visit(visitor, shape); } std::string output; jsoncons::encode_json(shapes, output, indenting::indent); std::cout << "\n(2)\n" << output << "\n"; } ``` Output: ``` (1) rectangle area: 3.0000000 triangle area: 4.0000000 circle area: 3.1415927 (2) [ { "height": 1.5, "type": "rectangle", "width": 2.0 }, { "height": 2.0, "type": "triangle", "width": 4.0 }, { "radius": 1.0, "type": "circle" } ] ``` Note the mapping to the "type" member, in particular, for the rectangle, ```cpp (height,"type",JSONCONS_RDONLY, [](const std::string& type) noexcept{return type == "rectangle";}, ns::rectangle_marker), ``` There are two things to observe. First, the class member being mapped, here `height`, can be any member, we don't actually use it. Instead, we use the function object `ns::rectangle_marker` to ouput the value "rectangle" with the key "type". Second, the function argument in this position cannot be a lambda expression (at least until C++20), because jsoncons uses it in an unevaluated context, so it is provided as a variable containing a lambda expression instead. See [convenience macros](ref/json_type_traits/convenience-macros.md) for full details.
#### Convert JSON numbers to/from boost multiprecision numbers ``` #include #include namespace jsoncons { template struct json_type_traits> { using multiprecision_type = boost::multiprecision::number; static bool is(const Json& val) noexcept { if (!(val.is_string() && val.semantic_tag() == semantic_tag::bigdec)) { return false; } else { return true; } } static multiprecision_type as(const Json& val) { return multiprecision_type(val.template as()); } static Json to_json(multiprecision_type val) { return Json(val.str(), semantic_tag::bigdec); } }; } int main() { typedef boost::multiprecision::number multiprecision_type; std::string s = "[100000000000000000000000000000000.1234]"; auto options = json_options{} .lossless_number(true); json j = json::parse(s, options); multiprecision_type x = j[0].as(); std::cout << "(1) " << std::setprecision(std::numeric_limits::max_digits10) << x << "\n"; json j2(json_array_arg, {x}); std::cout << "(2) " << j2[0].as() << "\n"; } ``` Output: ``` (1) 100000000000000000000000000000000.1234 (2) 100000000000000000000000000000000.1234 ``` ### Construct
#### Construct a json object Start with an empty json object and insert some name-value pairs, ```cpp json image_sizing; image_sizing.insert_or_assign("Resize To Fit",true); // a boolean image_sizing.insert_or_assign("Resize Unit", "pixels"); // a string image_sizing.insert_or_assign("Resize What", "long_edge"); // a string image_sizing.insert_or_assign("Dimension 1",9.84); // a double image_sizing.insert_or_assign("Dimension 2",json::null()); // a null value ``` or use an object initializer-list, ```cpp json file_settings( json_object_arg,{ {"Image Format", "JPEG"}, {"Color Space", "sRGB"}, {"Limit File Size", true}, {"Limit File Size To", 10000} }); }; ```
#### Insert a value into a location after creating objects when missing object keys Suppose you have ```cpp json j; // empty object std::vector keys = {"foo","bar","baz"}; // vector of keys ``` and wish to construct: ```json {"foo":{"bar":{"baz":"str"}}} ``` You can accomplish this in a loop as follows: ```cpp json* ptr = &j; for (const auto& item : keys) { auto r = ptr->try_emplace(item, json()); ptr = std::addressof(r.first->value()); } *ptr = "str"; ``` Since 0.162.0, you can also accomplish this with [jsonpointer::add](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/jsonpointer/add.md): ```cpp #include #include #include using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { std::vector keys = {"foo","bar","baz"}; jsonpointer::json_pointer location; for (const auto& key : keys) { location /= key; } json j; jsonpointer::add(j, location, "str", true); // create_if_missing set to true std::cout << pretty_print(j) << "\n\n"; } ```
#### Construct a json array ```cpp json color_spaces(json_array_arg); // an empty array color_spaces.push_back("sRGB"); color_spaces.push_back("AdobeRGB"); color_spaces.push_back("ProPhoto RGB"); ``` or use an array initializer-list, ```cpp json image_formats(json_array_arg, {"JPEG","PSD","TIFF","DNG"}); ```
#### Construct a json byte string ```cpp #include namespace jc=jsoncons; int main() { std::vector bytes = {'H','e','l','l','o'}; // default suggested encoding (base64url) json j1(byte_string_arg, bytes); std::cout << "(1) "<< j1 << "\n\n"; // base64 suggested encoding json j2(byte_string_arg, bytes, semantic_tag::base64); std::cout << "(2) "<< j2 << "\n\n"; // base16 suggested encoding json j3(byte_string_arg, bytes, semantic_tag::base16); std::cout << "(3) "<< j3 << "\n\n"; } ``` Output: ``` (1) "SGVsbG8" (2) "SGVsbG8=" (3) "48656C6C6F" ```
#### Construct multidimensional json arrays Construct a 3-dimensional 4 x 3 x 2 json array with all elements initialized to 0.0: ```cpp json j = json::make_array<3>(4, 3, 2, 0.0); double val = 1.0; for (std::size_t i = 0; i < a.size(); ++i) { for (std::size_t j = 0; j < j[i].size(); ++j) { for (std::size_t k = 0; k < j[i][j].size(); ++k) { j[i][j][k] = val; val += 1.0; } } } std::cout << pretty_print(j) << '\n'; ``` Output: ```json [ [ [1.0,2.0], [3.0,4.0], [5.0,6.0] ], [ [7.0,8.0], [9.0,10.0], [11.0,12.0] ], [ [13.0,14.0], [15.0,16.0], [17.0,18.0] ], [ [19.0,20.0], [21.0,22.0], [23.0,24.0] ] ] ```
#### Construct a json array that contains non-owning references to other json values (since 0.156.0) ```cpp #include #include int main() { std::string input = R"( { "machines": [ {"id": 1, "state": "running"}, {"id": 2, "state": "stopped"}, {"id": 3, "state": "running"} ] } )"; json j = json::parse(input); json j_v(json_array_arg); for (const auto& item : j.at("machines").array_range()) { if (item.at("state").as() == "running") { j_v.emplace_back(json_const_pointer_arg, &item); } } std::cout << "\n(1)\n" << pretty_print(j_v) << "\n\n"; for (const auto& item : j_v.array_range()) { std::cout << "json type: " << item.type() << ", storage kind: " << item.storage() << "\n"; } json j2 = deep_copy(j_v); std::cout << "\n(2)\n" << pretty_print(j2) << "\n\n"; for (const auto& item : j2.array_range()) { std::cout << "json type: " << item.type() << ", storage kind: " << item.storage() << "\n"; } } ``` Output: ```json (1) [ { "id": 1, "state": "running" }, { "id": 3, "state": "running" } ] json type: object, storage kind: json const pointer json type: object, storage kind: json const pointer (2) [ { "id": 1, "state": "running" }, { "id": 3, "state": "running" } ] json type: object, storage kind: object json type: object, storage kind: object ``` ### Access
#### Use string_view to access the actual memory that's being used to hold a string You can use `j.as()`, e.g. ```cpp json j = json::parse("\"Hello World\""); auto sv = j.as(); ``` `jsoncons::string_view` supports the member functions of `std::string_view`, including `data()` and `size()`. If your compiler supports `std::string_view`, you can also use `j.as()`.
#### Given a string in a json object that represents a decimal number, assign it to a double ```cpp json j(json_objectarg, { {"price", "25.17"} }); double price = j["price"].as(); ```
#### Retrieve a big integer that's been parsed as a string If an integer exceeds the range of an `int64_t` or `uint64_t`, jsoncons parses it as a string with semantic tagging `bigint`. ```cpp #include #include #include using jsoncons::json; int main() { std::string input = "-18446744073709551617"; json j = json::parse(input); // Access as string std::string s = j.as(); std::cout << "(1) " << s << "\n\n"; // Access as double double d = j.as(); std::cout << "(2) " << std::setprecision(17) << d << "\n\n"; // Access as jsoncons::bigint jsoncons::bigint bn = j.as(); std::cout << "(3) " << bn << "\n\n"; // If your compiler supports extended integer types __int128 i = j.as<__int128>(); std::cout << "(4) " << i << "\n\n"; } ``` Output: ``` (1) -18446744073709551617 (2) -1.8446744073709552e+19 (3) -18446744073709551617 (4) -18446744073709551617 ```
#### Look up a key, if found, return the value converted to type T, otherwise, return a default value of type T. ```cpp json j(json_object_arg, {{"price", "25.17"}}); double price = j.get_value_or("price", 25.00); // returns 25.17 double sale_price = j.get_value_or("sale_price", 22.0); // returns 22.0 ```
#### Retrieve a value in a hierarchy of JSON objects ```cpp #include #include #include int main() { json j = json::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 } ] } )"); // Using index or `at` accessors std::string result1 = j["reputons"][0]["rated"].as(); std::cout << "(1) " << result1 << '\n'; std::string result2 = j.at("reputons").at(0).at("rated").as(); std::cout << "(2) " << result2 << '\n'; // Using JSON Pointer std::string result3 = jsonpointer::get(j, "/reputons/0/rated").as(); std::cout << "(3) " << result3 << '\n'; // Using JSONPath json result4 = jsonpath::json_query(j, "$.reputons.0.rated"); if (result4.size() > 0) { std::cout << "(4) " << result4[0].as() << '\n'; } json result5 = jsonpath::json_query(j, "$..0.rated"); if (result5.size() > 0) { std::cout << "(5) " << result5[0].as() << '\n'; } } ```
#### Retrieve a json value as a byte string ```cpp #include namespace jc=jsoncons; int main() { json j; j["ByteString"] = json(byte_string_arg, std::vector{ 'H','e','l','l','o' }); j["EncodedByteString"] = json("SGVsbG8=", semantic_tag::base64); std::cout << "(1)\n"; std::cout << pretty_print(j) << "\n\n"; // Retrieve a byte string as a std::vector std::vector v = j["ByteString"].as>(); // Retrieve a byte string from a text string containing base64 character values byte_string bytes2 = j["EncodedByteString"].as(); std::cout << "(2) " << bytes2 << "\n\n"; // Retrieve a byte string view to access the memory that's holding the byte string byte_string_view bsv3 = j["ByteString"].as(); std::cout << "(3) " << bsv3 << "\n\n"; // Can't retrieve a byte string view of a text string try { byte_string_view bsv4 = j["EncodedByteString"].as(); } catch (const std::exception& e) { std::cout << "(4) "<< e.what() << "\n\n"; } } ``` Output: ``` (1) { "ByteString": "SGVsbG8", "EncodedByteString": "SGVsbG8=" } (2) 48 65 6c 6c 6f (3) 48 65 6c 6c 6f (4) Not a byte string ``` ### Iterate
#### Iterate over a json array ```cpp json j(json_array_arg, {1,2,3,4}); for (auto val : j.array_range()) { std::cout << val << '\n'; } ```
#### Iterate over a json object ```cpp json j(json_object_arg, { {"author", "Haruki Murakami"}, {"title", "Kafka on the Shore"}, {"price", 25.17} }); for (const auto& member : j.object_range()) { std::cout << member.key() << " => " << member.value() << '\n'; } // or, since 0.176.0, using C++ 17 structured binding for (const auto& [key, value] : j.object_range()) { std::cout << key << " => " << value << '\n'; } ``` ### Modify
#### Insert a new value in an array at a specific position ```cpp json cities(json_array_arg); // an empty array cities.push_back("Toronto"); cities.push_back("Vancouver"); // Insert "Montreal" at beginning of array cities.insert(cities.array_range().begin(),"Montreal"); std::cout << cities << '\n'; ``` Output: ``` ["Montreal","Toronto","Vancouver"] ```
#### Merge two json objects [json::merge](ref/json/merge.md) inserts another json object's key-value pairs into a json object, unless they already exist with an equivalent key. [json::merge_or_update](ref/json/merge_or_update.md) inserts another json object's key-value pairs into a json object, or assigns them if they already exist. The `merge` and `merge_or_update` functions perform only a one-level-deep shallow merge, not a deep merge of nested objects. ```cpp json another = json::parse(R"( { "a" : "2", "c" : [4,5,6] } )"); json j = json::parse(R"( { "a" : "1", "b" : [1,2,3] } )"); j.merge(std::move(another)); std::cout << pretty_print(j) << '\n'; ``` Output: ```json { "a": "1", "b": [1,2,3], "c": [4,5,6] } ```
#### Erase an object with a specified key from an array ```cpp int main() { std::string input = R"( [ { "address": "ashdod", "email": "ron10@gmail.com", "first name": "ron", "id": "756746783", "last name": "cohen", "phone": "0526732996", "salary": 3000, "type": "manager" }, { "address": "ashdod", "email": "nirlevy120@gmail.com", "first name": "nir", "id": "11884398", "last name": "levy", "phone": "0578198932", "salary": 4500, "type": "manager" } ] )"; try { // Read from input json instance = json::parse(input); // Locate the item to be erased auto it = std::find_if(instance.array_range().begin(), instance.array_range().end(), [](const json& item){return item.at("id") == "756746783";}); // If found, erase it if (it != instance.array_range().end()) { instance.erase(it); } std::cout << pretty_print(instance) << "\n\n"; } catch (const std::exception& e) { std::cout << e.what() << '\n'; } } ``` Output: ```json [ { "address": "ashdod", "email": "nirlevy120@gmail.com", "first name": "nir", "id": "11884398", "last name": "levy", "phone": "0578198932", "salary": 4500, "type": "manager" } ] ```
#### Iterating an array and erasing elements (since 0.168.6) ```cpp #include using jsoncons::json; int main() { std::string input = R"( ["a","b","c","d","e","f"] )"; json j = json::parse(input); auto it = j.array_range().begin(); while (it != j.array_range().end()) { if (*it == "a" || *it == "c") { it = j.erase(it); } else { it++; } } std::cout << j << "\n\n"; } ``` Output: ```json ["b","d","e","f"] ```
#### Iterating an object and erasing members (since 0.168.6) ```cpp #include using jsoncons::json; int main() { std::string input = R"( {"a":1, "b":2, "c":3, "d":4} )"; json j = json::parse(input); auto it = j.object_range().begin(); while (it != j.object_range().end()) { if (it->key() == "a" || it->key() == "c") { it = j.erase(it); } else { it++; } } std::cout << j << "\n\n"; } ``` Output: ```json {"b":2,"d":4} ``` ### Search and Replace
#### Search for and repace an object member key You can rename object members with the built in filter [rename_object_key_filter](ref/rename_object_key_filter.md) ```cpp #include #include #include using namespace jsoncons; int main() { std::string s = R"({"first":1,"second":2,"fourth":3,"fifth":4})"; json_stream_encoder encoder(std::cout); // Filters can be chained rename_object_key_filter filter2("fifth", "fourth", encoder); rename_object_key_filter filter1("fourth", "third", filter2); // A filter can be passed to any function that takes a json_visitor ... std::cout << "(1) "; std::istringstream is(s); //json_reader reader(is, filter1); // (until 0.164.0) json_stream_reader reader(is, filter1); // (since 0.164.0) reader.read(); std::cout << '\n'; // or std::cout << "(2) "; ojson j = ojson::parse(s); j.dump(filter1); std::cout << '\n'; } ``` Output: ```json (1) {"first":1,"second":2,"third":3,"fourth":4} (2) {"first":1,"second":2,"third":3,"fourth":4} ```
#### Search for and replace a value You can use [json_replace](ref/jsonpath/json_replace.md) in the `jsonpath` extension ```cpp #include #include // For brevity using jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { std::string data = R"( { "books": [ { "author": "Nigel Rees", "title": "Sayings of the Century", "isbn": "0048080489", "price": 8.95 }, { "author": "Evelyn Waugh", "title": "Sword of Honour", "isbn": "0141193557", "price": 12.99 }, { "author": "Herman Melville", "title": "Moby Dick", "isbn": "0553213113", "price": 8.99 } ] } )"; json j = json::parse(data); // Change the price of "Moby Dick" from $8.99 to $10 jsonpath::json_replace(j,"$.books[?(@.isbn == '0553213113')].price",10.0); // Increase the price of "Sayings of the Century" by $1 auto f = [](const std::string& /*location*/, json& value) { value = value.as() + 1.0; }; jsonpath::json_replace(j, "$.books[?(@.isbn == '0048080489')].price", f); // (since 0.161.0) std::cout << pretty_print(j) << '\n'; } ``` Output: ```json { "books": [ { "author": "Nigel Rees", "isbn": "0048080489", "price": 9.95, "title": "Sayings of the Century" }, { "author": "Evelyn Waugh", "isbn": "0141193557", "price": 12.99, "title": "Sword of Honour" }, { "author": "Herman Melville", "isbn": "0553213113", "price": 10.0, "title": "Moby Dick" } ] } ```
#### Update JSON in place Suppose you have a JSON text, and need to replace one or more strings found at a relative location path, but are not allowed to modify anything else in the original text. ```cpp #include using namespace jsoncons; class string_locator : public jsoncons::default_json_visitor { char* data_; std::size_t length_; std::vector path_; std::string from_; std::vector current_; std::vector positions_; public: using jsoncons::default_json_visitor::string_view_type; string_locator(char* data, std::size_t length, const std::vector& path, const std::string& from) : data_(data), length_(length), path_(path), from_(from) { } const std::vector& positions() const { return positions_; } private: bool visit_begin_object(semantic_tag, const ser_context&, std::error_code&) override { current_.emplace_back(); return true; } bool visit_end_object(const ser_context&, std::error_code&) override { current_.pop_back(); return true; } bool visit_key(const string_view_type& key, const ser_context&, std::error_code&) override { current_.back() = key; return true; } bool visit_string(const string_view_type& value, jsoncons::semantic_tag, const jsoncons::ser_context& context, std::error_code&) override { if (path_.size() <= current_.size() && std::equal(path_.rbegin(), path_.rend(), current_.rbegin())) { if (value == from_) { positions_.push_back(context.position()+1); // one past quote character } } return true; } }; void update_json_in_place(std::string& input, const std::vector& path, const std::string& from, const std::string& to) { string_locator locator(input.data(), input.size(), path, from); //jsoncons::json_reader reader(input, locator); // (until 0.164.0) jsoncons::json_string_reader reader(input, locator); // (since 0.164.0) reader.read(); for (auto it = locator.positions().rbegin(); it != locator.positions().rend(); ++it) { input.replace(*it, from.size(), to); } } int main() { std::string input = R"( { "Cola" : {"Type":"Drink", "Price": 10.99},"Water" : {"Type":"Drink"}, "Extra" : {"Cola" : {"Type":"Drink", "Price": 8.99}} } )"; try { std::cout << "(original)\n" << input << "\n"; update_json_in_place(input, {"Cola", "Type"}, "Drink", "SoftDrink"); std::cout << "(updated)\n" << input << "\n"; } catch (std::exception& e) { std::cout << e.what() << "\n"; } } ``` Output: ```json (original) { "Cola" : {"Type":"Drink", "Price": 10.99},"Water" : {"Type":"Drink"}, "Extra" : {"Cola" : {"Type":"Drink", "Price": 8.99}} } (updated) { "Cola" : {"Type":"SoftDrink", "Price": 10.99},"Water" : {"Type":"Drink"}, "Extra" : {"Cola" : {"Type":"SoftDrink", "Price": 8.99}} } ``` ### Flatten and unflatten
#### Flatten a json object with numberish keys to JSON Pointer/value pairs ```cpp #include #include #include // for brevity using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { json input = json::parse(R"( { "discards": { "1000": "Record does not exist", "1004": "Queue limit exceeded", "1010": "Discarding timed-out partial msg" }, "warnings": { "0": "Phone number missing country code", "1": "State code missing", "2": "Zip code missing" } } )"); json flattened = jsonpointer::flatten(input); std::cout << "(1)\n" << pretty_print(flattened) << "\n"; json unflattened1 = jsonpointer::unflatten(flattened); std::cout << "(2)\n" << pretty_print(unflattened1) << "\n"; json unflattened2 = jsonpointer::unflatten(flattened, jsonpointer::unflatten_options::assume_object); std::cout << "(3)\n" << pretty_print(unflattened2) << "\n"; } ``` Output: ``` (1) { "/discards/1000": "Record does not exist", "/discards/1004": "Queue limit exceeded", "/discards/1010": "Discarding timed-out partial msg", "/warnings/0": "Phone number missing country code", "/warnings/1": "State code missing", "/warnings/2": "Zip code missing" } (2) { "discards": { "1000": "Record does not exist", "1004": "Queue limit exceeded", "1010": "Discarding timed-out partial msg" }, "warnings": ["Phone number missing country code", "State code missing", "Zip code missing"] } (3) { "discards": { "1000": "Record does not exist", "1004": "Queue limit exceeded", "1010": "Discarding timed-out partial msg" }, "warnings": { "0": "Phone number missing country code", "1": "State code missing", "2": "Zip code missing" } } ``` Note that unflattening a json object of JSON Pointer-value pairs has no unique solution. An integer appearing in a path could be an array index or it could be an object key.
#### Flatten a json object to JSONPath/value pairs ```cpp #include #include #include #include // for brevity using jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { json input = json::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 }, { "rater": "HikingAsylum", "assertion": "intermediate", "rated": "Hongmin", "rating": 0.75 } ] } )"); json result = jsonpath::flatten(input); std::cout << pretty_print(result) << "\n"; json original = jsonpath::unflatten(result); assert(original == input); } ``` Output: ``` { "$['application']": "hiking", "$['reputons'][0]['assertion']": "advanced", "$['reputons'][0]['rated']": "Marilyn C", "$['reputons'][0]['rater']": "HikingAsylum", "$['reputons'][0]['rating']": 0.9, "$['reputons'][1]['assertion']": "intermediate", "$['reputons'][1]['rated']": "Hongmin", "$['reputons'][1]['rater']": "HikingAsylum", "$['reputons'][1]['rating']": 0.75 } ``` jsoncons-1.3.2/doc/Pages/000077500000000000000000000000001477700171100151625ustar00rootroot00000000000000jsoncons-1.3.2/doc/Pages/index.md000066400000000000000000000703661477700171100166270ustar00rootroot00000000000000# jsoncons: a C++ library for json construction [Introduction](#A1) [Reading JSON text from a file](#A2) [Constructing json values in C++](#A3) [Converting CSV files to json](#A5 ) [Pretty print](#A6) [Filters](#A7) [JSONPath](#A8) [About jsoncons::json](#A9) [Wide character support](#A10) [ojson and wojson](#A11)
### Introduction jsoncons is a C++, header-only library for constructing [JSON](http://www.json.org) and JSON-like data formats such as [CBOR](http://cbor.io/). For each supported data format, it enables you to work with the data in a number of ways: - As a variant-like data structure, [basic_json](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/basic_json.md) - As a strongly typed C++ data structure that implements [json_type_traits](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/json_type_traits.md) - With [cursor-level access](https://github.com/danielaparker/jsoncons/blob/doc/doc/ref/corelib/basic_json_cursor.md) to a stream of parse events, somewhat analogous to StAX pull parsing and push serializing in the XML world. Compared to other JSON libraries, jsoncons has been designed to handle very large JSON texts. At its heart are SAX-style parsers and serializers. It supports reading an entire JSON text in memory in a variant-like structure. But it also supports efficient access to the underlying data using StAX-style pull parsing and push serializing. And it supports incremental parsing into a user's preferred form, using information about user types provided by specializations of [json_type_traits](doc/ref/corelib/json_type_traits.md). The [jsoncons data model](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/data-model.md) supports the familiar JSON types - nulls, booleans, numbers, strings, arrays, objects - plus byte strings. In addition, jsoncons supports semantic tagging of datetimes, epoch times, big integers, big decimals, big floats and binary encodings. This allows it to preserve these type semantics when parsing JSON-like data formats such as CBOR that have them. For the examples below you need to include some header files and initialize a string of JSON data: ```cpp #include #include #include using namespace jsoncons; // for convenience std::string data = R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90, "confidence": 0.99 } ] } )"; ``` jsoncons allows you to work with the data in a number of ways: - As a variant-like data structure, [basic_json](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/basic_json.md) - As a strongly typed C++ data structure that implements [json_type_traits](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/json_type_traits.md) - As a stream of parse events #### As a variant-like data structure ```cpp int main() { // Parse the string of data into a json value json j = json::parse(data); // Does object member reputons exist? std::cout << "(1) " << std::boolalpha << j.contains("reputons") << "\n\n"; // Get a reference to reputons array const json& v = j["reputons"]; // Iterate over reputons array std::cout << "(2)\n"; for (const auto& item : v.array_range()) { // Access rated as string and rating as double std::cout << item["rated"].as() << ", " << item["rating"].as() << "\n"; } std::cout << "\n"; // Select all "rated" with JSONPath std::cout << "(3)\n"; json result = jsonpath::json_query(j,"$..rated"); std::cout << pretty_print(result) << "\n\n"; // Serialize back to JSON std::cout << "(4)\n" << pretty_print(j) << "\n\n"; } ``` Output: ``` (1) true (2) Marilyn C, 0.9 (3) [ "Marilyn C" ] (4) { "application": "hiking", "reputons": [ { "assertion": "advanced", "confidence": 0.99, "rated": "Marilyn C", "rater": "HikingAsylum", "rating": 0.9 } ] } ``` #### As a strongly typed C++ data structure jsoncons supports transforming JSON texts into C++ data structures. The functions [decode_json](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/decode_json.md) and [encode_json](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/encode_json.md) convert strings or streams of JSON data to C++ data structures and back. Decode and encode work for all C++ classes that have [json_type_traits](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/json_type_traits.md) defined. jsoncons already supports many types in the standard library, and your own types will be supported too if you specialize `json_type_traits` in the `jsoncons` namespace. ```cpp namespace ns { enum class hiking_experience {beginner,intermediate,advanced}; class hiking_reputon { std::string rater_; hiking_experience assertion_; std::string rated_; double rating_; std::optional generated_; // assumes C++17, if not use jsoncons::optional std::optional expires_; public: hiking_reputon(const std::string& rater, hiking_experience assertion, const std::string& rated, double rating, const std::optional& generated = std::optional(), const std::optional& expires = std::optional()) : rater_(rater), assertion_(assertion), rated_(rated), rating_(rating), generated_(generated), expires_(expires) { } const std::string& rater() const {return rater_;} hiking_experience assertion() const {return assertion_;} const std::string& rated() const {return rated_;} double rating() const {return rating_;} std::optional generated() const {return generated_;} std::optional expires() const {return expires_;} friend bool operator==(const hiking_reputon& lhs, const hiking_reputon& rhs) { return lhs.rater_ == rhs.rater_ && lhs.assertion_ == rhs.assertion_ && lhs.rated_ == rhs.rated_ && lhs.rating_ == rhs.rating_ && lhs.confidence_ == rhs.confidence_ && lhs.expires_ == rhs.expires_; } friend bool operator!=(const hiking_reputon& lhs, const hiking_reputon& rhs) { return !(lhs == rhs); }; }; class hiking_reputation { std::string application_; std::vector reputons_; public: hiking_reputation(const std::string& application, const std::vector& reputons) : application_(application), reputons_(reputons) {} const std::string& application() const { return application_;} const std::vector& reputons() const { return reputons_;} }; } // namespace ns // Declare the traits. Specify which data members need to be serialized. JSONCONS_ENUM_TRAITS(ns::hiking_experience, beginner, intermediate, advanced) // First four members listed are mandatory, generated and expires are optional JSONCONS_N_CTOR_GETTER_TRAITS(ns::hiking_reputon, 4, rater, assertion, rated, rating, generated, expires) // All members are mandatory JSONCONS_ALL_CTOR_GETTER_TRAITS(ns::hiking_reputation, application, reputons) int main() { // Decode the string of data into a c++ structure ns::hiking_reputation v = decode_json(data); // Iterate over reputons array value std::cout << "(1)\n"; for (const auto& item : v.reputons()) { std::cout << item.rated() << ", " << item.rating(); if (item.generated()) { std::cout << ", " << (*item.generated()).count(); } std::cout << "\n"; } // Encode the c++ structure into a string std::string s; encode_json(v, s, indenting::indent); std::cout << "(2)\n"; std::cout << s << "\n"; } ``` Output: ``` (1) Marilyn C, 0.9, 1514862245 (2) { "application": "hiking", "reputons": [ { "assertion": "advanced", "generated": 1514862245, "rated": "Marilyn C", "rater": "HikingAsylum", "rating": 0.9 } ] } ``` This example makes use of the convenience macros `JSONCONS_ENUM_TRAITS` and `JSONCONS_ALL_CTOR_GETTER_TRAITS` to specialize the [json_type_traits](doc/ref/corelib/json_type_traits.md) for the enum type `ns::hiking_experience` and the classes `ns::hiking_reputon` and `ns::hiking_reputation`. The macro `JSONCONS_ENUM_TRAITS` generates the code from the enum values, and the macro `JSONCONS_ALL_CTOR_GETTER_TRAITS` generates the code from the get functions and a constructor. These macro declarations must be placed outside any namespace blocks. See [examples](https://github.com/danielaparker/jsoncons/blob/master/doc/Examples.md#G1) for other ways of specializing `json_type_traits`. #### With cursor-level access ```cpp int main() { json_string_cursor cursor(data); for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::end_array: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::begin_object: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::end_object: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::key: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::string_value: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::null_value: std::cout << event.event_type() << "\n"; break; case staj_event_type::bool_value: std::cout << event.event_type() << ": " << std::boolalpha << event.get() << "\n"; break; case staj_event_type::int64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::double_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; default: std::cout << "Unhandled event type: " << event.event_type() << " " << "\n"; break; } } } ``` Output: ``` Marilyn C begin_object key: application string_value: hiking key: reputons begin_array begin_object key: rater string_value: HikingAsylum key: assertion string_value: advanced key: rated string_value: Marilyn C key: rating double_value: 0.9 key: confidence double_value: 0.99 end_object end_array end_object ```
### Reading JSON text from a file Input JSON file `books.json`: ```cpp [ { "title" : "Kafka on the Shore", "author" : "Haruki Murakami", "price" : 25.17 }, { "title" : "Women: A Novel", "author" : "Charles Bukowski", "price" : 12.0 }, { "title" : "Cutter's Way", "author" : "Ivan Passer" } ] ``` It consists of an array of book elements, each element is an object with members title, author, and price. Read the JSON text into a `json` value, ```cpp std::ifstream is("books.json"); json books = json::parse(is); ``` Loop through the book array elements, using a range-based for loop ```cpp for (const auto& book : books.array_range()) { std::string author = book["author"].as(); std::string title = book["title"].as(); std::cout << author << ", " << title << '\n'; } ``` or begin-end iterators ```cpp for (auto it = books.array_range().begin(); it != books.array_range().end(); ++it) { std::string author = (*it)["author"].as(); std::string title = (*it)["title"].as(); std::cout << author << ", " << title << '\n'; } ``` or a traditional for loop ```cpp for (std::size_t i = 0; i < books.size(); ++i) { json& book = books[i]; std::string author = book["author"].as(); std::string title = book["title"].as(); std::cout << author << ", " << title << '\n'; } ``` Output: ``` Haruki Murakami, Kafka on the Shore Charles Bukowski, Women: A Novel Ivan Passer, Cutter's Way ``` Loop through the members of the third book element, using a range-based for loop ```cpp for (const auto& member : books[2].object_range()) { std::cout << member.key() << "=" << member.value() << '\n'; } ``` or begin-end iterators: ```cpp for (auto it = books[2].object_range().begin(); it != books[2].object_range().end(); ++it) { std::cout << (*it).key() << "=" << (*it).value() << '\n'; } ``` Output: ``` author=Ivan Passer title=Cutter's Way ``` Note that the third book, Cutter's Way, is missing a price. You have a choice of object member accessors: - `book["price"]` will throw `std::out_of_range` if there is no price. - `book.at("price")` will throw `std::out_of_range` if there is no price. - `book.at_or_null("price")` will return a null json value if there is no price. - `book.get_value_or("price","n/a")` will return the price as `std::string` if available, otherwise `"n/a"`. Or, you can check if book has a member "price" with the member function `contains`, ```cpp if (book.contains("price")) { double price = book["price"].as(); std::cout << price; } else { std::cout << "n/a"; } ```
### Constructing json values in C++ The default `json` constructor produces an empty json object. For example ```cpp json image_sizing; std::cout << image_sizing << '\n'; ``` produces ```json {} ``` To construct a json object with members, take an empty json object and set some name-value pairs ```cpp image_sizing.insert_or_assign("Resize To Fit",true); // a boolean image_sizing.insert_or_assign("Resize Unit", "pixels"); // a string image_sizing.insert_or_assign("Resize What", "long_edge"); // a string image_sizing.insert_or_assign("Dimension 1",9.84); // a double image_sizing.insert_or_assign("Dimension 2",json::null()); // a null value ``` Or, use an object initializer-list: ```cpp json file_settings(json::object_arg, { {"Image Format", "JPEG"}, {"Color Space", "sRGB"}, {"Limit File Size", true}, {"Limit File Size To", 10000} }); ``` To construct a json array, initialize with the array type ```cpp json color_spaces(json_array_arg); ``` and add some elements ```cpp color_spaces.push_back("sRGB"); color_spaces.push_back("AdobeRGB"); color_spaces.push_back("ProPhoto RGB"); ``` Or, use an array initializer-list: ```cpp json image_formats(json_array_arg, {"JPEG","PSD","TIFF","DNG"}); ``` The `operator[]` provides another way for setting name-value pairs. ```cpp json file_export; file_export["File Format Options"]["Color Spaces"] = std::move(color_spaces); file_export["File Format Options"]["Image Formats"] = std::move(image_formats); file_export["File Settings"] = std::move(file_settings); file_export["Image Sizing"] = std::move(image_sizing); ``` Note that if `file_export["File Format Options"]` doesn't exist, the statement ``` file_export["File Format Options"]["Color Spaces"] = std::move(color_spaces) ``` creates `"File Format Options"` as an object and puts `"Color Spaces"` in it. Serializing ```cpp std::cout << pretty_print(file_export) << '\n'; ``` produces ```json { "File Format Options": { "Color Spaces": ["sRGB","AdobeRGB","ProPhoto RGB"], "Image Formats": ["JPEG","PSD","TIFF","DNG"] }, "File Settings": { "Color Space": "sRGB", "Image Format": "JPEG", "Limit File Size": true, "Limit File Size To": 10000 }, "Image Sizing": { "Dimension 1": 9.84, "Dimension 2": null, "Resize To Fit": true, "Resize Unit": "pixels", "Resize What": "long_edge" } } ```
### Converting CSV files to json Example CSV file (tasks.csv): ``` project_id, task_name, task_start, task_finish 4001,task1,01/01/2003,01/31/2003 4001,task2,02/01/2003,02/28/2003 4001,task3,03/01/2003,03/31/2003 4002,task1,04/01/2003,04/30/2003 4002,task2,05/01/2003, ``` You can read the `CSV` file into a `json` value with the `decode_csv` function. ```cpp #include #include #include using namespace jsoncons; int main() { std::ifstream is("input/tasks.csv"); auto options = csv::csv_options{} .assume_header(true) .trim(true) .ignore_empty_values(true) .column_types("integer,string,string,string"); ojson tasks = csv::decode_csv(is, options); std::cout << "(1)\n" << pretty_print(tasks) << "\n\n"; std::cout << "(2)\n"; csv::encode_csv(tasks, std::cout); } ``` Output: ```json (1) [ { "project_id": 4001, "task_name": "task1", "task_start": "01/01/2003", "task_finish": "01/31/2003" }, { "project_id": 4001, "task_name": "task2", "task_start": "02/01/2003", "task_finish": "02/28/2003" }, { "project_id": 4001, "task_name": "task3", "task_start": "03/01/2003", "task_finish": "03/31/2003" }, { "project_id": 4002, "task_name": "task1", "task_start": "04/01/2003", "task_finish": "04/30/2003" }, { "project_id": 4002, "task_name": "task2", "task_start": "05/01/2003" } ] ``` There are a few things to note about the effect of the parameter settings. - `assume_header` `true` tells the csv parser to parse the first line of the file for column names, which become object member names. - `trim` `true` tells the parser to trim leading and trailing whitespace, in particular, to remove the leading whitespace in the column names. - `ignore_empty_values` `true` causes the empty last value in the `task_finish` column to be omitted. - The `column_types` setting specifies that column one ("project_id") contains integers and the remaining columns strings.
### Pretty print The `pretty_print` function applies stylistic formatting to JSON text. For example ```cpp json j; j["verts"] = json(json_array_arg, {1, 2, 3}); j["normals"] = json(json_array_arg, {1, 0, 1}); j["uvs"] = json(json_array_arg, {0, 0, 1, 1}); std::cout << pretty_print(j) << '\n'; ``` produces ```json { "normals": [1,0,1], "uvs": [0,0,1,1], "verts": [1,2,3] } ``` By default, within objects, arrays of scalar values are displayed on the same line. The `pretty_print` function takes an optional second parameter, [basic_json_options](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/basic_json_options.md), that allows custom formatting of output. To display the array scalar values on a new line, set the `object_array_line_splits` property to `line_split_kind::new_line`. The code ```cpp auto options = json_options{} .object_array_line_splits(line_split_kind::new_line); std::cout << pretty_print(val,options) << '\n'; ``` produces ```json { "normals": [ 1,0,1 ], "uvs": [ 0,0,1,1 ], "verts": [ 1,2,3 ] } ``` To display the elements of array values on multiple lines, set the `object_array_line_splits` property to `line_split_kind::multi_line`. The code ```cpp auto options = json_options{} .object_array_line_splits(line_split_kind::multi_line); std::cout << pretty_print(val,options) << '\n'; ``` produces ```json { "normals": [ 1, 0, 1 ], "uvs": [ 0, 0, 1, 1 ], "verts": [ 1, 2, 3 ] } ```
### Filters You can rename object member names with the built in filter [rename_object_key_filter](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/rename_object_key_filter.md) ```cpp #include #include #include using namespace jsoncons; int main() { std::string s = R"({"first":1,"second":2,"fourth":3,"fifth":4})"; json_stream_encoder encoder(std::cout); // Filters can be chained rename_object_key_filter filter2("fifth", "fourth", encoder); rename_object_key_filter filter1("fourth", "third", filter2); // A filter can be passed to any function that takes // a json_visitor ... std::cout << "(1) "; //json_reader reader(s, filter1); // (until 0.164.0) json_string_reader reader(s, filter1); // (since 0.164.0) reader.read(); std::cout << '\n'; // or a json_visitor std::cout << "(2) "; ojson j = ojson::parse(s); j.dump(filter1); std::cout << '\n'; } ``` Output: ```json (1) {"first":1,"second":2,"third":3,"fourth":4} (2) {"first":1,"second":2,"third":3,"fourth":4} ``` Or define and use your own filters. See [basic_json_filter](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/basic_json_filter.md) for details.
### JSONPath [Stefan Goessner's JSONPath](http://goessner.net/articles/JsonPath/) is an XPATH inspired query language for selecting parts of a JSON structure. Example JSON file (store.json): ```json { "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ] } } ``` JSONPath examples: ```cpp #include using jsoncons::jsonpath::json_query; std::ifstream is("./input/store.json"); json booklist = json::parse(is); // The authors of books that are cheaper than $10 json result1 = json_query(booklist, "$.store.book[?(@.price < 10)].author"); std::cout << "(1) " << result1 << '\n'; // The number of books json result2 = json_query(booklist, "$..book.length"); std::cout << "(2) " << result2 << '\n'; // The third book json result3 = json_query(booklist, "$..book[2]"); std::cout << "(3)\n" << pretty_print(result3) << '\n'; // All books whose author's name starts with Evelyn json result4 = json_query(booklist, "$.store.book[?(@.author =~ /Evelyn.*?/)]"); std::cout << "(4)\n" << pretty_print(result4) << '\n'; // The titles of all books that have isbn number json result5 = json_query(booklist, "$..book[?(@.isbn)].title"); std::cout << "(5) " << result5 << '\n'; // All authors and titles of books json result6 = json_query(booklist, "$['store']['book']..['author','title']"); std::cout << "(6)\n" << pretty_print(result6) << '\n'; ``` Output: ```json (1) ["Nigel Rees","Herman Melville"] (2) [4] (3) [ { "author": "Herman Melville", "category": "fiction", "isbn": "0-553-21311-3", "price": 8.99, "title": "Moby Dick" } ] (4) [ { "author": "Evelyn Waugh", "category": "fiction", "price": 12.99, "title": "Sword of Honour" } ] (5) ["Moby Dick","The Lord of the Rings"] (6) [ "Nigel Rees", "Sayings of the Century", "Evelyn Waugh", "Sword of Honour", "Herman Melville", "Moby Dick", "J. R. R. Tolkien", "The Lord of the Rings" ] ```
### About jsoncons::json The [json](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/json.md) class is an instantiation of the `basic_json` class template that uses `char` as the character type and sorts object members in alphabetically order. ```cpp typedef basic_json> json; ``` If you prefer to retain the original insertion order, use [ojson](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/ojson.md) instead. The library includes an instantiation for wide characters as well, [wjson](https://github.com/danielaparker/jsoncons/blob/master/ref/doc/wjson.md) ```cpp typedef basic_json> wjson; ``` If you prefer to retain the original insertion order, use [wojson](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/wojson.md) instead. Note that the allocator type allows you to supply a custom allocator. For example, you can use the boost [fast_pool_allocator](http://www.boost.org/doc/libs/1_60_0/libs/pool/doc/html/boost/fast_pool_allocator.html): ```cpp #include #include typedef jsoncons::basic_json> my_json; my_json o; o.insert_or_assign("FirstName","Joe"); o.insert_or_assign("LastName","Smith"); ``` This results in a json value being constucted with all memory being allocated from the boost memory pool. (In this particular case there is no improvement in performance over `std::allocator`.) Note that the underlying memory pool used by the `boost::fast_pool_allocator` is never freed.
### Wide character support jsoncons supports wide character strings `wjson`. It supports `UTF16` encoding if `wchar_t` has size 2 (Windows) and `UTF32` encoding if `wchar_t` has size 4. You can construct a `wjson` value in exactly the same way as a `json` value, for instance: ```cpp using jsoncons::wjson; wjson j; j[L"field1"] = L"test"; j[L"field2"] = 3.9; j[L"field3"] = true; std::wcout << j << L"\n"; ``` which prints ```cpp {"field1":"test","field2":3.9,"field3":true} ```
### ojson and wojson The [ojson](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/ojson.md) ([wojson](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/wojson.md)) class is an instantiation of the `basic_json` class template that uses `char` (`wchar_t`) as the character type and keeps object members in their original order. ```cpp ojson o = ojson::parse(R"( { "street_number" : "100", "street_name" : "Queen St W", "city" : "Toronto", "country" : "Canada" } )"); std::cout << pretty_print(o) << '\n'; ``` Output: ```json { "street_number": "100", "street_name": "Queen St W", "city": "Toronto", "country": "Canada" } ``` Insert "postal_code" at end ```cpp o.insert_or_assign("postal_code", "M5H 2N2"); std::cout << pretty_print(o) << '\n'; ``` Output: ```json { "street_number": "100", "street_name": "Queen St W", "city": "Toronto", "country": "Canada", "postal_code": "M5H 2N2" } ``` Insert "province" before "country" ```cpp auto it = o.find("country"); o.insert_or_assign(it,"province","Ontario"); std::cout << pretty_print(o) << '\n'; ``` Output: ```json { "street_number": "100", "street_name": "Queen St W", "city": "Toronto", "province": "Ontario", "country": "Canada", "postal_code": "M5H 2N2" } ``` For more information, consult the latest [examples](https://github.com/danielaparker/jsoncons/blob/master/doc/Examples.md), [documentation](https://github.com/danielaparker/jsoncons/blob/master/doc/Reference.md) and [roadmap](https://github.com/danielaparker/jsoncons/blob/master/Roadmap.md). jsoncons-1.3.2/doc/Reference.md000066400000000000000000000027661477700171100163560ustar00rootroot00000000000000All core jsoncons classes and functions are in namespace `jsoncons`. #### Variant-like Data Structure [basic_json](ref/corelib/basic_json.md) #### Serialize and Deserialize Support [json_type_traits](ref/corelib/json_type_traits.md) [encode_json](ref/corelib/encode_json.md) [decode_json](ref/corelib/decode_json.md) [basic_json_options](ref/corelib/basic_json_options.md) #### Streaming API for JSON (StAJ) [staj_cursor](ref/corelib/staj_cursor.md) [basic_staj_event](ref/corelib/basic_staj_event.md) [staj_object_iterator](ref/corelib/staj_object_iterator.md) [staj_array_iterator](ref/corelib/staj_array_iterator.md) [basic_json_cursor](ref/corelib/basic_json_cursor.md) [basic_json_encoder](ref/corelib/basic_json_encoder.md) #### Push Parsing API [basic_json_visitor](ref/corelib/basic_json_visitor.md) [basic_json_parser](ref/corelib/basic_json_parser.md) [basic_json_reader](ref/corelib/basic_json_reader.md) [json_decoder](ref/corelib/json_decoder.md) [basic_json_filter](ref/corelib/basic_json_filter.md) [rename_object_key_filter](ref/corelib/rename_object_key_filter.md) ### Extensions #### [jsonpointer](ref/jsonpointer/jsonpointer.md) #### [jsonpatch](ref/jsonpatch/jsonpatch.md) #### [jsonpath](ref/jsonpath/jsonpath.md) #### [bson](ref/bson/bson.md) #### [cbor](ref/cbor/cbor.md) #### [msgpack](ref/msgpack/msgpack.md) #### [ubjson](ref/ubjson/ubjson.md) ### Tutorials [Basics](Tutorials/Basics.md) [Unicode support](Tutorials/Unicode%20support.md) jsoncons-1.3.2/doc/Tutorials/000077500000000000000000000000001477700171100161115ustar00rootroot00000000000000jsoncons-1.3.2/doc/Tutorials/Basics.md000066400000000000000000000253671477700171100176540ustar00rootroot00000000000000## Examples The examples below illustrate the use of the [json](../ref/basic_json.md) class and [json_query](../ref/jsonpath/json_query.md) function. ### json construction ```cpp #include // For convenience using jsoncons::json; // Construct a book object json book1; book1["category"] = "Fiction"; book1["title"] = "A Wild Sheep Chase: A Novel"; book1["author"] = "Haruki Murakami"; book1["date"] = "2002-04-09"; book1["price"] = 9.01; book1["isbn"] = "037571894X"; // Construct another using the insert_or_assign function json book2; book2.insert_or_assign("category", "History"); book2.insert_or_assign("title", "Charlie Wilson's War"); book2.insert_or_assign("author", "George Crile"); book2.insert_or_assign("date", "2007-11-06"); book2.insert_or_assign("price", 10.50); book2.insert_or_assign("isbn", "0802143415"); // Use insert_or_assign again, but more efficiently json book3; // Reserve memory, to avoid reallocations book3.reserve(6); // Insert in name alphabetical order // Give insert_or_assign a hint where to insert the next member auto hint = book3.insert_or_assign(book3.object_range().begin(),"author", "Haruki Murakami"); hint = book3.insert_or_assign(hint, "category", "Fiction"); hint = book3.insert_or_assign(hint, "date", "2006-01-03"); hint = book3.insert_or_assign(hint, "isbn", "1400079276"); hint = book3.insert_or_assign(hint, "price", 13.45); hint = book3.insert_or_assign(hint, "title", "Kafka on the Shore"); // Construct a fourth from a string json book4 = json::parse(R"( { "category" : "Fiction", "title" : "Pulp", "author" : "Charles Bukowski", "date" : "2004-07-08", "price" : 22.48, "isbn" : "1852272007" } )"); // Construct a booklist array json booklist(json_array_arg); // For efficiency, reserve memory, to avoid reallocations booklist.reserve(4); // For efficency, tell jsoncons to move the contents // of the four book objects into the array booklist.add(std::move(book1)); booklist.add(std::move(book2)); // Add the third book to the front auto pos = booklist.add(booklist.array_range().begin(),std::move(book3)); // and the last one immediately after booklist.add(pos+1,std::move(book4)); // See what's left of book1, 2, 3 and 4 (expect nulls) std::cout << book1 << "," << book2 << "," << book3 << "," << book4 << '\n'; ++ //Loop through the booklist elements using a range-based for loop for (const auto& book : booklist.array_range()) { std::cout << book["title"].as() << "," << book["price"].as() << '\n'; } // The second book json& book = booklist[1]; //Loop through the book's name-value pairs using a range-based for loop for (const auto& member : book.object_range()) { std::cout << member.key() << "," << member.value() << '\n'; } auto it = book.find("author"); if (it != book.object_range().end()) { // member "author" found } if (book.contains("author")) { // book has a member "author" } book.get("author", "author unknown").as(); // Returns author if found, otherwise "author unknown" try { book["ratings"].as(); } catch (const std::out_of_range& e) { // member "ratings" not found } // Add ratings book["ratings"]["*****"] = 4; book["ratings"]["*"] = 2; // Delete one-star ratings book["ratings"].erase("*"); ``` ```cpp // Serialize the booklist to a file std::ofstream os("store.json"); os << pretty_print(booklist); ``` The JSON output `store.json` ```json [ { "author":"Haruki Murakami", "category":"Fiction", "date":"2006-01-03", "isbn":"1400079276", "price":13.45, "title":"Kafka on the Shore" }, { "author":"Charles Bukowski", "category":"Fiction", "date":"2004-07-08", "isbn":"1852272007", "price":22.48, "ratings": { "*****":4 }, "title":"Pulp" }, { "author":"Haruki Murakami", "category":"Fiction", "date":"2002-04-09", "isbn":"037571894X", "price":9.01, "title":"A Wild Sheep Chase: A Novel" }, { "author":"George Crile", "category":"History", "date":"2007-11-06", "isbn":"0802143415", "price":10.5, "title":"Charlie Wilson's War" } ] ``` ### json query ```cpp #include #include #include // For convenience using jsoncons::json; using jsoncons::jsonpath::json_query; // Deserialize the booklist std::ifstream is("store.json"); json booklist; is >> booklist; // Use a JSONPath expression to find // // (1) The authors of books that cost less than $12 json result = json_query(booklist, "$[*][?(@.price < 12)].author"); std::cout << result << '\n'; // (2) The number of books result = json_query(booklist, "$.length"); std::cout << result << '\n'; // (3) The third book result = json_query(booklist, "$[2]"); std::cout << '\n' << pretty_print(result) << '\n'; // (4) The authors of books that were published in 2004 result = json_query(booklist, "$[*][?(@.date =~ /2004.*?/)].author"); std::cout << result << '\n'; // (5) The titles of all books that have ratings result = json_query(booklist, "$[*][?(@.ratings)].title"); std::cout << result << '\n'; // (6) All authors and titles of books result = json_query(booklist, "$..['author','title']"); std::cout << pretty_print(result) << '\n'; ``` Result: ```json (1) ["Haruki Murakami","George Crile"] (2) [4] (3) [ { "author":"Haruki Murakami", "category":"Fiction", "date":"2002-04-09", "isbn":"037571894X", "price":9.01, "title":"A Wild Sheep Chase: A Novel" } ] (4) ["Charles Bukowski"] (5) ["Pulp"] (6) [ "Nigel Rees", "Sayings of the Century", "Evelyn Waugh", "Sword of Honour", "Herman Melville", "Moby Dick", "J. R. R. Tolkien", "The Lord of the Rings" ] ``` ## Once again, this time with wide characters ### wjson construction ```cpp #include // For convenience using jsoncons::wjson; // Construct a book object wjson book1; book1[L"category"] = L"Fiction"; book1[L"title"] = L"A Wild Sheep Chase: A Novel"; book1[L"author"] = L"Haruki Murakami"; book1[L"date"] = L"2002-04-09"; book1[L"price"] = 9.01; book1[L"isbn"] = L"037571894X"; // Construct another using the insert_or_assign function wjson book2; book2.insert_or_assign(L"category", L"History"); book2.insert_or_assign(L"title", L"Charlie Wilson's War"); book2.insert_or_assign(L"author", L"George Crile"); book2.insert_or_assign(L"date", L"2007-11-06"); book2.insert_or_assign(L"price", 10.50); book2.insert_or_assign(L"isbn", L"0802143415"); // Use insert_or_assign again, but more efficiently wjson book3; // Reserve memory, to avoid reallocations book3.reserve(6); // Insert in name alphabetical order // Give insert_or_assign a hint where to insert the next member auto hint = book3.insert_or_assign(book3.object_range().begin(), L"author", L"Haruki Murakami"); hint = book3.insert_or_assign(hint, L"category", L"Fiction"); hint = book3.insert_or_assign(hint, L"date", L"2006-01-03"); hint = book3.insert_or_assign(hint, L"isbn", L"1400079276"); hint = book3.insert_or_assign(hint, L"price", 13.45); hint = book3.insert_or_assign(hint, L"title", L"Kafka on the Shore"); // Construct a fourth from a string wjson book4 = wjson::parse(LR"( { "category" : "Fiction", "title" : "Pulp", "author" : "Charles Bukowski", "date" : "2004-07-08", "price" : 22.48, "isbn" : "1852272007" } )"); // Construct a booklist array wjson booklist(json_array_arg); // For efficiency, reserve memory, to avoid reallocations booklist.reserve(4); // For efficency, tell jsoncons to move the contents // of the four book objects into the array booklist.add(std::move(book1)); booklist.add(std::move(book2)); // Add the third book to the front auto pos = booklist.add(booklist.array_range().begin(),std::move(book3)); // and the last one immediately after booklist.add(pos+1,std::move(book4)); // See what's left of book1, 2, 3 and 4 (expect nulls) std::wcout << book1 << L"," << book2 << L"," << book3 << L"," << book4 << '\n'; ++ //Loop through the booklist elements using a range-based for loop for (const auto& book : booklist.array_range()) { std::wcout << book[L"title"].as() << L"," << book[L"price"].as() << '\n'; } // The second book wjson& book = booklist[1]; //Loop through the book's name-value pairs using a range-based for loop for (const auto& member : book.object_range()) { std::wcout << member.key() << L"," << member.value() << '\n'; } auto it = book.find(L"author"); if (it != book.object_range().end()) { // member "author" found } if (book.contains(L"author")) { // book has a member "author" } book.get(L"author", L"author unknown").as(); // Returns author if found, otherwise "author unknown" try { book[L"ratings"].as(); } catch (const std::out_of_range& e) { // member "ratings" not found } // Add ratings book[L"ratings"][L"*****"] = 4; book[L"ratings"][L"*"] = 2; // Delete one-star ratings book[L"ratings"].erase(L"*"); ``` ```cpp // Serialize the booklist to a file std::wofstream os("booklist2.json"); os << pretty_print(booklist); ``` ### wjson query ```cpp // Deserialize the booklist std::wifstream is("booklist2.json"); wjson booklist; is >> booklist; // Use a JSONPath expression to find // // (1) The authors of books that cost less than $12 wjson result = json_query(booklist, L"$[*][?(@.price < 12)].author"); std::wcout << result << '\n'; // (2) The number of books result = json_query(booklist, L"$.length"); std::wcout << result << '\n'; // (3) The third book result = json_query(booklist, L"$[2]"); std::wcout << pretty_print(result) << '\n'; // (4) The authors of books that were published in 2004 result = json_query(booklist, L"$[*][?(@.date =~ /2004.*?/)].author"); std::wcout << result << '\n'; // (5) The titles of all books that have ratings result = json_query(booklist, L"$[*][?(@.ratings)].title"); std::wcout << result << '\n'; // (6) All authors and titles of books result = json_query(booklist, L"$..['author','title']"); std::wcout << pretty_print(result) << '\n'; ``` Result: ```json (1) ["Haruki Murakami","George Crile"] (2) [4] (3) [ { "author":"Haruki Murakami", "category":"Fiction", "date":"2002-04-09", "isbn":"037571894X", "price":9.01, "title":"A Wild Sheep Chase: A Novel" } ] (4) ["Charles Bukowski"] (5) ["Pulp"] (6) [ "Nigel Rees", "Sayings of the Century", "Evelyn Waugh", "Sword of Honour", "Herman Melville", "Moby Dick", "J. R. R. Tolkien", "The Lord of the Rings" ] ``` jsoncons-1.3.2/doc/Tutorials/Unicode support.md000066400000000000000000000122021477700171100215130ustar00rootroot00000000000000### Narrow character support for UTF8 encoding In the Linux and web worlds, `UTF-8` is the dominant character encoding. Note that (at least in MSVS) you cannot open a Windows file with a Unicode name using the standard ```cpp std::fstream fs(const char* filename) ``` Instead you need to use the non standard Microsoft extension ```cpp std::fstream fs(const wchar_t* filename) ``` #### Unicode escaping ```cpp string inputStr("[\"\\u0040\\u0040\\u0000\\u0011\"]"); std::cout << "Input: " << inputStr << '\n'; json arr = json::parse(inputStr); std::string str = arr[0].as(); std::cout << "Hex dump: ["; for (std::size_t i = 0; i < str.size(); ++i) { unsigned int val = static_cast(str[i]); if (i != 0) { std::cout << " "; } std::cout << "0x" << std::setfill('0') << std::setw(2) << std::hex << val; } std::cout << "]" << '\n'; std::ostringstream os; os << arr; std::cout << "Output: " << os.str() << '\n'; ``` Output: ``` Input: ["\u0040\u0040\u0000\u0011"] Hex dump: [0x40 0x40 0x00 0x11] Output: ["@@\u0000\u0011"] ``` Note that just the two control characters are escaped on output. #### Reading escaped unicode into utf8 encodings and writing back escaped unicode ```cpp string inputStr("[\"\\u007F\\u07FF\\u0800\"]"); std::cout << "Input: " << inputStr << '\n'; json arr = json::parse(inputStr); std::string s = arr[0].as(); std::cout << "Hex dump: ["; for (std::size_t i = 0; i < s.size(); ++i) { if (i != 0) std::cout << " "; unsigned int u(s[i] >= 0 ? s[i] : 256 + s[i] ); std::cout << "0x" << std::hex<< std::setfill('0') << std::setw(2) << u; } std::cout << "]" << '\n'; std::ostringstream os; auto options = json_options{} .escape_all_non_ascii(true); os << print(arr,options); std::string outputStr = os.str(); std::cout << "Output: " << os.str() << '\n'; json arr2 = json::parse(outputStr); std::string s2 = arr2[0].as(); std::cout << "Hex dump: ["; for (std::size_t i = 0; i < s2.size(); ++i) { if (i != 0) std::cout << " "; unsigned int u(s2[i] >= 0 ? s2[i] : 256 + s2[i] ); std::cout << "0x" << std::hex<< std::setfill('0') << std::setw(2) << u; } std::cout << "]" << '\n'; ``` Output: ``` Input: ["\u007F\u07FF\u0800"] Hex dump: [0x7f 0xdf 0xbf 0xe0 0xa0 0x80] Output: ["\u007F\u07FF\u0800"] Hex dump: [0x7f 0xdf 0xbf 0xe0 0xa0 0x80] ``` Since the escaped unicode consists of a control character (0x7f) and non-ascii, we get back the same text as what we started with. #### Reading escaped unicode into utf8 encodings and writing back escaped unicode (with continuations) ```cpp string input = "[\"\\u8A73\\u7D30\\u95B2\\u89A7\\uD800\\uDC01\\u4E00\"]"; json value = json::parse(input); auto options = json_options{} .escape_all_non_ascii(true); string output; value.dump(output,options); std::cout << "Input:" << '\n'; std::cout << input << '\n'; std::cout << '\n'; std::cout << "Output:" << '\n'; std::cout << output << '\n'; ``` Since all of the escaped unicode is non-ascii, we get back the same text as what we started with. ``` Input: ["\u8A73\u7D30\u95B2\u89A7\uD800\uDC01\u4E00"] Output: ["\u8A73\u7D30\u95B2\u89A7\uD800\uDC01\u4E00"] ``` ### Wide character support for UTF16 and UTF32 encodings jsoncons supports wide character strings with `wjson`. It assumes `UTF16` encoding if `wchar_t` has size 2 (Windows) and `UTF32` encoding if `wchar_t` has size 4. It is necessary to deal with UTF-16 character encoding in the Windows world because of lack of UTF-8 support in the Windows system API. Even if you choose to use wide character streams and strings to interact with the Windows API, you can still read and write to files in the more widely supported, endiness independent, UTF-8 format. To handle that you need to imbue your streams with the facet `std::codecvt_utf8_utf16`, which encapsulates the conversion between `UTF-8` and `UTF-16`. Note that (at least in MSVS) you cannot open a Windows file with a Unicode name using the standard std::wfstream fs(const char* filename) Instead you need to use the non standard Microsoft extension std::wfstream fs(const wchar_t* filename) #### Constructing a wjson value ```cpp using jsoncons::wjson; wjson j; j[L"field1"] = L"test"; j[L"field2"] = 3.9; j[L"field3"] = true; std::wcout << j << L"\n"; ``` Output: ``` {"field1":"test","field2":3.9,"field3":true} ``` #### Escaped unicode ```cpp wstring input = L"[\"\\u007F\\u07FF\\u0800\"]"; std::wistringstream is(input); wjson val = wjson::parse(is); wstring s = val[0].as(); std::cout << "length=" << s.length() << '\n'; std::cout << "Hex dump: ["; for (std::size_t i = 0; i < s.size(); ++i) { if (i != 0) std::cout << " "; uint32_t u(s[i] >= 0 ? s[i] : 256 + s[i] ); std::cout << "0x" << std::hex<< std::setfill('0') << std::setw(2) << u; } std::cout << "]" << '\n'; std::wofstream os("output/xxx.txt"); os.imbue(std::locale(os.getloc(), new std::codecvt_utf8_utf16)); auto options = wjson_options{} .escape_all_non_ascii(true); os << pretty_print(val,options) << L"\n"; ``` Output: ``` length=3 Hex dump: [0x7f 0x7ff 0x800] ``` and the file `xxx.txt` contains ``` ["\u007F\u07FF\u0800"] ``` jsoncons-1.3.2/doc/build.md000066400000000000000000000002361477700171100155450ustar00rootroot00000000000000Start Visual Studio Command prompt for x64 mkdir build64 & pushd build64 cmake -G "Visual Studio 14 2015 Win64" .. popd cmake --build build64 --config Debug jsoncons-1.3.2/doc/ref/000077500000000000000000000000001477700171100146775ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/bson/000077500000000000000000000000001477700171100156405ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/bson/basic_bson_cursor.md000066400000000000000000000205631477700171100216670ustar00rootroot00000000000000### jsoncons::bson::basic_bson_cursor ```cpp #include template< typename Source=jsoncons::binary_stream_source, typename Allocator=std::allocator> class basic_bson_cursor; ``` A pull parser for reporting BSON parse events. A typical application will repeatedly process the `current()` event and call the `next()` function to advance to the next event, until `done()` returns `true`. In addition, when positioned on a `begin_object` event, the `read_to` function can pull a complete object representing the events from `begin_object` to `end_object`, and when positioned on a `begin_array` event, a complete array representing the events from `begin_array` ro `end_array`. `basic_bson_cursor` is noncopyable and nonmoveable. Aliases for common sources are provided: Type |Definition --------------------|------------------------------ bson_stream_cursor |basic_bson_cursor bson_bytes_cursor |basic_bson_cursor ### Implemented interfaces [staj_cursor](staj_cursor.md) #### Constructors template basic_bson_cursor(Sourceable&& source, const bson_decode_options& options = bson_decode_options(), const Allocator& alloc = Allocator()); (1) template basic_bson_cursor(Sourceable&& source, std::error_code& ec); (2) template basic_bson_cursor(Sourceable&& source, const bson_decode_options& options, std::error_code& ec); (3) template basic_bson_cursor(std::allocator_arg_t, const Allocator& alloc, Sourceable&& source, const bson_decode_options& options, std::error_code& ec); (4) Constructors (1) reads from a buffer or stream source and throws a [ser_error](ser_error.md) if a parsing error is encountered while processing the initial event. Constructors (2)-(4) read from a buffer or stream source and set `ec` if a parsing error is encountered while processing the initial event. Note: It is the programmer's responsibility to ensure that `basic_bson_cursor` does not outlive any source passed in the constuctor, as `basic_bson_cursor` holds a pointer to but does not own this object. #### Parameters `source` - a value from which a `source_type` is constructible. #### Member functions bool done() const override; Checks if there are no more events. const staj_event& current() const override; Returns the current [staj_event](basic_staj_event.md). void read_to(json_visitor& visitor) override Feeds the current and succeeding [staj events](basic_staj_event.md) through the provided [visitor](basic_json_visitor.md), until the visitor indicates to stop. If a parsing error is encountered, throws a [ser_error](ser_error.md). void read_to(json_visitor& visitor, std::error_code& ec) override Feeds the current and succeeding [staj events](basic_staj_event.md) through the provided [visitor](basic_json_visitor.md), until the visitor indicates to stop. If a parsing error is encountered, sets `ec`. void next() override; Advances to the next event. If a parsing error is encountered, throws a [ser_error](ser_error.md). void next(std::error_code& ec) override; Advances to the next event. If a parsing error is encountered, sets `ec`. const ser_context& context() const override; Returns the current [context](ser_context.md) void reset(); Reset cursor to read another value from the same source template reset(Sourceable&& source) Reset cursor to read new value from a new source #### Non-member functions template staj_filter_view operator|(basic_bson_cursor& cursor, std::function pred); ### Examples Input JSON file `book_catalog.json`: ```json [ { "author" : "Haruki Murakami", "title" : "Hard-Boiled Wonderland and the End of the World", "isbn" : "0679743464", "publisher" : "Vintage", "date" : "1993-03-02", "price": 18.90 }, { "author" : "Graham Greene", "title" : "The Comedians", "isbn" : "0099478374", "publisher" : "Vintage Classics", "date" : "2005-09-21", "price": 15.74 } ] ``` #### Read BSON parse events ```cpp #include #include #include using namespace jsoncons; int main() { std::ifstream is("book_catalog.json"); bson_cursor cursor(is); for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: std::cout << event.event_type() << "\n"; break; case staj_event_type::end_array: std::cout << event.event_type() << "\n"; break; case staj_event_type::begin_object: std::cout << event.event_type() << "\n"; break; case staj_event_type::end_object: std::cout << event.event_type() << "\n"; break; case staj_event_type::key: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::string_value: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::null_value: std::cout << event.event_type() << ": " << "\n"; break; case staj_event_type::bool_value: std::cout << event.event_type() << ": " << std::boolalpha << event.get() << "\n"; break; case staj_event_type::int64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::double_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; default: std::cout << "Unhandled event type\n"; break; } } } ``` Output: ``` begin_array begin_object key: author string_value: Haruki Murakami key: title string_value: Hard-Boiled Wonderland and the End of the World key: isbn string_value: 0679743464 key: publisher string_value: Vintage key: date string_value: 1993-03-02 key: price double_value: 19 end_object begin_object key: author string_value: Graham Greene key: title string_value: The Comedians key: isbn string_value: 0099478374 key: publisher string_value: Vintage Classics key: date string_value: 2005-09-21 key: price double_value: 16 end_object end_array ``` #### Filter BSON parse events ```cpp #include #include #include using namespace jsoncons; int main() { bool author_next = false; auto filter = [&](const staj_event& event, const ser_context&) -> bool { if (event.event_type() == staj_event_type::key && event.get() == "author") { author_next = true; return false; } if (author_next) { author_next = false; return true; } return false; }; std::ifstream is("book_catalog.json"); bson_cursor cursor(is); auto filtered_c = cursor | filter; for (; !filtered_c.done(); filtered_c.next()) { const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::string_value: std::cout << event.get() << "\n"; break; } } } ``` Output: ``` Haruki Murakami Graham Greene ``` ### See also [staj_event](../basic_staj_event.md) [staj_array_iterator](../staj_array_iterator.md) [staj_object_iterator](../staj_object_iterator.md) jsoncons-1.3.2/doc/ref/bson/basic_bson_encoder.md000066400000000000000000000312261477700171100217670ustar00rootroot00000000000000### jsoncons::bson::basic_bson_encoder ```cpp #include template< typename Sink> > class basic_bson_encoder : public jsoncons::json_visitor ``` `basic_bson_encoder` is noncopyable. ![basic_bson_encoder](./diagrams/basic_bson_encoder.png) Two specializations for common sink types are defined: Type |Definition ---------------------------|------------------------------ bson_stream_encoder |basic_bson_encoder bson_bytes_encoder |basic_bson_encoder>> #### Member types Type |Definition ---------------------------|------------------------------ char_type |char sink_type |Sink string_view_type | #### Constructors explicit basic_bson_encoder(Sink&& sink) Constructs a new encoder that writes to the specified destination. #### Destructor virtual ~basic_bson_encoder() noexcept #### Member functions void reset(); Reset encoder to write another value to the same sink void reset(Sink&& sink) Reset encoder to write a new value to a new sink #### Inherited from [jsoncons::basic_json_visitor](basic_json_visitor.md) void flush(); (1) bool begin_object(semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (2) bool begin_object(std::size_t length, semantic_tag tag=semantic_tag::none, const ser_context& context = ser_context()); (3) bool end_object(const ser_context& context = ser_context()); (4) bool begin_array(semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (5) bool begin_array(std::size_t length, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (6) bool end_array(const ser_context& context=ser_context()); (7) bool key(const string_view_type& name, const ser_context& context=ser_context()); (8) bool null_value(semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (9) bool bool_value(bool value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (10) bool string_value(const string_view_type& value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (11) bool byte_string_value(const byte_string_view& source, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (12) (until 0.152.0) template bool byte_string_value(const ByteStringLike& souce, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (12) (since 0.152.0) template bool byte_string_value(const ByteStringLike& souce, uint64_t ext_tag, const ser_context& context=ser_context()); (13) (since 0.152.0) bool uint64_value(uint64_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (14) bool int64_value(int64_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (15) bool half_value(uint16_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (16) bool double_value(double value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (17) bool begin_object(semantic_tag tag, const ser_context& context, std::error_code& ec); (18) bool begin_object(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec); (19) bool end_object(const ser_context& context, std::error_code& ec); (20) bool begin_array(semantic_tag tag, const ser_context& context, std::error_code& ec); (21) bool begin_array(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec); (22) bool end_array(const ser_context& context, std::error_code& ec); (23) bool key(const string_view_type& name, const ser_context& context, std::error_code& ec); (24) bool null_value(semantic_tag tag, const ser_context& context, std::error_code& ec); (25) bool bool_value(bool value, semantic_tag tag, const ser_context& context, std::error_code& ec); (26) bool string_value(const string_view_type& value, semantic_tag tag, const ser_context& context, std::error_code& ec); (27) bool byte_string_value(const byte_string_view& source, semantic_tag tag, const ser_context& context, std::error_code& ec); (28) (until 0.152.0) template bool byte_string_value(const ByteStringLike& source, semantic_tag tag, const ser_context& context, std::error_code& ec); (28) (since 0.152.0) template bool byte_string_value(const ByteStringLike& source, uint64_t ext_tag, const ser_context& context, std::error_code& ec); (29) (since 0.152.0) bool uint64_value(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (30) bool int64_value(int64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (31) bool half_value(uint16_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (32) bool double_value(double value, semantic_tag tag, const ser_context& context, std::error_code& ec); (33) template bool typed_array(const span& data, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (34) bool typed_array(half_arg_t, const span& s, semantic_tag tag = semantic_tag::none, const ser_context& context = ser_context()); (35) bool begin_multi_dim(const span& shape, semantic_tag tag, const ser_context& context); (36) bool end_multi_dim(const ser_context& context=ser_context()); (37) template bool typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (38) bool typed_array(half_arg_t, const span& s, semantic_tag tag, const ser_context& context, std::error_code& ec); (39) bool begin_multi_dim(const span& shape, semantic_tag tag, const ser_context& context, std::error_code& ec); (40) bool end_multi_dim(const ser_context& context, std::error_code& ec); (41) (1) Flushes whatever is buffered to the destination. (2) Indicates the begining of an object of indefinite length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (3) Indicates the begining of an object of known length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (4) Indicates the end of an object. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (5) Indicates the beginning of an indefinite length array. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (6) Indicates the beginning of an array of known length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (7) Indicates the end of an array. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (8) Writes the name part of an object name-value pair. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (9) Writes a null value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (10) Writes a boolean value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (11) Writes a text string value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (12) Writes a byte string value `source` with a generic tag. Type `ByteStringLike` must be a container that has member functions `data()` and `size()`, and member type `value_type` with size exactly 8 bits (since 0.152.0.) Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (13) Writes a byte string value `source` with a format specific tag, `ext_tag`. Type `ByteStringLike` must be a container that has member functions `data()` and `size()`, and member type `value_type` with size exactly 8 bits (since 0.152.0.) Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (14) Writes a non-negative integer value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (15) Writes a signed integer value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (16) Writes a half precision floating point value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (17) Writes a double precision floating point value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (18)-(33) Same as (2)-(17), except sets `ec` and returns `false` on parse errors. ### Examples #### Encode to BSON ```cpp #include #include #include int main() { std::vector buffer; bson::bson_bytes_encoder encoder(buffer); encoder.begin_array(); // The total number of bytes comprising // the bson document will be calculated encoder.string_value("cat"); std::vector purr = {'p','u','r','r'}; encoder.byte_string_value(purr, 7); encoder.int64_value(1431027667, semantic_tag::epoch_second); encoder.end_array(); encoder.flush(); std::cout << byte_string_view(buffer) << "\n\n"; /* 23000000 -- Total number of bytes comprising the document (35 bytes) 02 -- UTF-8 string 3000 -- "0" 04000000 -- number bytes in the string (including trailing byte) 636174 -- "cat" 00 -- trailing byte 05 -- binary 3100 -- "1" 04000000 -- number of bytes 07 -- subtype 70757272 -- 'P','u','r','r' 09 -- datetime 3200 -- "2" d3bf4b55 -- 1431027667 00 */ } ``` Output: ``` 23,00,00,00,02,30,00,04,00,00,00,63,61,74,00,05,31,00,04,00,00,00,07,70,75,72,72,09,32,00,d3,bf,4b,55,00 ``` ### See also [byte_string_view](../byte_string_view.md) jsoncons-1.3.2/doc/ref/bson/bson.md000066400000000000000000000206631477700171100171320ustar00rootroot00000000000000### bson extension The bson extension implements decode from and encode to the [Binary JSON](http://bsonspec.org/) data format. You can either parse into or serialize from a variant-like data structure, [basic_json](../basic_json.md), or your own data structures, using [json_type_traits](../json_type_traits.md). [decode_bson](decode_bson.md) [basic_bson_cursor](basic_bson_cursor.md) [encode_bson](encode_bson.md) [basic_bson_encoder](basic_bson_encoder.md) [bson_options](bson_options.md) #### Mappings between BSON and jsoncons data items BSON data item | jsoncons data item |jsoncons semantic_tag ---------------------------------|---------------|------------ null | null | true or false | bool | int32 or int64 | int64 | int32 or int64 | uint64 | UTC datetime | int64 | epoch_milli Timestamp | uint64 | double | double | string | string | binary | byte_string | ext array | array | embedded document | object | decimal128 (since 0.165.0) | string | float128 ObjectId (since 0.165.0) | string | id regex (since 0.165.0) | string | regex JavaScript code (since 0.165.0) | string | code min_key (since 0.165.0) | string | max_key (since 0.165.0) | string | undefined (since 0.165.0) | null | undefined symbol (since 0.165.0) | string | ### Examples [Document with string and binary](#eg1) [Decode a BSON 128-bit decimal floating point (since 0.165.0)](#eg2) [Encode a BSON 128-bit decimal floating point (since 0.165.0)](#eg3) [Regular expression data (since 0.165.0)](#eg4) [ObjectId data (since 0.165.0)](#eg5)
#### Document with string and binary ```cpp #include #include #include using jsoncons::json; namespace bson = jsoncons::bson; // for brevity int main() { // Create some bson std::vector buffer; bson::bson_bytes_encoder encoder(buffer); encoder.begin_object(); // The total number of bytes comprising // the bson document will be calculated encoder.key("Hello"); encoder.string_value("World"); encoder.key("Data"); std::vector bstr = {'f','o','o','b','a','r'}; encoder.byte_string_value(bstr); // default subtype is user defined // or encoder.byte_string_value(bstr, 0x80); encoder.end_object(); encoder.flush(); std::cout << "(1)\n" << jsoncons::byte_string_view(buffer) << "\n"; /* 0x27,0x00,0x00,0x00, // Total number of bytes comprising the document (40 bytes) 0x02, // URF-8 string 0x48,0x65,0x6c,0x6c,0x6f, // Hello 0x00, // trailing byte 0x06,0x00,0x00,0x00, // Number bytes in string (including trailing byte) 0x57,0x6f,0x72,0x6c,0x64, // World 0x00, // trailing byte 0x05, // binary 0x44,0x61,0x74,0x61, // Data 0x00, // trailing byte 0x06,0x00,0x00,0x00, // number of bytes 0x80, // subtype 0x66,0x6f,0x6f,0x62,0x61,0x72, 0x00 */ ojson j = bson::decode_bson(buffer); std::cout << "(2)\n" << pretty_print(j) << "\n\n"; std::cout << "(3) " << j["Data"].tag() << "(" << j["Data"].ext_tag() << ")\n\n"; // Get binary value as a std::vector auto bstr2 = j["Data"].as>(); assert(bstr2 == bstr); std::vector buffer2; bson::encode_bson(j, buffer2); assert(buffer2 == buffer); } ``` Output: ``` (1) 27,00,00,00,02,48,65,6c,6c,6f,00,06,00,00,00,57,6f,72,6c,64,00,05,44,61,74,61,00,06,00,00,00,80,66,6f,6f,62,61,72,00 (2) { "Hello": "World", "Data": "Zm9vYmFy" } (3) ext(128) ```
#### Decode a BSON 128-bit decimal floating point (since 0.165.0) ```cpp #include #include #include using jsoncons::json; namespace bson = jsoncons::bson; // for brevity int main() { std::vector input = { 0x18,0x00,0x00,0x00, // Document has 24 bytes 0x13, // 128-bit decimal floating point 0x61,0x00, // "a" 0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, // 1E-6176 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00 // terminating null }; json j = bson::decode_bson(input); std::cout << "(1) " << j << "\n\n"; std::cout << "(2) " << j.at("a").tag() << "\n\n"; std::vector output; bson::encode_bson(j, output); assert(output == input); } ``` Output: ``` (1) {"a":"1E-6176"} (2) float128 ```
#### Encode a BSON 128-bit decimal floating point (since 0.165.0) ```cpp #include #include #include using jsoncons::json; namespace bson = jsoncons::bson; // for brevity int main() { json j; j.try_emplace("a", "1E-6176", jsoncons::semantic_tag::float128); // or j["a"] = json("1E-6176", jsoncons::semantic_tag::float128); std::cout << "(1) " << j << "\n\n"; std::cout << "(2) " << j.at("a").tag() << "\n\n"; std::vector output; bson::encode_bson(j, output); std::cout << "(3) " << jsoncons::byte_string_view(output) << "\n\n"; /* 18,00,00,00, // document has 24 bytes 13, // 128-bit decimal floating point 13,00, // "a" 01,00,00,00, 00,00,00,00, // 1E-6176 00,00,00,00, 00,00,00,00, 00 // terminating null */ } ``` Output: ``` (1) {"a":"1E-6176"} (2) float128 (3) 18,00,00,00,13,61,00,01,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 ```
#### Regular expression data (since 0.165.0) ```cpp #include #include #include using jsoncons::json; namespace bson = jsoncons::bson; // for brevity int main() { std::vector input = { 0x16,0x00,0x00,0x00, // Document has 22 bytes 0x0B, // Regular expression 0x72,0x65,0x67,0x65,0x78,0x00, // "regex" 0x5E,0x61,0x62,0x63,0x64,0x00, // "^abcd" 0x69,0x6C,0x78,0x00, // "ilx" 0x00 // terminating null }; json j = bson::decode_bson(input); std::cout << "(1) " << j << "\n\n"; std::cout << "(2) " << j.at("regex").tag() << "\n\n"; std::vector output; bson::encode_bson(j, output); assert(output == input); } ``` Output: ``` (1) {"regex":"/^abcd/ilx"} (2) regex ```
#### ObjectId data (since 0.165.0) ```cpp #include #include #include using jsoncons::json; namespace bson = jsoncons::bson; // for brevity int main() { std::vector input = { 0x16,0x00,0x00,0x00, // Document has 22 bytes 0x07, // ObjectId 0x6F,0x69,0x64,0x00, // "oid" 0x12,0x34,0x56,0x78,0x90,0xAB, 0xCD,0xEF,0x12,0x34,0xAB,0xCD, // (byte*12) 0x00 // terminating null }; json j = bson::decode_bson(input); std::cout << "(1) " << j << "\n\n"; std::cout << "(2) " << j.at("oid").tag() << "\n\n"; std::vector output; bson::encode_bson(j, output); assert(output == input); } ``` Output: ``` (1) {"oid":"1234567890abcdef1234abcd"} (2) id ``` ### See also [byte_string_view](../byte_string_view.md) ### Acknowledgements The jsoncons implementations of BSON decimal128 to and from string, and ObjectId to and from string, are based on the Apache 2 licensed [libbson](https://github.com/mongodb/mongo-c-driver/tree/master/src/libbson). The decimal128, regex, and ObjectId examples are from the libbson test cases. jsoncons-1.3.2/doc/ref/bson/bson_options.md000066400000000000000000000011301477700171100206710ustar00rootroot00000000000000### jsoncons::bson::bson_options ```cpp #include class bson_options; ```
![bson_options](./diagrams/bson_options.png) Specifies options for reading and writing CBOR. #### Constructors bson_options() Constructs a `bson_options` with default values. #### Modifiers void max_nesting_depth(int depth) The maximum nesting depth allowed when decoding and encoding BSON. Default is 1024. Parsing can have an arbitrarily large depth limited only by available memory. Serializing a [basic_json](../basic_json.md) to BSON is limited by stack size. jsoncons-1.3.2/doc/ref/bson/decode_bson.md000066400000000000000000000076641477700171100204430ustar00rootroot00000000000000### jsoncons::bson::decode_bson Decodes a [Binary JSON (BSON)](http://bsonspec.org/) data format into a C++ data structure. ```cpp #include template T decode_bson(const std::vector& source, const bson_decode_options& options = bson_decode_options()); (1) (until 0.152.0) template T decode_bson(const Source& source, const bson_decode_options& options = bson_decode_options()); (1) (since 0.152.0) template T decode_bson(std::istream& is, const bson_decode_options& options = bson_decode_options()); (2) template T decode_bson(InputIt first, InputIt last, const bson_decode_options& options = bson_decode_options()); (3) (since 0.153.0) template T decode_bson(const allocator_set& alloc_set, const Source& source, const bson_decode_options& options = bson_decode_options()); (4) (since 0.171.0) template T decode_bson(const allocator_set& alloc_set, std::istream& is, const bson_decode_options& options = bson_decode_options()); (5) (since 0.171.0) ``` (1) Reads BSON data from a contiguous byte sequence provided by `source` into a type T, using the specified (or defaulted) [options](bson_options.md). Type `Source` must be a container that has member functions `data()` and `size()`, and member type `value_type` with size exactly 8 bits (since 0.152.0.) Any of the values types `int8_t`, `uint8_t`, `char`, `unsigned char` and `std::byte` (since C++17) are allowed. Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). (2) Reads BSON data from a binary stream into a type T, using the specified (or defaulted) [options](bson_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). (3) Reads BSON data from the range [`first`,`last`) into a type T, using the specified (or defaulted) [options](bson_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). Functions (4)-(5) are identical to (1)-(2) except an [allocator_set](../allocator_set.md) is passed as an additional argument and provides allocators for result data and temporary allocations. #### Exceptions Throws a [ser_error](../ser_error.md) if parsing fails, and a [conv_error](conv_error.md) if type conversion fails. ### Examples #### Binary example ```cpp #include #include #include int main() { std::vector input = { 0x13,0x00,0x00,0x00, // Document has 19 bytes 0x05, // Binary data 0x70,0x44,0x00, // "pD" 0x05,0x00,0x00,0x00, // Length is 5 0x80, // Subtype is 128 0x48,0x65,0x6c,0x6c,0x6f, // 'H','e','l','l','o' 0x00 // terminating null }; json j = bson::decode_bson(input); std::cout << "JSON:\n" << pretty_print(j) << "\n\n"; std::cout << "tag: " << j["pD"].tag() << "\n"; std::cout << "ext_tag: " << j["pD"].ext_tag() << "\n"; auto bytes = j["pD"].as>(); std::cout << "binary data: " << byte_string_view{ bytes } << "\n"; } ``` Output: ``` JSON: { "pD": "SGVsbG8" } tag: ext ext_tag: 128 binary data: 48,65,6c,6c,6f ``` Note that printing a json value by default encodes byte strings as base64url strings, but the json value holds the actual bytes. ### See also [encode_bson](encode_bson.md) encodes a json value to the [Binary JSON](http://bsonspec.org/) data format. jsoncons-1.3.2/doc/ref/bson/diagrams/000077500000000000000000000000001477700171100174275ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/bson/diagrams/basic_bson_encoder.png000066400000000000000000000122051477700171100237360ustar00rootroot00000000000000PNG  IHDRUep7tEXtmxfile%3Cmxfile%20modified%3D%222020-03-31T16%3A26%3A20.274Z%22%20host%3D%22app.diagrams.net%22%20agent%3D%225.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F80.0.3987.149%20Safari%2F537.36%22%20etag%3D%22YPSwSI1lBYFNS_8yHi3v%22%20version%3D%2212.9.6%22%20type%3D%22device%22%3E%3Cdiagram%20id%3D%22iK-0d-7Yl-5MlnfMu26I%22%20name%3D%22Page-1%22%3EzVZNc9owEP01PqZjW5DCMQGStgyZpnQGcsoIa2OrlSUqCzD99ZWwhC3bTJKZHJpLtG%2B1%2BnjvrUyAJnl5L%2FE2WwgCLIhDUgZoGsRxFKKR%2FmeQY4UMxhZIJSV2Ug0s6V9wlRbdUQKFN1EJwRTd%2BmAiOIdEeRiWUhz8aS%2BC%2BbtucQodYJlg1kVXlKisQkfDsMa%2FAE0zt3MU2kyO3WQLFBkm4tCA0CxAEymEqkZ5OQFmyHO8VHV3F7Lng0ng6i0Fs4efJZ8%2FLrN48meuVov8qfx2ZVfZY7azF97ggibPvwrBn%2Fe0oErIIL5meofbjRmlZmQvpI6OJSl2nIDZKNTpQ0YVLLc4MdmD9oXGMpUzHUXn6ubB3SlAKigbkL3IPYgclDzqKTY7spxaU0WO40MtUTSwWNaQx2HYuiI9r1wTpweWu3fw%2BPkCjxvDI%2FBE90Uvjx%2FL7AtlbCKYlszUIjj9abxQUvyGRgZdozEiH6PF%2FyfGqCNGh1bg5Ma8DjpKGC60VD6TUFK1tqSb8ZMZfxraaFo2UtOjC7g%2B%2FNotYIJGlQnrslPk6i5qUIidTOB11yksU1CvdzkQ763rKtpQbNgjmMMkMKzo3n8h%2B1S0O3wXVN%2FsbJiB75cYtXxQXdsWNR%2B01jrjlu9GrXUqWjrrnCx1vvSbXJbuF1k8f1jjH5BerR7nsJ9DT8t%2F5RlIqjDXoukvHsWpxHnHerqtlG82vz254NDqZQthRlNuHKuNop8TdGualOpv1Y1N5JQQs03vO%2BG%2FJB%2FQ%2BFGr8eOwp%2FFRj4%2Fi9ze%2BDusvZaVg%2FXsDzf4B%3C%2Fdiagram%3E%3C%2Fmxfile%3E[,IDATx^_Ǘܘ) MBM$rp.\pt.\(Q?#~3c'Ō"5N7%s\I"7FyޞY{w2Yk}ڟY?c~H ϒfA1 rzp#0h ,nH?IoOmJ5>Z,%ZBɡx'@zGZ)ҟc0wjNJlAR%@rE@4J#kjxCTh} REqJZZ1Q?z\t8p 2$!W~:t9rČ1"X?~0;w4/6ӦM޴_98z9sLr; 2R|J5~RTY?(EC5N2g2ϟ?UV;w؀;v0[l_#:x`*_byY|ylXZWWgΝ;gikk3 .lmc\gϞ^vL8ќ?ތ7.#\i7o޴ٶ… MopE%Sͳhnhŋ}ğ]L5[bPE`x~z>}dm6sa p-l2{l֭[ۭw̘1$޽{gJ >J#gϬ 2c5jTP#$<8 Ÿ\b޾}kc ?=oѣ['R +ORz^T]ov~s{_zUV*l" k:_L,0xqkn9CoҤI}jz]]]AV3I%JJ5Wre|ݚ+Fن"BCRW II(۰\ f\1rJ-Kv+t^!rK|3e1SqI1bqTdZUUUAobTQaKU@6WQp>Y쯄w .vs SQQ_׽|455fƍ65cƌln~mqhnǎ3cǎ5K,ޗ\f/_l?%t"HM l?Q|iPCj6(5Uں,q j߿jQWSՂ#U7=>$t|~8 ɓ'۾0:K!6ڑqܺuˊTu8q}Rlۣv%Y)A\L5+< K镖Ly,ED\8i%4^gNŤd?*~Xq!kvٺK?^E"!Y-Ep jBK VjujHUj#G ->}:8QS-TeQoOL#H2}J8a A!ksOZQ1Ns8ЦDaJ!Q%U-W~N5*`}(T}u48IcT $()Յclř4d8cFT8+SRTA s|TWRe:v,j,LHTH Ց5J5kdPe4پJ"8HR-Y-(fTTS=}yJu`tT1O%`gFRM؄;jf}(@Oqj']/8JKJ#GRDzl"Qe3h(-j?@D?{z-9H ~;$2Hr @ @JkH<T=d( THH#J#L" JkH<T=d( THH#J#L" JkH<T=d( THH#J#L" JkH<T=d( THH#J#L" JkH<T=d( THH#J#L" JkH<T=d( THH#J#L" JkH<T=d( THH#J#L" JkH<T=d( THH#J#L" JkH<T=d( THH#J#L" JkH<T=d( THH#J#L" JkH<T=d( THH#J#́m֭[g#K{MKKʩ߿77n4˖-3&LnN xSGG{9pٹs3rH 7jnsW1b8qTTTiEJ5A˭f555юl߾}H:uTi&SWWg.]d73gδ^@Lx!^OO\|,Zĩ6K,1omwzݻdŋͳgςv!İRx̙cz{{XnҥK8pСC͛Efi|kkkinn,ʗJ5 XI4L'vZ+D -[X9M{ݻwL}}9yb@s_5k QJL~O };v2eJh!Cb'O"Ko!{ #:㖇Q;WuI\?E&UyߡS 쭽Jڵk)fIŭmҗ>,ܟ~}`vHUNhI LbLTS>aRo~}P[`;w9wh%^&[l)/ fv̥}ْ![|݃*A!)cǎ&w|jPOz8!|IUgl2-Ql*[g ŕyL5?.8*TEdᄲFQnHF۔j2!^-(V7+UѣA]1*S k pK.ZYY]ZrXM5JG演KFJ5SCi;H(l/{Ǐ):^8G (f:mOkuhfTI{Rj@ׯAMUouI"(Ք{l}ҥKUUlΞ=]Ƨkv'<R9rڱcGѩS… pyĉJ|OvIe͛7QF v\똜 b:>{O"g7nhr]rJg7mڤ,YƌElG&obŋZ%|___KLwސ(0a ׯ뱍pA&ζgZ2OVNr0"E!fmܹ3nNڵk>qDس~zm۶BێE@4HQ |@,ȻvQ4gΜA!yv-@Gd jTBDИRY9sL:dzpo֭߮[7*h߯+.E)!)ڒ=EIvRqlQD=RnRW}G/B&("; [ ^#Qd7Zە 5viT(VX]]!" ϶ jٮ~m]yMGDmtz3yU\³3[E>3PvLI;פEw_B=~XK_~-q$Or@C P)"+ PW1ԉ((᥌_YF=}TΝ;Z͘1CW͛:A (ŒM(*|Eʍ=FMĠCEZ^c~-G-DL8q@@)DY t*|E b dǏϜGn*J CKQl0G݊!DQߦ"i\t#Ì5@)z@YbQR݊"c}GUD1C"( )ZȻaPYv B%@ PBő?e{Y(26O>D7eKѸqv DaPT-Ed_vV)tS6;+XS.DQ<G %E=@U(2.wTq0QF3C"3OE6sv\CN ]kJ;0 ]+DQwM!D}M"CɟlY3g*̀R/Wc"&.D|/uS6gP9" M Q)j.B7Qd(̊vDQ|1c+Cɠȑ@!_;/oh(aJ@ 4QTELw F;w$/:uj( 凩C[k(bo MISvnʞ7o|y +@$ɾ<C!d 6N #_kKU#"˸b$@x|;j^DòQVb(4X﨩iRDQ=b(4';y]}1G#Qipbh2' }GҔ-4e/Yv꺯j"2U<C!5&y >E)y (B/MUu_l }垗}@ U2&@;*$6Qmڵn#w$MٿK5ZF1XiEd$no!r @U}G:!(stz@ E.8 Jw}tґ2!vضm7no~3b܁"PV1.ȏ8ɛ_|^y5~x駟|F dq QmXK1 QT FI#y'?Q>}C  $;A^pA Rw Xsw,^6oެݫF]%p=b m ԪUԢEԬYJaҶ}]o>u}-~]vիW}}} "}GU.mݺUM4I-X@;wN:tH޽[1v2iԢhɝ0GEJ~_ϿaĐ#KN'w(ʎ-V53t-fΜӟ2e:va5QQg֟KRTRjƍыf#oiӦ˗oy.>RoU5|}ܹsՑ#GtL搊G=}MRO4OGvء6˗/of+vU4%d?ꫯZ<7?Oꗿej'wT(J_f ᑶNv~A-Zy)pB='NlUo4ٳgq5jToڙU&CWHį~+@ 3ghs uu}ׯWݻwx5k/^|#ew m̻rJg5f̘W_}U Jx{DIlzX"e.9Lٝ,5J*2ʕ+VG>Oڙv^qȊ$~ɓ'CN"@>M6L5kD%n%%-Ruu!=o=4Yv9h=5\'`ڵC,QuNW v4QdgNrQ|8g +ou<g?Y({Dp$B'neb%7xu@;γzC(_|1oF̃Vva`@e_eo-ȬeW_>"YDQseg&S}vnݺ֎}_k5^mQTF\J"")d)$ )*R7 Ϯu<Qd1[f :Kf;03 Ty󻊝izeġ]?Wsϩ_JO+AhRd?deLzN2=&㏈"[G$ i:Jٕ"aWM򂓬PE"[vZ)++YJnNw+W)*xyb,ƮO%;ϟ?_鳬K.g ]yC"D]S!fe?{3> )Sd?}DᲣN%ƶ=}̼yA)4.u\)rsB~US̪7&kGUgL@h]ֳsC})^"[&ʫ4)Vo=l@ouN!z*&3y_رco!*C b.B.x~y S+Eչu8#:8r!}eli<G=8 H￯>l2gƍ׺6*%(o܃u@ŝGx"r\S?DQ̣(Q"PVˤe\ cLU<GѥC @B.9@U8y M-@UB.X9@U6y O5DBiCuu@ 8, /d58<X2R@S7 4/Bm=DQ !@7 4/B9DQ츲 _n#R~!y٢7r}V)NQTW88r A&~!CͫiΦ֙\E%@* T1lWc"䇓EfB.t9BI 3{Fwqo%愐/ yb̫&L'_Q*%~83ER#9?3fi*5AQu/ȷEۀa&K$D M2(A `BuhZɜ:'t/y/"5hJ5yiC|_5^(TBnq"W <@ruE*-LQT3p @]E.`#_LҥKu4B_@ZDU:Z@1I-j !xBQI 0#LU*0Icu*~!r.Fϥ([Uȕ4zC|_țbHCE g$P8*kMx$m\tI7O/DnNQ{%G.r8Šʗ[ngm.^j;v~b&(0GMSq(:m ;/˗/WWO>2BsA$E7%PT!Wh'E!;hACBE{ (j:sFKUEZJ-ZH͚5+*ΝS[nUGQGwsҤIjJl8tڽ{1bDm6M_V?j$*L"DQQ G" ,,/׮]SӧOW_pJz6>DQ1ă dNDѴiԾ}˗ÇuCjlܸQeaիWsmU[DhݻWsQcǎɓ't<۾gj~Qr'^S)gϞ!Rɳ[*@#GT;vh1:uZpC8O8U)I.i̱yf5jԨ!Վkj|:u9y5sLuI]5 x@ )vڥ,378{Zrڳgl`6mRK,QcƌѢIAD<$B-YZb*ͨ{qDpqO~d"l{iXYF~O0yH[vܙj\'tڵCx8q@8_^m۶v^{M]rE=ydPD}W~v@6D⨨(3gΠU  ҋ#_BӱK6=,iY&*#euE|-3gδC.>E8$E[hjݺuޮ݆TllQi*(=z1NWŋk E3ڮd{Ls-TBb -8)WQd h5[o5dKVyݶPX`Z$\vH*HR32K -" [$_˹"A( <ɯvF-"( 0"Jيs rJ-d{hUŲEY."ʆ #DQQg Y'͛ .U<מ"[TFƐ}5ݧco?~<7 B>Hה]oƝe"C2"V! DQY:EgYOqO6{<"{t4&O:3]f3[E>3P6mӧOk'\B똜 b:>{OE4j7o3 _"@AI-rʍ =FMEMD9!,DQ|Eop ‰FDE.`*RDlEy "_DQP05,rĺ Oɗ2(2a(`X`0̍\q.K,;DQ^`2,Ex (anXsY^/ed ba(`X`E s "G|)$NQ{࿗X F/ކ#( ,`8\KY$'v3$"eX5|64DQ`8""MEhq. @ % @3T@ (" @"r }F2@ @ 9@># @M" SD@ g  @QD@ *E @h`d @l @3r }F@ =E @ @P)" @ @T@ "@># @g @` @6z@ @O9@RD&@ D9@ @E3 }F@ @ 9@l @"r <#@L @"r P)" @@g$ @` @l @3r )" УݻVX6oެ&OիW9{UGÇժUԢEԫ4oGuxё#Gԙ3gպu봝fp4.zW#_Sٰ]3@F޽[1Ω (`a*Ʉ t%OmܸQeae*E3gTWVSLQǎkUΝ;fϞYta!W_sǏ7|S֮]wYo߾b8IDATϻyZrڳg"DXemk̙c˛ĦI&T{0JDȴiӴ>flEdmDleߟs{ƒ!AE$z@(2⾽@KСCZ8qBm'F\\{\fl@m0Vv%~|rȼEdgƐ1}b܂@!B8HEF $o:)d >Ν>]Q2剢ٞ1Řli%MY)h->DlܹSO%lQ(,(y(KA%֓ 9UUIҥR$׈(2H-p' z"8Evoݘ~dU0رcG&R6x(VdoFd٢^h%{zDQ"~J!?D1BtD Q|Kdq7""m̈ksT:Y()3{ؓ~%<>SZ)2v'~߫Gdd߶z3{K/?DQGiEVLFTC{!l"@@yw "(8% @m H@ B @QD@ g {.H2IENDB`jsoncons-1.3.2/doc/ref/bson/encode_bson.md000066400000000000000000000133051477700171100204420ustar00rootroot00000000000000### jsoncons::bson::encode_bson Encodes a C++ data structure to the [Binary JSON (BSON)](http://bsonspec.org/) data format. ```cpp #include template void encode_bson(const T& jval, ByteContainer& cont, const bson_decode_options& options = bson_decode_options()); (1) template void encode_bson(const T& jval, std::ostream& os, const bson_decode_options& options = bson_decode_options()); (2) template void encode_bson(const allocator_set& alloc_set, const T& jval, ByteContainer& cont, const bson_decode_options& options = bson_decode_options()); (3) (since 0.171.0) template void encode_bson(const allocator_set& alloc_set, const T& jval, std::ostream& os, const bson_decode_options& options = bson_decode_options()); (4) (since 0.171.0) ``` (1) Writes a value of type T into a byte container in the BSON data format, using the specified (or defaulted) [options](bson_options.md). Type 'T' must be an instantiation of [basic_json](basic_json.md) or support [json_type_traits](../json_type_traits.md). Type `ByteContainer` must be back insertable and have member type `value_type` with size exactly 8 bits (since 0.152.0.) Any of the values types `int8_t`, `uint8_t`, `char`, `unsigned char` and `std::byte` (since C++17) are allowed. (2) Writes a value of type T into a binary stream in the BSON data format, using the specified (or defaulted) [options](bson_options.md). Type 'T' must be an instantiation of [basic_json](basic_json.md) or support [json_type_traits](../json_type_traits.md). Functions (3)-(4) are identical to (1)-(2) except an [allocator_set](../allocator_set.md) is passed as an additional argument. ### Examples #### null ```cpp void null_example() { json j; j.try_emplace("hello", null_type()); std::vector buffer; bson::encode_bson(j, buffer); std::cout << byte_string_view(buffer) << "\n\n"; } ``` Output: ``` 0c,00,00,00,0a,68,65,6c,6c,6f,00,00 ``` #### bool ```cpp int main() { std::map m{ {"a", true} }; std::vector buffer; bson::encode_bson(m, buffer); std::cout << byte_string_view(buffer) << "\n\n"; } ``` Output: ``` 09,00,00,00,08,61,00,01,00 ``` #### int32 ```cpp int main() { ojson j(json_object_arg); j.try_emplace("a", -123); // int32 j.try_emplace("c", 0); // int32 j.try_emplace("b", 123); // int32 std::vector buffer; bson::encode_bson(j, buffer); std::cout << byte_string_view(buffer) << "\n\n"; } ``` Output: ``` 1a,00,00,00,10,61,00,85,ff,ff,ff,10,63,00,00,00,00,00,10,62,00,7b,00,00,00,00 ``` #### int64 ```cpp int main() { std::map m{ {"a", 100000000000000ULL} }; std::vector buffer; bson::encode_bson(m, buffer); std::cout << byte_string_view(buffer) << "\n\n"; } ``` Output: ``` 10,00,00,00,12,61,00,00,40,7a,10,f3,5a,00,00,00 ``` #### double ```cpp int main() { std::map m{ {"a", 123.4567} }; std::vector buffer; bson::encode_bson(m, buffer); std::cout << byte_string_view(buffer) << "\n\n"; } ``` Output: ``` 10,00,00,00,01,61,00,53,05,a3,92,3a,dd,5e,40,00 ``` #### utf8 string ```cpp int main() { json j; j.try_emplace("hello", "world"); std::vector buffer; bson::encode_bson(j, buffer); std::cout << byte_string_view(buffer) << "\n\n"; } ``` Output: ``` 16,00,00,00,02,68,65,6c,6c,6f,00,06,00,00,00,77,6f,72,6c,64,00,00 ``` #### binary ```cpp int main() { json j; std::vector bstr = {'1', '2', '3', '4'}; j.try_emplace("binary", byte_string_arg, bstr); // default subtype is user defined // or j.try_emplace("binary", byte_string_arg, bstr, 0x80); std::vector buffer; bson::encode_bson(j, buffer); std::cout << byte_string_view(buffer) << "\n\n"; } ``` Output: ``` 16,00,00,00,05,62,69,6e,61,72,79,00,04,00,00,00,80,31,32,33,34,00 ``` #### array ```cpp int main() { json a(json_array_arg); a.push_back("hello"); a.push_back("world"); json j(json_object_arg); j["array"] = std::move(a); std::vector buffer; bson::encode_bson(j, buffer); std::cout << byte_string_view(buffer) << "\n\n"; } ``` Output: ``` 2b,00,00,00,04,61,72,72,61,79,00,1f,00,00,00,02,30,00,06,00,00,00,68,65,6c,6c,6f,00,02,31,00,06,00,00,00,77,6f,72,6c,64,00,00,00 ``` #### UTC datetime ```cpp #include #include #include int main() { auto duration = std::chrono::system_clock::now().time_since_epoch(); auto time = std::chrono::duration_cast(duration); json j; j.try_emplace("time", time); auto milliseconds = j["time"].as(); std::cout << "Time since epoch (milliseconds): " << milliseconds.count() << "\n\n"; auto seconds = j["time"].as(); std::cout << "Time since epoch (seconds): " << seconds.count() << "\n\n"; std::vector data; bson::encode_bson(j, data); std::cout << "BSON bytes:\n" << jsoncons::byte_string_view(data) << "\n\n"; /* 13,00,00,00, // document has 19 bytes 09, // UTC datetime 74,69,6d,65,00, // "time" ea,14,7f,96,73,01,00,00, // 1595957777642 00 // terminating null */ } ``` Output: ``` Time since epoch (milliseconds): 1595957777642 Time since epoch (seconds): 1595957777 BSON bytes: 13,00,00,00,09,74,69,6d,65,00,ea,14,7f,96,73,01,00,00,00 ``` ### See also [decode_bson](decode_bson) decodes a [Binary JSON](http://bsonspec.org/) data format to a json value. jsoncons-1.3.2/doc/ref/cbor/000077500000000000000000000000001477700171100156245ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/cbor/basic_cbor_cursor.md000066400000000000000000000344731477700171100216440ustar00rootroot00000000000000### jsoncons::cbor::basic_cbor_cursor ```cpp #include template< typename Source=jsoncons::binary_stream_source, typename Allocator=std::allocator> class basic_cbor_cursor; ``` A pull parser for reporting CBOR parse events. A typical application will repeatedly process the `current()` event and call the `next()` function to advance to the next event, until `done()` returns `true`. In addition, when positioned on a `begin_object` event, the `read_to` function can pull a complete object representing the events from `begin_object` to `end_object`, and when positioned on a `begin_array` event, a complete array representing the events from `begin_array` ro `end_array`. `basic_cbor_cursor` is noncopyable and nonmoveable. Aliases for common sources are provided: Type |Definition --------------------|------------------------------ cbor_stream_cursor |basic_cbor_cursor cbor_bytes_cursor |basic_cbor_cursor ### Implemented interfaces [staj_cursor](staj_cursor.md) #### Constructors basic_cbor_cursor(Sourceable&& source, const cbor_decode_options& options = cbor_decode_options(), const Allocator& alloc = Allocator()); (1) template basic_cbor_cursor(Sourceable&& source, std::error_code& ec); (2) template basic_cbor_cursor(Sourceable&& source, const cbor_decode_options& options, std::error_code& ec); (3) template basic_cbor_cursor(std::allocator_arg_t, const Allocator& alloc, Sourceable&& source, const cbor_decode_options& options, std::error_code& ec); (4) Constructors (1) reads from a buffer or stream source and throws a [ser_error](ser_error.md) if a parsing error is encountered while processing the initial event. Constructors (2)-(4) read from a buffer or stream source and set `ec` if a parsing error is encountered while processing the initial event. Note: It is the programmer's responsibility to ensure that `basic_cbor_cursor` does not outlive any source passed in the constuctor, as `basic_cbor_cursor` holds a pointer to but does not own this object. #### Parameters `source` - a value from which a `source_type` is constructible. #### Member functions uint64_t raw_tag() const; // (since 1.2.0) Returns the CBOR tag associated with the current value bool done() const override; Checks if there are no more events. const staj_event& current() const override; Returns the current [staj_event](basic_staj_event.md). void read_to(json_visitor& visitor) override Feeds the current and succeeding [staj events](basic_staj_event.md) through the provided [visitor](basic_json_visitor.md), until the visitor indicates to stop. If a parsing error is encountered, throws a [ser_error](ser_error.md). void read_to(json_visitor& visitor, std::error_code& ec) override Feeds the current and succeeding [staj events](basic_staj_event.md) through the provided [visitor](basic_json_visitor.md), until the visitor indicates to stop. If a parsing error is encountered, sets `ec`. void next() override; Advances to the next event. If a parsing error is encountered, throws a [ser_error](ser_error.md). void next(std::error_code& ec) override; Advances to the next event. If a parsing error is encountered, sets `ec`. const ser_context& context() const override; Returns the current [context](ser_context.md) void reset(); Reset cursor to read another value from the same source template reset(Sourceable&& source) Reset cursor to read new value from a new sources #### Non-member functions template staj_filter_view operator|(basic_cbor_cursor& cursor, std::function pred); ### Examples Input JSON file `book_catalog.json`: ```json [ { "author" : "Haruki Murakami", "title" : "Hard-Boiled Wonderland and the End of the World", "isbn" : "0679743464", "publisher" : "Vintage", "date" : "1993-03-02", "price": 18.90 }, { "author" : "Graham Greene", "title" : "The Comedians", "isbn" : "0099478374", "publisher" : "Vintage Classics", "date" : "2005-09-21", "price": 15.74 } ] ``` #### Read CBOR parse events ```cpp #include #include #include using namespace jsoncons; int main() { std::ifstream is("book_catalog.json"); cbor_cursor cursor(is); for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: std::cout << event.event_type() << "\n"; break; case staj_event_type::end_array: std::cout << event.event_type() << "\n"; break; case staj_event_type::begin_object: std::cout << event.event_type() << "\n"; break; case staj_event_type::end_object: std::cout << event.event_type() << "\n"; break; case staj_event_type::key: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::string_value: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::null_value: std::cout << event.event_type() << ": " << "\n"; break; case staj_event_type::bool_value: std::cout << event.event_type() << ": " << std::boolalpha << event.get() << "\n"; break; case staj_event_type::int64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::half_value: case staj_event_type::double_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; default: std::cout << "Unhandled event type\n"; break; } } } ``` Output: ``` begin_array begin_object key: author string_value: Haruki Murakami key: title string_value: Hard-Boiled Wonderland and the End of the World key: isbn string_value: 0679743464 key: publisher string_value: Vintage key: date string_value: 1993-03-02 key: price double_value: 19 end_object begin_object key: author string_value: Graham Greene key: title string_value: The Comedians key: isbn string_value: 0099478374 key: publisher string_value: Vintage Classics key: date string_value: 2005-09-21 key: price double_value: 16 end_object end_array ``` #### Filter CBOR parse events ```cpp #include #include #include using namespace jsoncons; int main() { bool author_next = false; auto filter = [&](const staj_event& event, const ser_context&) -> bool { if (event.event_type() == staj_event_type::key && event.get() == "author") { author_next = true; return false; } if (author_next) { author_next = false; return true; } return false; }; std::ifstream is("book_catalog.json"); cbor_cursor cursor(is); auto filtered_c = cursor | filter; for (; !filtered_c.done(); filtered_c.next()) { const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::string_value: std::cout << event.get() << "\n"; break; } } } ``` Output: ``` Haruki Murakami Graham Greene ``` ### Typed Array examples #### Read a typed array ```cpp #include #include #include #include #include struct my_cbor_visitor : public default_json_visitor { std::vector v; private: bool visit_typed_array(const span& data, semantic_tag, const ser_context&, std::error_code&) override { v = std::vector(data.begin(),data.end()); return false; } }; int main() { std::vector v{10.0,20.0,30.0,40.0}; std::vector buffer; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(v, buffer, options); std::cout << "(1)\n"; std::cout << byte_string_view(buffer) << "\n\n"; /* 0xd8, // Tag 0x56, // Tag 86, float64, little endian, Typed Array 0x58,0x20, // Byte string value of length 32 0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x40, 0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x40, 0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x40, 0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x40 */ cbor::cbor_bytes_cursor cursor(buffer); assert(cursor.current().event_type() == staj_event_type::begin_array); assert(cursor.is_typed_array()); my_cbor_visitor visitor; cursor.read_to(visitor); std::cout << "(2)\n"; for (auto item : handler.v) { std::cout << item << "\n"; } std::cout << "\n"; } ``` Output: ``` (1) d8 56 58 20 00 00 00 00 00 00 24 40 00 00 00 00 00 00 34 40 00 00 00 00 00 00 3e 40 00 00 00 00 00 00 44 40 (2) 10 20 30 40 ``` #### Navigating Typed Arrays with cursor - multi-dimensional row major with typed array This example is taken from [CBOR Tags for Typed Arrays](https://tools.ietf.org/html/rfc8746) ```cpp #include int main() { const std::vector input = { 0xd8,0x28, // Tag 40 (multi-dimensional row major array) 0x82, // array(2) 0x82, // array(2) 0x02, // unsigned(2) 1st Dimension 0x03, // unsigned(3) 2nd Dimension 0xd8,0x41, // Tag 65 (uint16 big endian Typed Array) 0x4c, // byte string(12) 0x00,0x02, // unsigned(2) 0x00,0x04, // unsigned(4) 0x00,0x08, // unsigned(8) 0x00,0x04, // unsigned(4) 0x00,0x10, // unsigned(16) 0x01,0x00 // unsigned(256) }; cbor::cbor_bytes_cursor cursor(input); for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::end_array: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; default: std::cout << "Unhandled event type " << event.event_type() << " " << "(" << event.tag() << ")\n"; break; } } } ``` Output: ``` begin_array (multi-dim-row-major) begin_array (n/a) uint64_value: 2 (n/a) uint64_value: 3 (n/a) end_array (n/a) begin_array (n/a) uint64_value: 2 (n/a) uint64_value: 4 (n/a) uint64_value: 8 (n/a) uint64_value: 4 (n/a) uint64_value: 10 (n/a) uint64_value: 100 (n/a) end_array (n/a) end_array (n/a) ``` #### Navigating Typed Arrays with cursor - multi-dimensional column major with classical CBOR array This example is taken from [CBOR Tags for Typed Arrays](https://tools.ietf.org/html/rfc8746) ```cpp #include int main() { const std::vector input = { 0xd9,0x04,0x10, // Tag 1040 (multi-dimensional column major array) 0x82, // array(2) 0x82, // array(2) 0x02, // unsigned(2) 1st Dimension 0x03, // unsigned(3) 2nd Dimension 0x86, // array(6) 0x02, // unsigned(2) 0x04, // unsigned(4) 0x08, // unsigned(8) 0x04, // unsigned(4) 0x10, // unsigned(16) 0x19,0x01,0x00 // unsigned(256) }; cbor::cbor_bytes_cursor cursor(input); for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::end_array: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; default: std::cout << "Unhandled event type " << event.event_type() << " " << "(" << event.tag() << ")\n"; break; } } } ``` Output: ``` begin_array (multi-dim-column-major) begin_array (n/a) uint64_value: 2 (n/a) uint64_value: 3 (n/a) end_array (n/a) begin_array (n/a) uint64_value: 2 (n/a) uint64_value: 4 (n/a) uint64_value: 8 (n/a) uint64_value: 4 (n/a) uint64_value: 10 (n/a) uint64_value: 100 (n/a) end_array (n/a) end_array (n/a) ``` ### See also [staj_event](../basic_staj_event.md) [staj_array_iterator](staj_array_iterator.md) [staj_object_iterator](staj_object_iterator.md) jsoncons-1.3.2/doc/ref/cbor/basic_cbor_encoder.md000066400000000000000000000436601477700171100217440ustar00rootroot00000000000000### jsoncons::cbor::basic_cbor_encoder ```cpp #include template< typename Sink> > class basic_cbor_encoder final : public json_visitor ``` `basic_cbor_encoder` is noncopyable ![basic_cbor_encoder](./diagrams/basic_cbor_encoder.png) Four specializations for common sink types are defined: Type |Definition ---------------------------|------------------------------ cbor_stream_encoder |basic_cbor_encoder cbor_bytes_encoder |basic_cbor_encoder>> #### Member types Type |Definition ---------------------------|------------------------------ char_type |char sink_type |Sink string_view_type | #### Constructors explicit basic_cbor_encoder(Sink&& sink) Constructs a new encoder that writes to the specified destination. #### Destructor virtual ~basic_cbor_encoder() noexcept #### Member functions void reset(); Reset encoder to write another value to the same sink void reset(Sink&& sink) Reset encoder to write a new value to a new sink void begin_object_with_tag(uint64_t raw_tag); // (since 1.2.0) void begin_object_with_tag(std::size_t length, uint64_t raw_tag); // (since 1.2.0) void begin_array_with_tag(uint64_t raw_tag); // (since 1.2.0) void begin_array_with_tag(std::size_t length, uint64_t raw_tag); // (since 1.2.0) void null_value_with_tag(uint64_t raw_tag); // (since 1.2.0) void bool_value_with_tag(bool value, uint64_t raw_tag); // (since 1.2.0) void string_value_with_tag(const string_view_type& value, uint64_t raw_tag); // (since 1.2.0) template void byte_string_value_with_tag(const ByteStringLike& value, uint64_t raw_tag); // (since 1.2.0) void double_value_with_tag(double value, uint64_t raw_tag); // (since 1.2.0) void uint64_value_with_tag(uint64_t value, uint64_t raw_tag); // (since 1.2.0) void int64_value_with_tag(int64_t value, uint64_t raw_tag); // (since 1.2.0) #### Inherited from [jsoncons::basic_json_visitor](../basic_json_visitor.md) void flush(); (1) bool begin_object(semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (2) bool begin_object(std::size_t length, semantic_tag tag=semantic_tag::none, const ser_context& context = ser_context()); (3) bool end_object(const ser_context& context = ser_context()); (4) bool begin_array(semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (5) bool begin_array(std::size_t length, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (6) bool end_array(const ser_context& context=ser_context()); (7) bool key(const string_view_type& name, const ser_context& context=ser_context()); (8) bool null_value(semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (9) bool bool_value(bool value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (10) bool string_value(const string_view_type& value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (11) bool byte_string_value(const byte_string_view& source, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (12) (until 0.152.0) template bool byte_string_value(const ByteStringLike & souce, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (12) (since 0.152.0) template bool byte_string_value(const ByteStringLike & souce, uint64_t ext_tag, const ser_context& context=ser_context()); (13) (since 0.152.0) bool uint64_value(uint64_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (14) bool int64_value(int64_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (15) bool half_value(uint16_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (16) bool double_value(double value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (17) bool begin_object(semantic_tag tag, const ser_context& context, std::error_code& ec); (18) bool begin_object(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec); (19) bool end_object(const ser_context& context, std::error_code& ec); (20) bool begin_array(semantic_tag tag, const ser_context& context, std::error_code& ec); (21) bool begin_array(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec); (22) bool end_array(const ser_context& context, std::error_code& ec); (23) bool key(const string_view_type& name, const ser_context& context, std::error_code& ec); (24) bool null_value(semantic_tag tag, const ser_context& context, std::error_code& ec); (25) bool bool_value(bool value, semantic_tag tag, const ser_context& context, std::error_code& ec); (26) bool string_value(const string_view_type& value, semantic_tag tag, const ser_context& context, std::error_code& ec); (27) bool byte_string_value(const byte_string_view& source, semantic_tag tag, const ser_context& context, std::error_code& ec); (28) (until 0.152.0) template bool byte_string_value(const Source& source, semantic_tag tag, const ser_context& context, std::error_code& ec); (28) (since 0.152.0) template bool byte_string_value(const Source& source, uint64_t ext_tag, const ser_context& context, std::error_code& ec); (29) (since 0.152.0) bool uint64_value(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (30) bool int64_value(int64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (31) bool half_value(uint16_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (32) bool double_value(double value, semantic_tag tag, const ser_context& context, std::error_code& ec); (33) template bool typed_array(const span& data, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (34) bool typed_array(half_arg_t, const span& s, semantic_tag tag = semantic_tag::none, const ser_context& context = ser_context()); (35) bool begin_multi_dim(const span& shape, semantic_tag tag, const ser_context& context); (36) bool end_multi_dim(const ser_context& context=ser_context()); (37) template bool typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (38) bool typed_array(half_arg_t, const span& s, semantic_tag tag, const ser_context& context, std::error_code& ec); (39) bool begin_multi_dim(const span& shape, semantic_tag tag, const ser_context& context, std::error_code& ec); (40) bool end_multi_dim(const ser_context& context, std::error_code& ec); (41) (1) Flushes whatever is buffered to the destination. (2) Indicates the begining of an object of indefinite length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (3) Indicates the begining of an object of known length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (4) Indicates the end of an object. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (5) Indicates the beginning of an indefinite length array. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (6) Indicates the beginning of an array of known length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (7) Indicates the end of an array. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (8) Writes the name part of an object name-value pair. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (9) Writes a null value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (10) Writes a boolean value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (11) Writes a text string value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (12) Writes a byte string value `source` with a generic tag. Type `Source` must be a container that has member functions `data()` and `size()`, and member type `value_type` with size exactly 8 bits (since 0.152.0.) Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (13) Writes a byte string value `source` with a format specific tag, `ext_tag`. Type `Source` must be a container that has member functions `data()` and `size()`, and member type `value_type` with size exactly 8 bits (since 0.152.0.) Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (14) Writes a non-negative integer value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (15) Writes a signed integer value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (16) Writes a half precision floating point value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (17) Writes a double precision floating point value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (18)-(33) Same as (2)-(17), except sets `ec` and returns `false` on parse errors. ### Examples [Encode to CBOR buffer](#eg1) [Encode to CBOR stream](#eg2) [Encode with raw CBOR tags (since 1.2.0)](#eg3) [Encode Typed Array tags - array of half precision floating-point](#eg4) [Encode Typed Array tags - multi-dimensional column major tag](#eg5)
#### Encode to CBOR buffer ```cpp #include #include #include int main() { std::vector buffer; cbor::cbor_bytes_encoder encoder(buffer); encoder.begin_array(); // Indefinite length array encoder.string_value("cat"); std::vector purr = {'p','u','r','r'}; encoder.byte_string_value(purr); std::vector hiss = {'h','i','s','s'}; encoder.byte_string_value(hiss, semantic_tag::base64); // suggested conversion to base64 encoder.int64_value(1431027667, semantic_tag::epoch_second); encoder.end_array(); encoder.flush(); std::cout << byte_string_view(buffer) << "\n\n"; /* 9f -- Start indefinte length array 63 -- String value of length 3 636174 -- "cat" 44 -- Byte string value of length 4 70757272 -- 'p''u''r''r' d6 - Expected conversion to base64 44 68697373 -- 'h''i''s''s' c1 -- Tag value 1 (seconds relative to 1970-01-01T00:00Z in UTC time) 1a -- 32 bit unsigned integer 554bbfd3 -- 1431027667 ff -- "break" */ } ``` Output: ``` 9f,63,63,61,74,44,70,75,72,72,d6,44,68,69,73,73,c1,1a,55,4b,bf,d3,ff ```
#### Encode to CBOR stream ```cpp #include #include #include int main() { std::ostringstream os; cbor::cbor_stream_encoder encoder(os); encoder.begin_array(3); // array of length 3 encoder.string_value("-18446744073709551617", semantic_tag::bigint); encoder.string_value("184467440737095516.16", semantic_tag::bigdec); encoder.int64_value(1431027667, semantic_tag::epoch_second); encoder.end_array(); encoder.flush(); std::cout << byte_string_view(os.str()) << "\n\n"; /* 83 -- array of length 3 c3 -- Tag 3 (negative bignum) 49 -- Byte string value of length 9 010000000000000000 -- Bytes content c4 -- Tag 4 (decimal fraction) 82 -- Array of length 2 21 -- -2 (exponent) c2 Tag 2 (positive bignum) 49 -- Byte string value of length 9 010000000000000000 c1 -- Tag 1 (seconds relative to 1970-01-01T00:00Z in UTC time) 1a -- 32 bit unsigned integer 554bbfd3 -- 1431027667 */ } ``` Output: ``` 83,c3,49,01,00,00,00,00,00,00,00,00,c4,82,21,c2,49,01,00,00,00,00,00,00,00,00,c1,1a,55,4b,bf,d3 ```
#### Encode with raw CBOR tags (since 1.2.0) ```cpp #include #include #include namespace cbor = jsoncons::cbor; int main() { std::vector data; cbor::cbor_bytes_encoder encoder(data); encoder.begin_array(1); encoder.uint64_value_with_tag(10, 0xC1); encoder.end_array(); encoder.flush(); cbor::cbor_bytes_cursor cursor(data); assert(cursor.current().event_type() == jsoncons::staj_event_type::begin_array); cursor.next(); assert(cursor.raw_tag() == 0xC1); assert(cursor.current().get() == 10); } ```
#### Encode Typed Array tags - array of half precision floating-point ```cpp #include #include #include int main() { std::vector buffer; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::cbor_bytes_encoder encoder(buffer, options); std::vector values = {0x3bff,0x3c00,0x3c01,0x3555}; encoder.typed_array(half_arg, values); // buffer contains a half precision floating-point, native endian, Typed Array std::cout << "(1)\n" << byte_string_view(buffer) << "\n\n"; auto j = cbor::decode_cbor(buffer); std::cout << "(2)\n"; for (auto item : j.array_range()) { std::cout << std::boolalpha << item.is_half() << " " << std::hex << (int)item.as() << " " << std::defaultfloat << item.as() << "\n"; } std::cout << "\n"; std::cout << "(3)\n" << pretty_print(j) << "\n\n"; } ``` Output ``` (1) d8 54 48 ff 3b 00 3c 01 3c 55 35 (2) true 3bff 0.999512 true 3c00 1 true 3c01 1.00098 true 3555 0.333252 (3) [ 0.99951171875, 1.0, 1.0009765625, 0.333251953125 ] ```
#### Encode Typed Array tags - multi-dimensional column major tag ```cpp #include #include int main() { std::vector v; cbor::cbor_bytes_encoder encoder(v); std::vector shape = { 2,3 }; encoder.begin_multi_dim(shape, semantic_tag::multi_dim_column_major); encoder.begin_array(6); encoder.uint64_value(2); encoder.uint64_value(4); encoder.uint64_value(8); encoder.uint64_value(4); encoder.uint64_value(16); encoder.uint64_value(256); encoder.end_array(); encoder.end_multi_dim(); std::cout << "(1)\n" << byte_string_view(v) << "\n\n"; auto j = cbor::decode_cbor(v); std::cout << "(2) " << j.tag() << "\n"; std::cout << pretty_print(j) << "\n\n"; } ``` Output: ``` (1) d9 04 10 82 82 02 03 86 02 04 08 04 10 19 01 00 (2) multi-dim-column-major [ [2, 3], [2, 4, 8, 4, 16, 256] ] ``` ### See also [byte_string_view](../byte_string_view.md) jsoncons-1.3.2/doc/ref/cbor/cbor.md000066400000000000000000000511351477700171100171000ustar00rootroot00000000000000## cbor extension The cbor extension implements decode from and encode to the IETF standard [Concise Binary Object Representation (CBOR)](http://cbor.io/). You can either parse into or serialize from a variant-like data structure, [basic_json](../basic_json.md), or your own data structures, using [json_type_traits](../json_type_traits.md). [decode_cbor](decode_cbor.md) [basic_cbor_cursor](basic_cbor_cursor.md) [encode_cbor](encode_cbor.md) [basic_cbor_encoder](basic_cbor_encoder.md) [cbor_options](cbor_options.md) ### Tag handling and extensions All tags not explicitly mentioned below are ignored. 0 (standard date/time string) CBOR standard date/time strings are decoded into jsoncons strings tagged with `semantic_tag::datetime`. jsoncons strings tagged with `semantic_tag::datetime` are encoded into CBOR standard date/time strings. 1 (epoch time) CBOR epoch times are decoded into jsoncons int64_t, uint64_t and double and tagged with `semantic_tag::epoch_second`. jsoncons int64_t, uint64_t and double tagged with `semantic_tag::epoch_second` are encoded into CBOR epoch time. 2,3 (positive and negative bignum) CBOR positive and negative bignums are decoded into jsoncons strings and tagged with `semantic_tag::bigint`. jsoncons strings tagged with `semantic_tag::bigint` are encoded into CBOR positive or negative bignums. 4 (decimal fratction) CBOR decimal fractions are decoded into jsoncons strings tagged with `semantic_tag::bigdec`. jsoncons strings tagged with `semantic_tag::bigdec` are encoded into CBOR decimal fractions. 5 (bigfloat) CBOR bigfloats are decoded into a jsoncons string that consists of the following parts - (optional) minus sign - 0x - nonempty sequence of hexadecimal digits (defines mantissa) - p followed with optional minus or plus sign and nonempty sequence of hexadecimal digits (defines base-2 exponent) and tagged with `semantic_tag::bigfloat`. jsoncons strings that consist of the following parts - (optional) plus or minus sign - 0x or 0X - nonempty sequence of hexadecimal digits optionally containing a decimal-point character - (optional) p or P followed with optional minus or plus sign and nonempty sequence of decimal digits and tagged with `semantic_tag::bigfloat` are encoded into CBOR bignums. 21, 22, 23 (byte string expected conversion is base64url, base64 or base16) CBOR byte strings tagged with 21, 22 and 23 are decoded into jsoncons byte strings tagged with `semantic_tag::base64url`, `semantic_tag::base64` and `semantic_tag::base16`. jsoncons byte strings tagged with `semantic_tag::base64url`, `semantic_tag::base64` and `semantic_tag::base16` are encoded into CBOR byte strings tagged with 21, 22 and 23. 32 (URI) CBOR URI strings are decoded into jsoncons strings tagged with `semantic_tag::uri`. jsoncons strings tagged with `semantic_tag::uri` are encoded into CBOR URI strings. 33, 34 (UTF-8 string is base64url or base64) CBOR strings tagged with 33 and 34 are decoded into jsoncons strings tagged with `semantic_tag::base64url` and `semantic_tag::base64`. jsoncons strings tagged with `semantic_tag::base64url` and `semantic_tag::base64` are encoded into CBOR strings tagged with 33 and 34. 256, 25 [stringref-namespace, stringref](http://cbor.schmorp.de/stringref) Tags 256 and 25 are automatically decoded when detected. They are encoded when CBOR option `pack_strings` is set to true. 64-87 [Tags for Typed Arrays](https://tools.ietf.org/html/rfc8746) Tags 64-82 (excepting float128 big endian) and 84-86 (excepting float128 little endian) are automatically decoded when detected. They may be encoded when CBOR option `use_typed_arrays` is set to true. #### Mappings between CBOR and jsoncons data items CBOR data item|CBOR tag | jsoncons data item|jsoncons tag ---------------|------------------------------------------------| --------------|------------------ null |  | null | undefined |  | null | undefined true or false |  | bool | unsigned or negative integer |  | int64 | unsigned or negative integer | 1 (epoch-based date/time) | int64 | seconds unsigned integer |  | uint64 | unsigned integer | 1 (epoch-based date/time) | uint64 | seconds half-precision float, float, or double |  | half | float or double |  | double | double | 1 (epoch-based date/time) | double | seconds string |  | string | byte string | 2 (positive bignum) or 2 (negative bignum) | string | bigint array | 4 (decimal fraction) | string | bigdec array | 5 (bigfloat) | string | bigfloat string | 0 (date/time string) | string | datetime string | 32 (uri) | string | uri string | 33 (base64url) | string | base64url string | 34 (base64) | string | base64 byte string |  | byte_string | byte string | 21 (Expected conversion to base64url encoding) | byte_string | base64url byte string | 22 (Expected conversion to base64 encoding) | byte_string | base64 byte string | 23 (Expected conversion to base16 encoding) | byte_string | base16 array |  | array | map |  | object | ## Examples [Working with CBOR data](#A1) [Encode and decode of a large typed array](#A2) [CBOR and basic_json](#A3) [Byte string with unknown CBOR tag (unknown to jsoncons)](#A4) [Query CBOR with JSONPath](#A5)
### Working with CBOR data For the examples below you need to include some header files and initialize a buffer of CBOR data: ```cpp #include #include #include #include #include using namespace jsoncons; // for convenience const std::vector data = { 0x9f, // Start indefinte length array 0x83, // Array of length 3 0x63, // String value of length 3 0x66,0x6f,0x6f, // "foo" 0x44, // Byte string value of length 4 0x50,0x75,0x73,0x73, // 'P''u''s''s' 0xc5, // Tag 5 (bigfloat) 0x82, // Array of length 2 0x20, // -1 0x03, // 3 0x83, // Another array of length 3 0x63, // String value of length 3 0x62,0x61,0x72, // "bar" 0xd6, // Expected conversion to base64 0x44, // Byte string value of length 4 0x50,0x75,0x73,0x73, // 'P''u''s''s' 0xc4, // Tag 4 (decimal fraction) 0x82, // Array of length 2 0x38, // Negative integer of length 1 0x1c, // -29 0xc2, // Tag 2 (positive bignum) 0x4d, // Byte string value of length 13 0x01,0x8e,0xe9,0x0f,0xf6,0xc3,0x73,0xe0,0xee,0x4e,0x3f,0x0a,0xd2, 0xff // "break" }; ``` jsoncons allows you to work with the CBOR data similarly to JSON data: - As a variant-like data structure, [basic_json](../basic_json.md) - As a strongly typed C++ data structure that implements [json_type_traits](../json_type_traits.md) - With [cursor-level access](doc/ref/cbor/basic_cbor_cursor.md) to a stream of parse events #### As a variant-like data structure ```cpp int main() { // Parse the CBOR data into a json value json j = cbor::decode_cbor(data); // Pretty print std::cout << "(1)\n" << pretty_print(j) << "\n\n"; // Iterate over rows std::cout << "(2)\n"; for (const auto& row : j.array_range()) { std::cout << row[1].as() << " (" << row[1].tag() << ")\n"; } std::cout << "\n"; // Select the third column with JSONPath std::cout << "(3)\n"; json result = jsonpath::json_query(j,"$[*][2]"); std::cout << pretty_print(result) << "\n\n"; // Serialize back to CBOR std::vector buffer; cbor::encode_cbor(j, buffer); std::cout << "(4)\n" << byte_string_view(buffer) << "\n\n"; } ``` Output: ``` (1) [ ["foo", "UHVzcw", "0x3p-1"], ["bar", "UHVzcw==", "1.23456789012345678901234567890"] ] (2) 50,75,73,73 (n/a) 50,75,73,73 (base64) (3) [ "0x3p-1", "1.23456789012345678901234567890" ] (4) 82,83,63,66,6f,6f,44,50,75,73,73,c5,82,20,03,83,63,62,61,72,d6,44,50,75,73,73,c4,82,38,1c,c2,4d,01,8e,e9,0f,f6,c3,73,e0,ee,4e,3f,0a,d2 ``` #### As a strongly typed C++ data structure ```cpp int main() { // Parse the string of data into a std::vector> value auto val = cbor::decode_cbor>>(data); std::cout << "(1)\n"; for (const auto& row : val) { std::cout << std::get<0>(row) << ", " << std::get<1>(row) << ", " << std::get<2>(row) << "\n"; } std::cout << "\n"; // Serialize back to CBOR std::vector buffer; cbor::encode_cbor(val, buffer); std::cout << "(2)\n" << byte_string_view(buffer) << "\n\n"; } ``` Output: ``` (1) foo, 50,75,73,73, 0x3p-1 bar, 50,75,73,73, 1.23456789012345678901234567890 (2) 82,9f,63,66,6f,6f,44,50,75,73,73,66,30,78,33,70,2d,31,ff,9f,63,62,61,72,44,50,75,73,73,78,1f,31,2e,32,33,34,35,36,37,38,39,30,31,32,33,34,35,36,37,38,39,30,31,32,33,34,35,36,37,38,39,30,ff ``` Note that when decoding the bigfloat and decimal fraction into a `std::string`, we lose the semantic information that the variant like data structure preserved with a tag, so serializing back to CBOR produces a text string. #### With cursor-level access ```cpp int main() { cbor::cbor_bytes_cursor cursor(data); for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::end_array: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::begin_object: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::end_object: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::key: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::string_value: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::byte_string_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::null_value: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::bool_value: std::cout << event.event_type() << ": " << std::boolalpha << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::int64_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::half_value: case staj_event_type::double_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; default: std::cout << "Unhandled event type " << event.event_type() << " " << "(" << event.tag() << ")\n"; break; } } } ``` Output: ``` begin_array (n/a) begin_array (n/a) string_value: foo (n/a) byte_string_value: 50,75,73,73 (n/a) string_value: 0x3p-1 (bigfloat) end_array (n/a) begin_array (n/a) string_value: bar (n/a) byte_string_value: 50,75,73,73 (base64) string_value: 1.23456789012345678901234567890 (bigdec) end_array (n/a) end_array (n/a) ``` You can apply a filter to a cursor using the pipe syntax, for example, ```cpp int main() { auto filter = [&](const staj_event& ev, const ser_context&) -> bool { return (ev.tag() == semantic_tag::bigdec) || (ev.tag() == semantic_tag::bigfloat); }; cbor::cbor_bytes_cursor cursor(data); auto filtered_c = cursor | filter; for (; !filtered_c.done(); filtered_c.next()) { const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::string_value: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; default: std::cout << "Unhandled event type " << event.event_type() << " " << "(" << event.tag() << ")\n"; break; } } } ``` Output: ``` string_value: 0x3p-1 (bigfloat) string_value: 1.23456789012345678901234567890 (bigdec) ```
### Encode and decode of a large typed array ```cpp #include #include #include using namespace jsoncons; int main() { std::vector x(15000000); for (std::size_t i = 0; i < x.size(); ++i) { x[i] = static_cast(i); } auto options = cbor::cbor_options{} .use_typed_arrays(true); std::vector buf; cbor::encode_cbor(x, buf, options); std::cout << "first 19 bytes:\n\n"; std::cout << byte_string_view(buf).substr(0, 19) << "\n\n"; /* 0xd8,0x55 -- Tag 85 (float32 little endian Typed Array) 0x5a - byte string (four-byte uint32_t for n, and then n bytes follow) 03 93 87 00 -- 60000000 00 00 00 00 -- 0.0f 00 00 80 3f -- 1.0f 00 00 00 40 -- 2.0f */ auto y = cbor::decode_cbor>(buf); assert(y == x); } ``` Output: ``` first 19 bytes: d8,55,5a,03,93,87,00,00,00,00,00,00,00,80,3f,00,00,00,40 ```
### CBOR and basic_json ```cpp #include #include #include using namespace jsoncons; int main() { ojson j1 = ojson::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 } ] } )"); // Encode a basic_json value to a CBOR value std::vector data; cbor::encode_cbor(j1, data); // Decode a CBOR value to a basic_json value ojson j2 = cbor::decode_cbor(data); std::cout << "(1)\n" << pretty_print(j2) << "\n\n"; // Accessing the data items const ojson& reputons = j2["reputons"]; std::cout << "(2)\n"; for (auto element : reputons.array_range()) { std::cout << element.at("rated").as() << ", "; std::cout << element.at("rating").as() << "\n"; } std::cout << '\n'; // Get a CBOR value for a nested data item with jsonpointer std::error_code ec; const auto& rated = jsonpointer::get(j2, "/reputons/0/rated", ec); if (!ec) { std::cout << "(3) " << rated.as_string() << "\n"; } std::cout << '\n'; } ``` Output: ``` (1) { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.9 } ] } (2) Marilyn C, 0.9 (3) Marilyn C ```
### Byte string with unknown CBOR tag (unknown to jsoncons) ```cpp #include #include int main() { // Create some CBOR std::vector buffer; cbor::cbor_bytes_encoder encoder(buffer); std::vector bstr = {'f','o','o','b','a','r'}; encoder.byte_string_value(bstr, 274); // byte string with tag 274 encoder.flush(); std::cout << "(1)\n" << byte_string_view(buffer) << "\n\n"; /* d9, // tag 01,12, // 274 46, // byte string, length 6 66,6f,6f,62,61,72 // 'f','o','o','b','a','r' */ json j = cbor::decode_cbor(buffer); std::cout << "(2)\n" << pretty_print(j) << "\n\n"; std::cout << "(3) " << j.tag() << "(" << j.ext_tag() << ")\n\n"; // Get byte string as a std::vector auto bstr2 = j.as>(); std::vector buffer2; cbor::encode_cbor(j, buffer2); std::cout << "(4)\n" << byte_string_view(buffer2.data(),buffer2.size()) << "\n"; } ``` Output: ``` (1) d9,01,12,46,66,6f,6f,62,61,72 (2) "Zm9vYmFy" (3) ext(274) (4) d9,01,12,46,66,6f,6f,62,61,72 ```
### Query CBOR with JSONPath ```cpp #include #include #include #include #include #include using namespace jsoncons; // For convenience int main() { // Construct a json array of numbers json j(json_array_arg); j.emplace_back(5.0); j.emplace_back(0.000071); j.emplace_back("-18446744073709551617",semantic_tag::bigint); j.emplace_back("1.23456789012345678901234567890", semantic_tag::bigdec); j.emplace_back("0x3p-1", semantic_tag::bigfloat); // Encode to JSON std::cout << "(1)\n"; std::cout << pretty_print(j); std::cout << "\n\n"; // as() and as() std::cout << "(2)\n"; std::cout << std::dec << std::setprecision(15); for (const auto& item : j.array_range()) { std::cout << item.as() << ", " << item.as() << "\n"; } std::cout << "\n"; // Encode to CBOR std::vector v; cbor::encode_cbor(j,v); std::cout << "(3)\n" << byte_string_view(v) << "\n\n"; /* 85 -- Array of length 5 fa -- float 40a00000 -- 5.0 fb -- double 3f129cbab649d389 -- 0.000071 c3 -- Tag 3 (negative bignum) 49 -- Byte string value of length 9 010000000000000000 c4 -- Tag 4 (decimal fraction) 82 -- Array of length 2 38 -- Negative integer of length 1 1c -- -29 c2 -- Tag 2 (positive bignum) 4d -- Byte string value of length 13 018ee90ff6c373e0ee4e3f0ad2 c5 -- Tag 5 (bigfloat) 82 -- Array of length 2 20 -- -1 03 -- 3 */ // Decode back to json json other = cbor::decode_cbor(v); assert(other == j); // Query with JSONPath std::cout << "(4)\n"; json result = jsonpath::json_query(other,"$[?(@ < 1.5)]"); std::cout << pretty_print(result) << "\n\n"; } ``` Output: ``` (1) [ 5.0, 7.1e-05, "-18446744073709551617", "1.23456789012345678901234567890", "0x3p-1" ] (2) 5.0, 5 7.1e-05, 7.1e-05 -18446744073709551617, -1.84467440737096e+19 1.23456789012345678901234567890, 1.23456789012346 0x3p-1, 1.5 (3) 85,fa,40,a0,00,00,fb,3f,12,9c,ba,b6,49,d3,89,c3,49,01,00,00,00,00,00,00,00,00,c4,82,38,1c,c2,4d,01,8e,e9,0f,f6,c3,73,e0,ee,4e,3f,0a,d2,c5,82,20,03 (4) [ 7.1e-05, "-18446744073709551617", "1.23456789012345678901234567890" ] ``` ### See also [byte_string_view](../byte_string_view.md) jsoncons-1.3.2/doc/ref/cbor/cbor_options.md000066400000000000000000000024741477700171100206550ustar00rootroot00000000000000### jsoncons::cbor::cbor_options ```cpp #include class cbor_options; ```
![cbor_options](./diagrams/cbor_options.png) Specifies options for reading and writing CBOR. #### Constructors cbor_options() Constructs a `cbor_options` with default values. #### Modifiers void max_nesting_depth(int depth) The maximum nesting depth allowed when decoding and encoding CBOR. Default is 1024. Parsing can have an arbitrarily large depth limited only by available memory. Serializing a [basic_json](../basic_json.md) to CBOR is limited by stack size. cbor_options& pack_strings(bool value) If set to `true`, then encode will store text strings and byte strings once, and use string references to represent repeated occurences of the strings. Decoding the resulting CBOR requires a decoder that supports the [stringref extension to CBOR](http://cbor.schmorp.de/stringref), such as jsoncons itself, or [Perl CBOR::XS](http://software.schmorp.de/pkg/CBOR-XS.html) If set to `false` (the default), then encode will encode strings the usual CBOR way. This option does not affect decode - jsoncons will always decode string references if present. cbor_options& use_typed_arrays(bool value) This option does not affect decode - jsoncons will always decode typed arrays if present. jsoncons-1.3.2/doc/ref/cbor/decode_cbor.md000066400000000000000000000236061477700171100204050ustar00rootroot00000000000000### jsoncons::cbor::decode_cbor ```cpp #include ```
Decodes a [Concise Binary Object Representation](http://cbor.io/) data format into a C++ data structure. ```cpp template T decode_cbor(const std::vector& source, const cbor_decode_options& options = cbor_decode_options()); (1) (until 0.152.0) template T decode_cbor(const Source& source, const cbor_decode_options& options = cbor_decode_options()); (1) (since 0.152.0) template T decode_cbor(std::istream& is, const cbor_decode_options& options = cbor_decode_options()); (2) template T decode_cbor(InputIt first, InputIt last, const cbor_decode_options& options = cbor_decode_options()); (3) (since 0.153.0) template T decode_cbor(const allocator_set& alloc_set, const Source& source, const cbor_decode_options& options = cbor_decode_options()); (4) (since 0.171.0) template T decode_cbor(const allocator_set& alloc_set, std::istream& is, const cbor_decode_options& options = cbor_decode_options()); (5) (since 0.171.0) ``` (1) Reads CBOR data from a contiguous byte sequence provided by `source` into a type T, using the specified (or defaulted) [options](cbor_options.md). Type `Source` must be a container that has member functions `data()` and `size()`, and member type `value_type` with size exactly 8 bits (since 0.152.0.) Any of the values types `int8_t`, `uint8_t`, `char`, `unsigned char` and `std::byte` (since C++17) are allowed. Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). (2) Reads CBOR data from a binary stream into a type T, using the specified (or defaulted) [options](cbor_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). (3) Reads CBOR data from the range [`first`,`last`) into a type T, using the specified (or defaulted) [options](cbor_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). Functions (4)-(5) are identical to (1)-(2) except an [allocator_set](../allocator_set.md) is passed as an additional argument and provides allocators for result data and temporary allocations. #### Exceptions Throws a [ser_error](../ser_error.md) if parsing fails, and a [conv_error](conv_error.md) if type conversion fails. ### Examples #### Round trip (JSON to CBOR bytes back to JSON) ```cpp #include #include using namespace jsoncons; int main() { ojson j1 = ojson::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 } ] } )"); std::vector v; cbor::encode_cbor(j1, v); ojson j2 = cbor::decode_cbor(v); std::cout << pretty_print(j2) << '\n'; } ``` Output: ```json { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.9 } ] } ``` #### Round trip (JSON to CBOR file back to JSON) ```cpp #include #include using namespace jsoncons; int main() { json j = json::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 } ] } )"); std::ofstream os; os.open("./output/store.cbor", std::ios::binary | std::ios::out); cbor::encode_cbor(j,os); std::vector v; std::ifstream is; is.open("./output/store.cbor", std::ios::binary | std::ios::in); json j2 = cbor::decode_cbor(is); std::cout << pretty_print(j2) << '\n'; } ``` Output: ```json { "application": "hiking", "reputons": [ { "assertion": "advanced", "rated": "Marilyn C", "rater": "HikingAsylum", "rating": 0.9 } ] } ``` #### Decode CBOR byte string ```cpp #include #include using namespace jsoncons; int main() { // byte string of length 5 std::vector buf = {0x45,'H','e','l','l','o'}; json j = cbor::decode_cbor(buf); auto bstr = j.as>(); // use byte_string_view to display as hex std::cout << "(1) "<< byte_string_view(bstr) << "\n\n"; // byte string value to JSON text becomes base64url std::cout << "(2) " << j << '\n'; } ``` Output: ``` (1) 48,65,6c,6c,6f (2) "SGVsbG8" ``` #### Decode CBOR byte string with base64 encoding hint ```cpp #include #include using namespace jsoncons; int main() { // semantic tag indicating expected conversion to base64 // followed by byte string of length 5 std::vector buf = {0xd6,0x45,'H','e','l','l','o'}; json j = cbor::decode_cbor(buf); auto bs = j.as(); // byte_string to ostream displays as hex std::cout << "(1) "<< bs << "\n\n"; // byte string value to JSON text becomes base64 std::cout << "(2) " << j << '\n'; } ``` Output: ``` (1) 48 65 6c 6c 6f (2) "SGVsbG8=" ``` #### Decode packed strings [stringref-namespace, stringref](http://cbor.schmorp.de/stringref) This example taken from [CBOR stringref extension](http://cbor.schmorp.de/stringref) shows three stringref-namespace tags, with two nested inside another: ```cpp int main() { std::vector v = {0xd9,0x01,0x00, // tag(256) 0x85, // array(5) 0x63, // text(3) 0x61,0x61,0x61, // "aaa" 0xd8, 0x19, // tag(25) 0x00, // unsigned(0) 0xd9, 0x01,0x00, // tag(256) 0x83, // array(3) 0x63, // text(3) 0x62,0x62,0x62, // "bbb" 0x63, // text(3) 0x61,0x61,0x61, // "aaa" 0xd8, 0x19, // tag(25) 0x01, // unsigned(1) 0xd9, 0x01,0x00, // tag(256) 0x82, // array(2) 0x63, // text(3) 0x63,0x63,0x63, // "ccc" 0xd8, 0x19, // tag(25) 0x00, // unsigned(0) 0xd8, 0x19, // tag(25) 0x00 // unsigned(0) }; ojson j = cbor::decode_cbor(v); std::cout << pretty_print(j) << "\n"; } ``` Output: ``` [ "aaa", "aaa", ["bbb", "aaa", "aaa"], ["ccc", "ccc"], "aaa" ] ``` #### Decode Typed Array tags jsoncons implements [Tags for Typed Arrays](https://tools.ietf.org/html/rfc8746). Tags 64-82 and Tags 84-86 are automatically decoded when detected. ```cpp #include #include #include int main() { const std::vector input = { 0xd8,0x52, // Tag 82 (float64 big endian Typed Array) 0x50, // Byte string value of length 16 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; auto j = cbor::decode_cbor(input); std::cout << "(1)\n" << pretty_print(j) << "\n\n"; auto v = cbor::decode_cbor>(input); std::cout << "(2)\n"; for (auto item : v) { std::cout << std::defaultfloat << item << "\n"; } std::cout << "\n"; std::vector output1; cbor::encode_cbor(v, output1); // output1 contains a classical CBOR array std::cout << "(3)\n" << byte_string_view(output1) << "\n\n"; std::vector output2; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(v, output2, options); // output2 contains a float64, native endian, Typed Array std::cout << "(4)\n" << byte_string_view(output2) << "\n\n"; } ``` Output: ``` (1) [ -1.7976931348623157e+308, 1.7976931348623157e+308 ] (2) -1.79769e+308 1.79769e+308 (3) 82 fb ff ef ff ff ff ff ff ff fb 7f ef ff ff ff ff ff ff (4) d8 56 50 ff ff ff ff ff ff ef ff ff ff ff ff ff ff ef 7f ``` #### Decode Typed Array tags - multi-dimensional row major tag jsoncons implements the tags for row-major and column-major order multi-dimensional arrays, as defined in [Tags for Typed Arrays](https://tools.ietf.org/html/rfc8746). ```cpp #include #include int main() { const std::vector input = { 0xd8,0x28, // Tag 40 (multi-dimensional row major array) 0x82, // array(2) 0x82, // array(2) 0x02, // unsigned(2) 1st Dimension 0x03, // unsigned(3) 2nd Dimension 0xd8,0x41, // Tag 65 (uint16 big endian Typed Array) 0x4c, // byte string(12) 0x00,0x02, // unsigned(2) 0x00,0x04, // unsigned(4) 0x00,0x08, // unsigned(8) 0x00,0x04, // unsigned(4) 0x00,0x10, // unsigned(16) 0x01,0x00 // unsigned(256) }; json j = cbor::decode_cbor(input); std::cout << j.tag() << "\n"; std::cout << pretty_print(j) << "\n"; } ``` Output: ``` multi-dim-row-major [ [2, 3], [2, 4, 8, 4, 16, 256] ] ``` ### See also [byte_string_view](../byte_string_view.md) [encode_cbor](encode_cbor.md) encodes a json value to the [Concise Binary Object Representation](http://cbor.io/) data format. jsoncons-1.3.2/doc/ref/cbor/diagrams/000077500000000000000000000000001477700171100174135ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/cbor/diagrams/basic_cbor_encoder.png000066400000000000000000000121111477700171100237020ustar00rootroot00000000000000PNG  IHDRxeGWsRGBtEXtmxfile%3Cmxfile%20host%3D%22app.diagrams.net%22%20agent%3D%22Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F131.0.0.0%20Safari%2F537.36%22%20version%3D%2224.8.1%22%3E%3Cdiagram%20id%3D%22iK-0d-7Yl-5MlnfMu26I%22%20name%3D%22Page-1%22%3ExVbBctowEP0aH9OxrZrQYzAkbShpKZ0BemGEvbFVZInKAky%2BvhKWsYWdSdthplzQvt2VVu%2BtJDsozIoHgbfphMdAHd%2BNCwcNHd%2F33MBVfxo5lkjP65dAIkhsgmpgRl6gyjTojsSQW4GScyrJ1gYjzhhE0sKwEPxghz1zaq%2B6xQm0gFmEaRudk1imJdqvtqXxj0CStFrZc40nw1WwAfIUx%2FzQgNDIQaHgXJajrAiBavIqXsq8%2B1e858IEMPknCaOn7wUbT2epH%2F4ay%2FkkWxaPN2aWPaY7s%2BE1zkm0%2BplzttqTnEguTPnyWHEi%2BI7FoKd1HTQ4pETCbIsj7T2oLlBYKjOqLE8N22VWa4KQUDQgU%2FYD8AykOKoQ431vGDQt5FWMHmpBvJ7B0oYYVR42PZCcZ65pUgPD1F%2BwdvsKa9GaixWwSJ0CxVqPqjoGaz1K5JmJf%2BXxmVAacqrk0LkITj%2BF51LwDTQ8qIc%2BoPg6zPtB8P%2BoT%2FaT1B8%2FLfA3SG7m0zHsx9BB%2FSeWgiASM0WcumcITgTOWlyrDUubUJs4xhlcsGwgTEnClBkpGpWsaKDpI%2BqGuDOOjMSxXqZTQVvjK0hypttI4rsdkqAOSfwrSDLd3PamP4INCYNlP%2Fi8u%2F%2Fy6HVI0mIfWHynL2NNI8W5Oiu2FlAQuTAc6fFSj98FxhoWDdfwWBlMFb%2BoJtBGI0ubddrJOr6lQc53IoK3jz3E1pPRVqqhRNAhRIUJoFiSvf3QdKljVvjKiaq4PpvIbgTkXghc7sdkNR%2BGy4nci%2Fv18vBKLBKQrYlOzXLedlf%2FKLN%2B38rw%2BisBjX4D%3C%2Fdiagram%3E%3C%2Fmxfile%3EP̉1IDATx^]P+TZOARE _XLkB-Q F!BA#B# $_Q`|PP ɓ&hЦRcZzaݙsg=s?r3k[{{͚}܇j/gL{ok:L`РDۣw̉@>s/Nn, |>^:ʤkTN@_y @$&NaI-Z':e+R_%&VaUN@_y ^s@! / /K@tj9$pUkTN@_y @$&NaI-Z':e+R_%&VaUN@_y ^s@! / /K@tj9$pU?z(v܉cǎaذḁKj*8qG.dݻX`֯_ 's[f &N7vڕRIXn>C<2?`ٲe|;wlO<={:thVm護ӧ{2(W5ʕ+cVYׁ\p'~ V_l='#FÇ1n8\p!o߾ɓ'͛I$+V)jyXӧ޽{1cF˧OM++^{-ʕ+2dΝ;I&ef!۷ڵkIEfO"ÇO,Ξ=ٶm[R[?k,lٲ~hѢ3_Wȑ#?dT 8o{ |n )Sb8~8z$VoFEO>;v,N:-{j/_v/_|yBZqy-y'?~;:+>m9s&ܹ@x E'i޼yQX,YC֭[Ͷ}jy}km3&Yp^z'ڼqFp9s76 0[D"F|/6}-[8Ƴ?:5 ބO4ƿD_s)ŋ 64ő믿g}vJ^_l i=Ϲ~z2FAv9ބ pܗ_~9x믛 =(o"[ {=rQyW_5}2>fW_mE8:9{J׮]۬ڳ7l/o%Y.:>#-yzD Ճi{駟&7-Lj݄*ٮҥQCy!s|~ԨQ{Y~k+Ӫ?{*a/(֞ [^~oKqPr}7(7Nٞx5ik50xnڴ)abտ/_}yhXR֢GҭR9.Js\裏6gNNnq˥ 1Rm@gXѲrNk)<( $c(3`eo1}yP'[+lijX.FIKPđqszJ}k"pUܽ{w+k{T~M /TyɲҥKX>M| |V?;{*x_qfϭTfo" pXQ+ E\%xO )nփgU~ m\ͭEc- /,vKZI㷳PvX)0.ŷI6oތ?]" >#vׄNL[&♶%EcqO|]4y=dŗg _wIpe0{Wݾ_t&e/:i| h LM¾}G}y_ {'g:dW|ezNGUոJ&`? |tC@5]Q1hk2TN@_y @$&NaI-Z':e+R_%&VaUN@_y ^s@! / /K@tj9$pUkTN@_y @$&NaI-Z':e+R_%&VaUN@_y ^s@! / /K@tj9$pUh P@/:UFgEYb!" "' |yUT" " &DJ@ibH5D@D RHD@D@9 " GX%" x>*,k@$&Va^s@D@"% 4 KD@$" ") |UX" " H H#M DJ@ibH5D@D RHD@D@9 " GX%" x>*,k@$&Va^s@D@"% 4 KD@$" ") |UX" " H H#M DJ@ibH5D@D RHD@D@9 " GX%" x>*,k@$&Va^s $0 \jg}&a bq66=6<ږ%]$WLJ{y&>vs`% ŸlxިoX?`-{!#k>)m8xFl>n'Vyn0q:ES  |)Xkm4Mz& !gҭ`| X/s  .Y-"ڦhV<@A=?υ|a W>n[>sƝ7MΗO@_>㺍&&Dgˋ 7o ۃ;. Wa ?滂=xYhbԋm_ C\ [(D%k(tlS&Y>lX 6[&?Y AآᓁhZAl5'P7> |iH5/ZU*iG}%kcxAg%%`o]XZUiy 8=G'=6 |袽EOm+-UD I}o0vެ>=QU|hoϸn#tB]+lϰ5A4o놐nF!??xQ:au%vߟq?>8w=zEF!%= [^FM̋'ũ3x-& DD@kF@$&Va^s@D@"% 4 KD@ P]ZIENDB`jsoncons-1.3.2/doc/ref/cbor/diagrams/cbor_options.png000066400000000000000000000243231477700171100226250ustar00rootroot00000000000000PNG  IHDREQsttEXtmxfile%3Cmxfile%20host%3D%22app.diagrams.net%22%20modified%3D%222020-04-16T00%3A35%3A06.912Z%22%20agent%3D%225.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F80.0.3987.163%20Safari%2F537.36%22%20etag%3D%22uct1c94P-5FGakEm0tIq%22%20version%3D%2212.9.6%22%20type%3D%22device%22%3E%3Cdiagram%20id%3D%22yA7M8pUu49T19xTu_T4b%22%20name%3D%22Page-1%22%3EzVjbctsgEP0aPbYjCcuXx9hO3Tyk46ln2qQvGSKtJaYINAhHcr6%2BKALr6voyre0nswd2QWcPsNhCszhfCJxEjzwAarl2kFtobrmuY6Ox%2BimQbYkMJhoIBQn0oApYkXcwnhrdkADSxkDJOZUkaYI%2BZwx82cCwEDxrDltz2pw1wSF0gJWPaRf9SQIZlejYsyv8K5AwMjM7tu6JsRmsgTTCAc9qELq30ExwLstWnM%2BAFuQZXkq%2FL3t6dwsTwOQxDiO0jB7Jwot%2F%2FFp4gF%2BT6Zx%2F0lHeMN3oD%2FZfuXjhiSScpXrhcmvYEHzDAigC2haaZhGRsEqwX%2FRmKv8Ki2RMleWoZneBZjYQEvIapBe8AB6DFFs1JDdq0eRp9ThDbWdVLhxDcFTLw0BjWKc%2F3IWuGFINTdIJhLn9hAXgK%2BnfDG%2FusMWb28Pb4JK8oX7egN00b659bd4Gf92gLz6PY86uzhs6Ypt6l6TN69DW4QhYcFdcEMryKU5T4jdpgZzIJ81g0X4u2p89bc3zWtd8awymFv9kAhRGzaswK7cPy%2FjtTUHKN8KHw%2FtKYhGCPKwjCBrXXTehtYz1JcxgAiiW5K15SfZlUc%2Bw5ER92U4vTlMvyGnpoPxs7VS%2F01px2tt12IpT0tKJ8yGp3Uefr7LhdVR2vlrc21LBoHVsoDNl4IxbgcaX1cH4H%2BjgzJPjsvoxFfih0%2Ba2dNauItG5OvNagnUvrLPJ9XS2VzMHtYBuWgudo%2BJYLbQD%2FUctfMejZ3fybTaMHGc9yUYP786y5%2BX2wCIQRGKmtrB6cBMcChx3BKIqOtmURCoF%2Fw0zTrlQCONMjZyuCaUtCFMSskJXSgKg8GlRHxL1VL7THTEJgmKa3oKzWZLuldMJtfpoTwIOvQ3d04tOZVYP9TKD1d8d6P4P%3C%2Fdiagram%3E%3C%2Fmxfile%3EGIQ IDATx^[Ƿ$(IˋhPP-KX5/65Ҁ C#ZK *`C)ԗVbQHLЄ|>o9gf\ f^֙w56@PF=>n '0 Q~}$X/yqF@\A $%`Z .m D?ɗb82 E$"`P6| 88(F cBE-.OD9 M"_5Qض`kK|)#@QD@ @,r%`ȗi"(jT0-Xb$_(@\A $%`Z .m D?ɗb82 E$"`P6| 88(F cBE-.OD9 M"_5Qض`kK|)#@QD@ @E.r۷o7SL1˖-cǎ3gΘ]vѣG6gUܾ}۬]lٲL<٬_ެX̙34? \ds 0EYj4"9DQqS7p#/}h4DQÇJ "-GD?nN>ml۶lڴɞs=[8pgڪǕ+W̺ugE;6sܹs͝;wlHG\Cɦ tK.5.]3OqUVy̙f߾}\xqyaN(nͱgk-'N*~AּΛ/Y| :DѠGI "ȑ#va{ngɓԩSv!7n"E?L~ŋf͚5<&{5ĀΕҡ1wa[>7~tIڵkf>mI9AqFǦt=qDqF׭PuwϦMhJ0Jp:5|ucNͥ#6g|i!P2DQɀYHܹr8qC []O͛7 u@m"_ʕ+;̍$.ԗ _P?w+ 'ӭ'n:te)N8 .EQvzWm/2;rDn>[l%P?o LQDv@ ڰaCfQ h!*UW5wDQhCmx"m~i;Wt[N=<.\fnUN%^ȱsvGŜ/۾Ӝ.Q3Ϙ˗/裏zʼv;@@T Iik%vHJE*ECDMъ NJQ<݂R μ""߾$˗3f(wH}6oF@wT@ I 9S"";;--g%MOQZQ5f^8;n-)<ݶz)R/S=Eqhɒ%#qEf֬Y?$Q4~xD/@/1ԏ(ҵm޼\t{,(8STzիf֭3<}q-ݞ>SαtO9^ϟYRZ3׃??4_|׾f$q'8 P)"+ Pb_QT+?^KŽVx ݗ_~iDqM+g}V-Zv ΃@+ Zf@V1(+7QT7ʎI^A^(IE7VILI)A@DYC!0dzxIgoőޥDQAaF@52l*~(ȆmW|ߣ{Cu@Ui@QbQ4yRw"g}GeEqBQԔHagC QE"Q;@QTT|e!DN!wߵM=0aBn0&j'(=$e!DQ![E˿)w,)x8CL \B97; LQDQm虸 C&dEx6V)|; /?qK !4Jv.Qܢ3|eEf&[ !%X(rD\ߑ~߳^`Q2DcL(bQD:!(r?M<: ܵM !jOF(!wȔjшֆݎ*E˼އ,O.UI`1f =KŐ/ړ)xZoq~E23f1$>9EM2 v(˻14XY7H&Ԕ=44d-Z4kAjq/kɡ<CMll;r_k{?,ky HB4@}GuךfY(jVem]7Pc!K ԾkI5Epn,U<CL3pѾ#5e?k9҉E- |nWu@ UM@wlj^reFUu_1&E$Biʾy J C hu}_ | C uX1TWDa館ZXdk /oCh$*5(ZQ7Pݑd~4w'_}P0P2P@79%PVQp]5Epn,yoV NCE彯NQT8Rtn0ay"w w(*+Ba( #iE|4&M2?;>#28` w( 6(*#<of֬YA 7@wA^p R٪dw;EuFKE3ׯ7+V0s)ߋ3\rlٲٳܺucǎM9e!<~_};wXQ~ܹlذ8qb9@a-Ν;g9bveF]~}Yv]S'Oֿ֊"Pyw3K,1:oڴ 1/WBHw(z/NZpTQ}vyfkٳg̙3Rߪ\t=z,[̞ҥK ,0ǎ3)R۶m37o4w*aWrG*Ag϶ӧ'NqO>mܺumFnsZTB !?Tp>-:|ϻ#/ߓrv횵DZ3fL,y'|Ӽ)ٷ-Guyp~ߚGy:@H;Rŭ/^~_v[βnMe=Zx]k=|ٿgzW;kD?J 7pߢHpJ(8Ac+_nkJٽ{wGhkM"EiQ׬YcEL/t|lmgΜ߸q#vL隽{vƍmuD5򗿴ՏnvGմ|2eJ=Kyu۷3n^z顸-*o޿|VH護ު"י@f~ߑ!{pq^^<ЮРuDֻ^ָ^--N$Izٴizuw՝8ZuJVYK%ϵ`;G|zTP`yTlt^> 7%8q=E/_G+*;:dv~c(hH ~4%v/Ļy׫"\z'bO>"Y!TJ@X׎?JDQ_'ň4nҮGíA .)MX 68H",8I#4M]iDN5I')ɢ]A\|=Dj I;I)qJV(R_GyE] 4g7gE^" {]3 PPS^D>{q4[ݼϟYRoMiY/uDQ[;C7QkS [N~4X˾s#(*mG8j}%~!5O\rϫUZ"4U<G!P*8Y}-MSDQq,)BT@ /Z]4qNE3du<G&G~4꾯s@gǕ=r@E7JC)Z[9';DQvf\@h7Qq*"ZhQE&Z>/*@Ge.cؾl8җY}?~4^sF 7lX" ,a7 zP!Ƽ *4aU5a 3*|iJP;3E19&<R>kC /XTDQԙ3X`a@(>}:Q@c * @(EJ̕@BPqeXEak#P8{ , Ӄ@]B9hEQ)@⨮Ex Z:*͛e Z&bLlU*fGE|qB4V FQ4hşJ-X*$(3_$LDQ f(K54Vw#PF/DεQ -X w!PT/LH1&3`(J &e7_{=X?1 e@M[M 8B:m2;/k֬17_~C/1%z dGzմ٣w?޽{U쭃ZiQhfʔ)fٲeرc̙3f׮]fѕvmvZe3yd~zb 3gΜJOϗ?3_|yꩧ̟gj7Iց!K!znQ4uFVt˗̚5|vG}ԨGȽl~4%(jl0|$HBaѣGmuHܜ>}ٶmٴi=G[+v#gϞU+Wud;vl"sΙsڟkVFƞ8qټynU]dlZ`AgͽtRsҥz7ޤ<|sΝsE#9sٷoC,/^a>l{v\(nͱgk[O8a$}ˌ3xٳomF@w"2;wLi=r wlL |T9AlEU/Q9s[nn1Ox|iԗc!P!*Ef*%gK[)r^,H[_OؔY)/WU矶R μ$Q㋥y˓/Y| Qȳޡwyn5=+izҊ"K)JQz|BSQ/z)EK,Q뷧(vk  *J (r[8ImnOE7)1cƌx_)xJzZ+gSO]zlݺu9TuLO%UGϲ~K8@ϔ!7^!"_B4%"Wnnv}zlRds!DQh i Ғ<t'("C  IKF@5*\,rmt1~/pd HE.lpp0QE ƶ\["]K1"r` 0(DLkDQ…m!"זH'R GF@X J&/EQԨpal[ȵ%IÑQ ("  IKF@5*\,rmt1~/pd HE.lpp0QE ƶ\["]K1"r",Yhq. @ `A @QD@   @QD@ *E @`d @l @3r }F@ =E @ @P)" @ @T@ !@># @g @` @>z@ @O9@RD&@ D9@ @C3 }F@ @ 9@| @"r < @L @"r P)" @@g$ @` @l @3r )" @=E @x@J@E @RD@ H@ 9@># @g۷ڵk͖-[ԩSݽr=gϞ=fرܻwϬ_ެXL6-ռ&yѱc̙3gkf^yk9srehP#_'P(a9Qk.3z*f.@AE B _L;O>iqNGv-]\t3M=qBǝ'ϟoܹP+:˭a+IDAT'07nUe>׽{۷[r. P.DQ|E2Fŋf͚5Vx饗E?ݸqì[޽ʉ, 3wͼy:nn޽{wl2eG6T!3gδBF}&l_MvNmI~ԩSܵ% C# H (8Qogr_U=9rEoqNgN\WW`yϣvEv|:4߉"w4uИ!n1 (.N@sĉ"'hB Cي(nQ9m^_ݖV}7'h|pۉmرN$|Q?DQs;X^@Qȯ8dҶR(r[O:/V)'4"]#QUJ/.-?Dрpo  "8 !ݸ~h%(0x;}5Iy>>N$h̘1h/U\OQ(o)'( ?FX\Eѧu݉3'BΟ?oυ S\:@Nb#Iu{߮rĽ_?O^zռ˝9;ݓr[n5ǏOmiO;=E?DQ4"TJQT)n&FUBEd h4"E v/!@AQD@ c 4 @"r < ?>3=IENDB`jsoncons-1.3.2/doc/ref/cbor/encode_cbor.md000066400000000000000000000172361477700171100204210ustar00rootroot00000000000000### jsoncons::cbor::encode_cbor ```cpp #include template void encode_cbor(const T& jval, ByteContainer& cont, const cbor_decode_options& options = cbor_decode_options()); (1) template void encode_cbor(const T& val, std::ostream& os, const cbor_encode_options& options = cbor_encode_options()); (2) template void encode_cbor(const allocator_set& alloc_set, const T& jval, ByteContainer& cont, const cbor_decode_options& options = cbor_decode_options()); (3) (since 0.171.0) template void encode_cbor(const allocator_set& alloc_set, const T& val, std::ostream& os, const cbor_encode_options& options = cbor_encode_options()); (4) (since 0.171.0) ``` Encodes a C++ data structure to the [Concise Binary Object Representation](http://cbor.io/) data format. (1) Writes a value of type T into a byte container in the CBOR data format, using the specified (or defaulted) [options](cbor_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). Type `ByteContainer` must be back insertable and have member type `value_type` with size exactly 8 bits (since 0.152.0.) Any of the values types `int8_t`, `uint8_t`, `char`, `unsigned char` and `std::byte` (since C++17) are allowed. (2) Writes a value of type T into a binary stream in the CBOR data format, using the specified (or defaulted) [options](cbor_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). Functions (3)-(4) are identical to (1)-(2) except an [allocator_set](../allocator_set.md) is passed as an additional argument. ### Examples #### cbor example ```cpp #include #include using namespace jsoncons; int main() { ojson j1; j1["zero"] = 0; j1["one"] = 1; j1["two"] = 2; j1["null"] = null_type(); j1["true"] = true; j1["false"] = false; j1["max int64_t"] = (std::numeric_limits::max)(); j1["max uint64_t"] = (std::numeric_limits::max)(); j1["min int64_t"] = (std::numeric_limits::lowest)(); j1["max int32_t"] = (std::numeric_limits::max)(); j1["max uint32_t"] = (std::numeric_limits::max)(); j1["min int32_t"] = (std::numeric_limits::lowest)(); j1["max int16_t"] = (std::numeric_limits::max)(); j1["max uint16_t"] = (std::numeric_limits::max)(); j1["min int16_t"] = (std::numeric_limits::lowest)(); j1["max int8_t"] = (std::numeric_limits::max)(); j1["max uint8_t"] = (std::numeric_limits::max)(); j1["min int8_t"] = (std::numeric_limits::lowest)(); j1["max double"] = (std::numeric_limits::max)(); j1["min double"] = (std::numeric_limits::lowest)(); j1["max float"] = (std::numeric_limits::max)(); j1["zero float"] = 0.0; j1["min float"] = (std::numeric_limits::lowest)(); j1["Key too long for small string optimization"] = "String too long for small string optimization"; std::vector cont; cbor::encode_cbor(j1, cont); ojson j2 = cbor::decode_cbor(cont); std::cout << pretty_print(j2) << '\n'; } ``` Output: ```json { "zero": 0, "one": 1, "two": 2, "null": null, "true": true, "false": false, "max int64_t": 9223372036854775807, "max uint64_t": 18446744073709551615, "min int64_t": -9223372036854775808, "max int32_t": 2147483647, "max uint32_t": 4294967295, "min int32_t": -2147483648, "max int16_t": 32767, "max uint16_t": 65535, "min int16_t": -32768, "max int8_t": 127, "max uint8_t": 255, "min int8_t": -128, "max double": 1.79769313486232e+308, "min double": -1.79769313486232e+308, "max float": 3.40282346638529e+038, "zero float": 0.0, "min float": -3.40282346638529e+038, "Key too long for small string optimization": "String too long for small string optimization" } ``` #### Encode CBOR byte string ```cpp #include #include using namespace jsoncons; int main() { // construct byte string value std::vector cont = {'H','e','l','l','o'}; json j(byte_string_arg, cont); std::vector buf; cbor::encode_cbor(j, buf); std::cout << "(1) " << byte_string_view(buf) << "\n\n"; json j2 = cbor::decode_cbor(buf); std::cout << "(2) " << j2 << '\n'; } ``` Output: ``` (1) 45,48,65,6c,6c,6f (2) "SGVsbG8" ``` #### Encode byte string with encoding hint ```cpp #include #include using namespace jsoncons; int main() { // construct byte string value std::vector cont = {'H','e','l','l','o'}; json j1(byte_string_arg, cont, semantic_tag::base64); std::vector buf; cbor::encode_cbor(j1, buf); std::cout << "(1) " << byte_string_view(buf) << "\n\n"; json j2 = cbor::decode_cbor(buf); std::cout << "(2) " << j2 << '\n'; } ``` Output: ``` (1) d6,45,48,65,6c,6c,6f (2) "SGVsbG8=" ``` #### Encode packed strings [stringref-namespace, stringref](http://cbor.schmorp.de/stringref) This example taken from [CBOR stringref extension](http://cbor.schmorp.de/stringref) shows how to encode a data structure that contains many repeated strings more efficiently. ```cpp #include #include #include #include using namespace jsoncons; int main() { ojson j = ojson::parse(R"( [ { "name" : "Cocktail", "count" : 417, "rank" : 4 }, { "rank" : 4, "count" : 312, "name" : "Bath" }, { "count" : 691, "name" : "Food", "rank" : 4 } ] )"); auto options = cbor::cbor_encode_options{} .pack_strings(true); std::vector buf; cbor::encode_cbor(j, buf, options); std::cout << byte_string_view(buf) << "\n\n"; /* d90100 -- tag (256) 83 -- array(3) a3 -- map(3) 64 -- text string (4) 6e616d65 -- "name" 68 -- text string (8) 436f636b7461696c -- "Cocktail" 65 -- text string (5) 636f756e74 -- "count" 1901a1 -- unsigned(417) 64 -- text string (4) 72616e6b -- "rank" 04 -- unsigned(4) a3 -- map(3) d819 -- tag(25) 03 -- unsigned(3) 04 -- unsigned(4) d819 -- tag(25) 02 -- unsigned(2) 190138 -- unsigned(312) d819 -- tag(25) 00 -- unsigned(0) 64 -- text string(4) 42617468 -- "Bath" a3 -- map(3) d819 -- tag(25) 02 -- unsigned(2) 1902b3 -- unsigned(691) d819 -- tag(25) 00 -- unsigned(0) 64 - text string(4) 466f6f64 -- "Food" d819 -- tag(25) 03 -- unsigned(3) 04 -- unsigned(4) */ ojson j2 = cbor::decode_cbor(buf); assert(j2 == j); } ``` Output: ``` d9,01,00,83,a3,64,6e,61,6d,65,68,43,6f,63,6b,74,61,69,6c,65,63,6f,75,6e,74,19,01,a1,64,72,61,6e,6b,04,a3,d8,19,03,04,d8,19,02,19,01,38,d8,19,00,64,42,61,74,68,a3,d8,19,02,19,02,b3,d8,19,00,64,46,6f,6f,64,d8,19,03,04 ``` ### See also [byte_string_view](../byte_string_view.md) [decode_cbor](decode_cbor.md) decodes a [Concise Binary Object Representation](http://cbor.io/) data format to a json value. jsoncons-1.3.2/doc/ref/corelib/000077500000000000000000000000001477700171100163165ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/corelib/allocator_set.md000066400000000000000000000041171477700171100214760ustar00rootroot00000000000000### jsoncons::allocator_set ```cpp #include template< typename Allocator,typename TempAllocator > allocator_set; ``` Member type |Definition ------------------------------------|------------------------------ `allocator_type`|`Allocator` `temp_allocator_type`|`TempAllocator` #### Constructors allocator_set(const Allocator& alloc=Allocator(), const TempAllocator& temp_alloc=TempAllocator()) Constructs an `allocator_set` with an allocator for result data and a second allocator for temporary allocations. allocator_set(const allocator_set& other) Copy constructor. allocator_set(allocator_set&& other) Move constructor. #### Accessors Allocator get_allocator() const; Returns an allocator object for result data TempAllocator get_temp_allocator() const; Returns an allocator object for for temporary allocations #### Helper functions template allocator_set combine_allocators( const Allocator& alloc, const TempAllocator& temp_alloc); Combines an allocator for result data and an allocator for temporary allocations into an `allocator_set` object, deducing the allocator types from the types of the arguments. allocator_set,std::allocator> combine_allocators() Creates an `allocator_set,std::allocator>` object with default allocators for result data and temporary allocations. template allocator_set> combine_allocators( const Allocator& alloc); Creates an `allocator_set` with the provided allocator for result data and defaulting to a `std::allocator` for temporary allocations. template allocator_set,TempAllocator> temp_allocator_only(const TempAllocator& temp_alloc) Creates a `allocator_set` object, defaulting the result allocator type to `std::allocator` and deducing the temp allocator type from the type of the `temp_alloc` argument. jsoncons-1.3.2/doc/ref/corelib/basic_default_json_visitor.md000066400000000000000000000027131477700171100242400ustar00rootroot00000000000000### jsoncons::basic_default_json_visitor ```cpp #include template < typename CharT > class basic_default_json_visitor ``` A [basic_json_visitor](basic_json_visitor.md) that discards all incoming json events. Serves as a base class for user defined content handlers. `basic_default_json_visitor` is noncopyable and nonmoveable. ![basic_default_json_visitor](./diagrams/basic_default_json_visitor.png) Aliases for common character types are provided: Type |Definition --------------------|------------------------------ default_json_visitor |`basic_default_json_visitor` wdefault_json_visitor |`basic_default_json_visitor` #### Member types Member type |Definition ------------------------------------|------------------------------ `char_type`|CharT `string_view_type`|A non-owning view of a string, holds a pointer to character data and length. Supports conversion to and from strings. Will be typedefed to the C++ 17 [std::string view](http://en.cppreference.com/w/cpp/string/basic_string_view) if C++ 17 is detected or if `JSONCONS_HAS_STD_STRING_VIEW` is defined, otherwise proxied. #### Constructors basic_default_json_visitor(bool accept_more = true) Constructs a `basic_default_json_visitor`. The parameter `accept_more` indicates whether the content handler will, after consuming an event, accept more events. ### See also [basic_json_filter](basic_json_filter.md) jsoncons-1.3.2/doc/ref/corelib/basic_json.md000066400000000000000000000337401477700171100207610ustar00rootroot00000000000000### jsoncons::basic_json ```cpp #include template< typename CharT, class Policy = sorted_policy, typename Allocator = std::allocator > class basic_json; namespace pmr { template using basic_json = jsoncons::basic_json>; using json = basic_json; (since 0.171.0) using wjson = basic_json; using ojson = basic_json; using wojson = basic_json; } ``` A `basic_json` is a union type that can hold one of a number of possible data members, some that require an allocator (a long string, byte string, array, or object), and other trivially copyable ones that do not (an empty object, short string, number, boolean, or null). The data member may be tagged with a [semantic_tag](semantic_tag.md) that provides additional information about its value. The sizeof a `basic_json` regardless of its template parameters is normally 16 bytes. A `basic_json` is allocator-aware, and supports allocator propagation to allocator-aware arrays or objects. Every constructor has a version that accepts an allocator argument. A long string, byte string, array or object contains a pointer to underlying storage, the allocator is used to allocate that storage, and it is retained in that storage. For other data members the allocator argument is ignored. For more about allocators, see Allocators. When assigned a new `basic_json` value, the old value is overwritten. The member data type of the new value may be different from the old value. A `basic_json` can support multiple readers concurrently, as long as it is not being modified. If it is being modified, it must be by one writer with no concurrent readers. Several aliases for common character types and policies for ordering an object's name/value pairs are provided: Type |Definition --------------------|------------------------------ [jsoncons::json](json.md) |`jsoncons::basic_json>` [jsoncons::ojson](ojson.md) |`jsoncons::basic_json>` [jsoncons::wjson](wjson.md) |`jsoncons::basic_json>` [jsoncons::wojson](wojson.md) |`jsoncons::basic_json>` `jsoncons::pmr::json` (0.171.0) |`jsoncons::pmr::basic_json` `jsoncons::pmr::ojson` (0.171.0) |`jsoncons::pmr::basic_json` `jsoncons::pmr::wjson` (0.171.0) |`jsoncons::pmr::basic_json` `jsoncons::pmr::wojson` (0.171.0) |`jsoncons::pmr::basic_json` #### Template parameters
CharT Character type of text string
Policy Implementation policy for arrays and objects
Allocator Allocator type for allocating internal storage for long strings, byte strings, arrays and objects. The allocator type may be a stateless allocator, a std::pmr::polymorphic_allocator, or a std::scoped_allocator_adaptor. Non-propagating stateful allocators, such as the Boost.Interprocess allocators, must be wrapped by a std::scoped_allocator_adaptor.
#### Member types Member type |Definition ------------------------------------|------------------------------ `char_type`|CharT `policy_type`|Policy `allocator_type` (until 0.171.0)|A stateless allocator, or a non-propagating stateful allocator `allocator_type` (after 0.171.0)|A stateless allocator, [std::pmr::polymorphic_allocator](https://en.cppreference.com/w/cpp/memory/polymorphic_allocator), or [std::scoped_allocator_adaptor](https://en.cppreference.com/w/cpp/memory/scoped_allocator_adaptor) `char_traits_type`|`std::char_traits` `char_allocator_type`|`allocator_type` rebound to `char_type` `reference`|`basic_json&` `const_reference`|`const basic_json&` `pointer`|`basic_json*` `const_pointer`|`const basic_json*` `string_view_type`|`basic_string_view` `key_type`|A [ContiguousContainer](https://en.cppreference.com/w/cpp/named_req/ContiguousContainer) to `char_type` `key_value_type`|`key_value` `object_iterator`|A [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator) to [key_value_type](json/key_value.md) `const_object_iterator`|A const [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator) to const [key_value_type](json/key_value.md) `array_iterator`|A [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator) to `basic_json` `const_array_iterator`|A const [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator) to `const basic_json` `object_range_type`|range (since 0.173.3) `const_object_range_type`|range (since 0.173.3) `array_range_type`|range (since 0.173.3) `const_array_range_type`|range (since 0.173.3) `proxy_type`|proxy. The `proxy_type` class supports conversion to `basic_json&`. (removed in 1.0.0) ### Static member functions
parse Parses JSON.
make_array Makes a multidimensional basic_json array.
const basic_json& null() Returns a null value
### Member functions
(constructor) constructs the basic_json value
(destructor) destructs the basic_json value
operator= assigns values
allocator_type get_allocator() const For a long string, byte string, array, or object, returns the retained allocator used to allocate memory for their storage, otherwise attempts to return a default constructed allocator. #### Ranges and Iterators
array_range Returns a range that supports a range-based for loop over the elements of a basic_json array.
obect_range Returns a range that supports a range-based for loop over the key-value pairs of a basic_json object.
#### Capacity
size_t size() const noexcept Returns the number of elements in a basic_json array, or the number of members in a object, or zero
bool empty() const noexcept Returns true if a basic_json string, object or array has no elements, otherwise false
size_t capacity() const Returns the size of the storage space currently allocated for a basic_json object or array
void reserve(std::size_t n) Increases the capacity of a basic_json object or array to allow at least n members or elements
void resize(std::size_t n) Resizes a basic_json array so that it contains n elements
void resize(std::size_t n, const basic_json& val) Resizes a basic_json array so that it contains n elements that are initialized to val
void shrink_to_fit() Requests the removal of unused capacity
#### Accessors
bool contains(const string_view_type& key) const noexcept Returns true if an object has a member with the given key , otherwise false
is Checks if a basic_json value matches a type.
as Attempts to convert a basic_json value to a value of a type.
operator[] Access or insert specified element.
at
at_or_null
Return the specified value.
get_value_or Return the specified value if available, otherwise a default value.
semantic_tag tag() const Returns the [semantic_tag](semantic_tag.md) associated with this value uint64_t ext_tag() const If `tag()` == `semantic_tag::ext`, returns a format specific tag associated with a byte string value, otherwise return 0. An example is a MessagePack `type` in the range 0-127 associated with the MessagePack ext format family, or a CBOR tag preceeding a byte string. json_type type() const Returns the [json type](json_type.md) associated with this value object_iterator find(const string_view_type& name) const_object_iterator find(const string_view_type& name) const Returns an object iterator to a member whose name compares equal to `name`. If there is no such member, returns `object_range.end()`. Throws `std::domain_error` if not an object. #### Modifiers
void clear() Remove all elements from an array or members from an object, otherwise do nothing
erase Erases array elements and object members
push_back Adds a value to the end of a basic_json array
insert Inserts elements
emplace_back Constructs a value in place at the end of a basic_json array
emplace Constructs a value in place before a specified position in a basic_json array
try_emplace Constructs a key-value pair in place in a basic_json object if the key does not exist, does nothing if the key exists
insert_or_assign Inserts a key-value pair in a basic_json object if the key does not exist, or assigns a new value if the key already exists
merge Inserts another basic_json object's key-value pairs into a basic_json object, if they don't already exist.
merge_or_update Inserts another basic_json object's key-value pairs into a basic_json object, or assigns them if they already exist.
void swap(basic_json& val) noexcept Exchanges the content of the basic_json value with the content of val, which is another basic_json value
#### Serialization
dump Serializes basic_json value to a string, stream, or basic_json_visitor.
#### Non member functions bool operator==(const basic_json& lhs, const basic_json& rhs) Returns `true` if two basic_json objects compare equal, `false` otherwise. bool operator!=(const basic_json& lhs, const basic_json& rhs) Returns `true` if two basic_json objects do not compare equal, `false` otherwise. bool operator<(const basic_json& lhs, const basic_json& rhs) Compares the contents of lhs and rhs lexicographically. bool operator<=(const basic_json& lhs, const basic_json& rhs) Compares the contents of lhs and rhs lexicographically. bool operator>(const basic_json& lhs, const basic_json& rhs) Compares the contents of lhs and rhs lexicographically. bool operator>=(const basic_json& lhs, const basic_json& rhs) Compares the contents of lhs and rhs lexicographically. std::basic_istream& operator>>(std::basic_istream& is, basic_json& o) Reads a `basic_json` value from a stream. std::basic_ostream& operator<<(std::basic_ostream& os, const basic_json& o) Inserts basic_json value into stream. std::basic_ostream& print(const basic_json& val) std::basic_ostream& print(const basic_json& val, const basic_json_options& options) Inserts basic_json value into stream using the specified [basic_json_options](basic_json_options.md) if supplied. std::basic_ostream& pretty_print(const basic_json& val) std::basic_ostream& pretty_print(const basic_json& val, const basic_json_options& options) Inserts basic_json value into stream using the specified [basic_json_options](basic_json_options.md) if supplied. void swap(basic_json& a, basic_json& b) noexcept Exchanges the values of `a` and `b` jsoncons-1.3.2/doc/ref/corelib/basic_json_cursor.md000066400000000000000000000264311477700171100223550ustar00rootroot00000000000000### jsoncons::basic_json_cursor ```cpp #include template< typename CharT, typename Source=jsoncons::stream_source, typename Allocator=std::allocator> basic_json_cursor; ``` A pull parser for reporting JSON parse events. A typical application will repeatedly process the `current()` event and call the `next()` function to advance to the next event, until `done()` returns `true`. In addition, when positioned on a `begin_object` event, the `read_to` function can pull a complete object representing the events from `begin_object` to `end_object`, and when positioned on a `begin_array` event, a complete array representing the events from `begin_array` to `end_array`. `basic_json_cursor` is noncopyable and nonmoveable. Aliases for common character types are provided: Type |Definition --------------------|------------------------------ `json_stream_cursor` (since 0.167.0) |`basic_json_cursor>` `json_string_cursor` (since 0.167.0) |`basic_json_cursor>` `wjson_stream_cursor` (since 0.167.0) |`basic_json_cursor>` `wjson_string_cursor` (since 0.167.0) |`basic_json_cursor>` `json_cursor` (until 0.167.0) |`basic_json_cursor` `wjson_cursor` (until 0.167.0) |`basic_json_cursor` ### Implemented interfaces [basic_staj_cursor](staj_cursor.md) #### Constructors template basic_json_cursor(Sourceable&& source, const basic_json_decode_options& options = basic_json_decode_options(), std::function err_handler = default_json_parsing(), const Allocator& alloc = Allocator()); (1) template basic_json_cursor(Sourceable&& source, std::error_code& ec); (2) template basic_json_cursor(Sourceable&& source, const basic_json_decode_options& options, std::error_code& ec); (3) template basic_json_cursor(Sourceable&& source, const basic_json_decode_options& options, std::function err_handler, std::error_code& ec); (4) template basic_json_cursor(std::allocator_arg_t, const Allocator& alloc, Sourceable&& source, const basic_json_decode_options& options, std::function err_handler, std::error_code& ec); (5) Constructor (1) reads from a character sequence or stream and throws a [ser_error](ser_error.md) if a parsing error is encountered while processing the initial event. Constructors (2)-(5) read from a character sequence or stream and set `ec` if a parsing error is encountered while processing the initial event. Note: It is the programmer's responsibility to ensure that `basic_json_cursor` does not outlive the source, as `basic_json_cursor` holds a pointer to but does not own this resource. #### Parameters `source` - a value from which a `jsoncons::basic_string_view` is constructible, or a value from which a `source_type` is constructible. In the case that a `jsoncons::basic_string_view` is constructible from `source`, `source` is dispatched immediately to the parser. Otherwise, the `json_cursor` reads from a `source_type` in chunks. #### Member functions bool done() const override; Checks if there are no more events. const basic_staj_event& current() const override; Returns the current [basic_staj_event](basic_staj_event.md). void read_to(json_visitor& visitor) override Feeds the current and succeeding [staj events](basic_staj_event.md) through the provided [visitor](basic_json_visitor.md), until the visitor indicates to stop. If a parsing error is encountered, throws a [ser_error](ser_error.md). void read_to(basic_json_visitor& visitor, std::error_code& ec) override Feeds the current and succeeding [staj events](basic_staj_event.md) through the provided [visitor](basic_json_visitor.md), until the visitor indicates to stop. If a parsing error is encountered, sets `ec`. void next() override; Advances to the next event. If a parsing error is encountered, throws a [ser_error](ser_error.md). void next(std::error_code& ec) override; Advances to the next event. If a parsing error is encountered, sets `ec`. const ser_context& context() const override; Returns the current [context](ser_context.md) void reset(); Reset cursor to read another value from the same source template reset(Sourceable&& source) Reset cursor to read new value from a new source #### Non-member functions template basic_staj_filter_view operator|(basic_json_cursor& cursor, std::function&, const ser_context&)> pred); ### Examples Input JSON file `book_catalog.json`: ```json [ { "author" : "Haruki Murakami", "title" : "Hard-Boiled Wonderland and the End of the World", "isbn" : "0679743464", "publisher" : "Vintage", "date" : "1993-03-02", "price": 18.90 }, { "author" : "Graham Greene", "title" : "The Comedians", "isbn" : "0099478374", "publisher" : "Vintage Classics", "date" : "2005-09-21", "price": 15.74 } ] ``` #### Read JSON parse events ```cpp #include #include #include using namespace jsoncons; int main() { std::ifstream is("book_catalog.json"); json_stream_cursor cursor(is); for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: std::cout << event.event_type() << "\n"; break; case staj_event_type::end_array: std::cout << event.event_type() << "\n"; break; case staj_event_type::begin_object: std::cout << event.event_type() << "\n"; break; case staj_event_type::end_object: std::cout << event.event_type() << "\n"; break; case staj_event_type::key: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::string_value: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::null_value: std::cout << event.event_type() << ": " << "\n"; break; case staj_event_type::bool_value: std::cout << event.event_type() << ": " << std::boolalpha << event.get() << "\n"; break; case staj_event_type::int64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::double_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; default: std::cout << "Unhandled event type\n"; break; } } } ``` Output: ``` begin_array begin_object key: author string_value: Haruki Murakami key: title string_value: Hard-Boiled Wonderland and the End of the World key: isbn string_value: 0679743464 key: publisher string_value: Vintage key: date string_value: 1993-03-02 key: price double_value: 19 end_object begin_object key: author string_value: Graham Greene key: title string_value: The Comedians key: isbn string_value: 0099478374 key: publisher string_value: Vintage Classics key: date string_value: 2005-09-21 key: price double_value: 16 end_object end_array ``` #### Filter the event stream ```cpp #include #include #include using namespace jsoncons; int main() { bool author_next = false; auto filter = [&](const staj_event& event, const ser_context&) -> bool { if (event.event_type() == staj_event_type::key && event.get() == "author") { author_next = true; return false; } if (author_next) { author_next = false; return true; } return false; }; std::ifstream is("book_catalog.json"); json_stream_cursor cursor(is); auto filtered_c = cursor | filter; for (; !filtered_c.done(); filtered_c.next()) { const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::string_value: std::cout << event.get() << "\n"; break; } } } ``` Output: ``` Haruki Murakami Graham Greene ``` #### Pull nested objects into a basic_json ```cpp #include #include // json_decoder and json #include int main() { std::ifstream is("book_catalog.json"); json_stream_cursor cursor(is); json_decoder decoder; for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: { std::cout << event.event_type() << " " << "\n"; break; } case staj_event_type::end_array: { std::cout << event.event_type() << " " << "\n"; break; } case staj_event_type::begin_object: { std::cout << event.event_type() << " " << "\n"; cursor.read_to(decoder); json j = decoder.get_result(); std::cout << pretty_print(j) << "\n"; break; } default: { std::cout << "Unhandled event type: " << event.event_type() << " " << "\n"; break; } } } } ``` Output: ``` begin_array begin_object { "author": "Haruki Murakami", "date": "1993-03-02", "isbn": "0679743464", "price": 18.9, "publisher": "Vintage", "title": "Hard-Boiled Wonderland and the End of the World" } begin_object { "author": "Graham Greene", "date": "2005-09-21", "isbn": "0099478374", "price": 15.74, "publisher": "Vintage Classics", "title": "The Comedians" } end_array ``` ### See also [basic_staj_event](basic_staj_event.md) [staj_array_iterator](staj_array_iterator.md) [staj_object_iterator](staj_object_iterator.md) jsoncons-1.3.2/doc/ref/corelib/basic_json_encoder.md000066400000000000000000000324371477700171100224620ustar00rootroot00000000000000### jsoncons::basic_json_encoder ```cpp #include template< typename CharT, typename Sink> > basic_json_encoder : public jsoncons::basic_json_visitor template< typename CharT, typename Sink> > basic_compact_json_encoder : public jsoncons::basic_json_visitor ``` `basic_json_encoder` and `basic_compact_json_encoder` are noncopyable and nonmoveable. ![basic_json_encoder](./diagrams/basic_json_encoder.png) Four specializations for common character types and sink types are defined for both the pretty print and compressed serializers: Type |Definition ---------------------------|------------------------------ json_stream_encoder |basic_json_encoder> json_string_encoder |basic_json_encoder> wjson_stream_encoder |basic_json_encoder> wjson_string_encoder |basic_json_encoder> compact_json_stream_encoder (since 0.151.2) |basic_compact_json_encoder> compact_json_string_encoder (since 0.151.2) |basic_compact_json_encoder> compact_wjson_stream_encoder (since 0.151.2) |basic_compact_json_encoder> compact_wjson_string_encoder (since 0.151.2) |basic_compact_json_encoder> #### Member types Type |Definition ---------------------------|------------------------------ char_type |CharT sink_type |Sink string_view_type | #### Constructors explicit basic_json_encoder(Sink&& sink) Constructs a new encoder that is associated with the destination `sink`. basic_json_encoder(Sink&& sink, const basic_json_options& options) Constructs a new encoder that is associated with the destination `sink` and uses the specified [json options](basic_json_options.md). #### Destructor virtual ~basic_json_encoder() noexcept #### Member functions void reset(); Reset encoder to write another value to the same sink void reset(Sink&& sink) Reset encoder to write a new value to a new sink #### Inherited from [basic_json_visitor](../basic_json_visitor.md) void flush(); (1) bool begin_object(semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (2) bool begin_object(std::size_t length, semantic_tag tag=semantic_tag::none, const ser_context& context = ser_context()); (3) bool end_object(const ser_context& context = ser_context()); (4) bool begin_array(semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (5) bool begin_array(std::size_t length, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (6) bool end_array(const ser_context& context=ser_context()); (7) bool key(const string_view_type& name, const ser_context& context=ser_context()); (8) bool null_value(semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (9) bool bool_value(bool value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (10) bool string_value(const string_view_type& value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (11) bool byte_string_value(const byte_string_view& source, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (12) (until 0.152.0) template bool byte_string_value(const ByteStringLike& souce, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (12) (since 0.152.0) template bool byte_string_value(const ByteStringLike& souce, uint64_t ext_tag, const ser_context& context=ser_context()); (13) (since 0.152.0) bool uint64_value(uint64_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (14) bool int64_value(int64_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (15) bool half_value(uint16_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (16) bool double_value(double value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (17) bool begin_object(semantic_tag tag, const ser_context& context, std::error_code& ec); (18) bool begin_object(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec); (19) bool end_object(const ser_context& context, std::error_code& ec); (20) bool begin_array(semantic_tag tag, const ser_context& context, std::error_code& ec); (21) bool begin_array(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec); (22) bool end_array(const ser_context& context, std::error_code& ec); (23) bool key(const string_view_type& name, const ser_context& context, std::error_code& ec); (24) bool null_value(semantic_tag tag, const ser_context& context, std::error_code& ec); (25) bool bool_value(bool value, semantic_tag tag, const ser_context& context, std::error_code& ec); (26) bool string_value(const string_view_type& value, semantic_tag tag, const ser_context& context, std::error_code& ec); (27) bool byte_string_value(const byte_string_view& source, semantic_tag tag, const ser_context& context, std::error_code& ec); (28) (until 0.152.0) template bool byte_string_value(const ByteStringLike& source, semantic_tag tag, const ser_context& context, std::error_code& ec); (28) (since 0.152.0) template bool byte_string_value(const ByteStringLike& source, uint64_t ext_tag, const ser_context& context, std::error_code& ec); (29) (since 0.152.0) bool uint64_value(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (30) bool int64_value(int64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (31) bool half_value(uint16_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (32) bool double_value(double value, semantic_tag tag, const ser_context& context, std::error_code& ec); (33) template bool typed_array(const span& data, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (34) bool typed_array(half_arg_t, const span& s, semantic_tag tag = semantic_tag::none, const ser_context& context = ser_context()); (35) bool begin_multi_dim(const span& shape, semantic_tag tag, const ser_context& context); (36) bool end_multi_dim(const ser_context& context=ser_context()); (37) template bool typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (38) bool typed_array(half_arg_t, const span& s, semantic_tag tag, const ser_context& context, std::error_code& ec); (39) bool begin_multi_dim(const span& shape, semantic_tag tag, const ser_context& context, std::error_code& ec); (40) bool end_multi_dim(const ser_context& context, std::error_code& ec); (41) (1) Flushes whatever is buffered to the destination. (2) Indicates the begining of an object of indefinite length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (3) Indicates the begining of an object of known length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (4) Indicates the end of an object. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (5) Indicates the beginning of an indefinite length array. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (6) Indicates the beginning of an array of known length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (7) Indicates the end of an array. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (8) Writes the name part of an object name-value pair. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (9) Writes a null value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (10) Writes a boolean value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (11) Writes a text string value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (12) Writes a byte string value `source` with a generic tag. Type `ByteStringLike` must be a container that has member functions `data()` and `size()`, and member type `value_type` with size exactly 8 bits (since 0.152.0.) Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (13) Writes a byte string value `source` with a format specific tag, `ext_tag`. Type `ByteStringLike` must be a container that has member functions `data()` and `size()`, and member type `value_type` with size exactly 8 bits (since 0.152.0.) Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (14) Writes a non-negative integer value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (15) Writes a signed integer value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (16) Writes a half precision floating point value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (17) Writes a double precision floating point value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (18)-(33) Same as (2)-(17), except sets `ec` and returns `false` on parse errors. ### Examples ### Feeding json events directly to a `json_stream_encoder` ```cpp #include #include #include using namespace jsoncons; using boost::numeric::ublas::matrix; int main() { matrix A(2, 2); A(0, 0) = 1; A(0, 1) = 2; A(1, 0) = 3; A(1, 1) = 4; auto options = json_options{}; json_stream_encoder os(std::cout, options); os.begin_array(); for (std::size_t i = 0; i < A.size1(); ++i) { os.begin_array(); for (std::size_t j = 0; j < A.size2(); ++j) { os.double_value(A(i, j)); } os.end_array(); } os.end_array(); return 0; } ``` Output: ```json [ [1,2], [3,4] ] ``` ### See also [byte_string_view](../byte_string_view.md) jsoncons-1.3.2/doc/ref/corelib/basic_json_filter.md000066400000000000000000000651461477700171100223330ustar00rootroot00000000000000### jsoncons::basic_json_filter ```cpp #include template < typename CharT > class basic_json_filter ``` Defines an interface for filtering JSON events. `basic_json_filter` is noncopyable and nonmoveable. ![basic_json_filter](./diagrams/basic_json_filter.png) Aliases for common character types are provided: Type |Definition --------------------|------------------------------ json_filter |`basic_json_filter` wjson_filter |`basic_json_filter` #### Member types Member type |Definition ------------------------------------|------------------------------ `char_type`|CharT `string_view_type`|A non-owning view of a string, holds a pointer to character data and length. Supports conversion to and from strings. Will be typedefed to the C++ 17 [std::string view](http://en.cppreference.com/w/cpp/string/basic_string_view) if C++ 17 is detected or if `JSONCONS_HAS_STD_STRING_VIEW` is defined, otherwise proxied. #### Constructors basic_json_filter(basic_json_visitor& visitor) All JSON events that pass through the `basic_json_filter` go to the specified [visitor](basic_json_visitor.md). You must ensure that the `visitor` exists as long as does `basic_json_filter`, as `basic_json_filter` holds a pointer to but does not own this object. #### Accessors basic_json_visitor& destination() Returns a reference to the JSON visitor that sends json events to the destination handler. ### Inherited from [jsoncons::basic_json_visitor](basic_json_visitor.md) #### Public member functions void flush(); (1) bool begin_object(semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (2) bool begin_object(std::size_t length, semantic_tag tag=semantic_tag::none, const ser_context& context = ser_context()); (3) bool end_object(const ser_context& context = ser_context()); (4) bool begin_array(semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (5) bool begin_array(std::size_t length, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (6) bool end_array(const ser_context& context=ser_context()); (7) bool key(const string_view_type& name, const ser_context& context=ser_context()); (8) bool null_value(semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (9) bool bool_value(bool value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (10) bool string_value(const string_view_type& value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (11) bool byte_string_value(const byte_string_view& source, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (12) (until 0.152.0) template bool byte_string_value(const ByteStringLike& souce, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (12) (since 0.152.0) template bool byte_string_value(const ByteStringLike& souce, uint64_t ext_tag, const ser_context& context=ser_context()); (13) (since 0.152.0) bool uint64_value(uint64_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (14) bool int64_value(int64_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (15) bool half_value(uint16_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (16) bool double_value(double value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (17) bool begin_object(semantic_tag tag, const ser_context& context, std::error_code& ec); (18) bool begin_object(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec); (19) bool end_object(const ser_context& context, std::error_code& ec); (20) bool begin_array(semantic_tag tag, const ser_context& context, std::error_code& ec); (21) bool begin_array(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec); (22) bool end_array(const ser_context& context, std::error_code& ec); (23) bool key(const string_view_type& name, const ser_context& context, std::error_code& ec); (24) bool null_value(semantic_tag tag, const ser_context& context, std::error_code& ec); (25) bool bool_value(bool value, semantic_tag tag, const ser_context& context, std::error_code& ec); (26) bool string_value(const string_view_type& value, semantic_tag tag, const ser_context& context, std::error_code& ec); (27) bool byte_string_value(const byte_string_view& source, semantic_tag tag, const ser_context& context, std::error_code& ec); (28) (until 0.152.0) template bool byte_string_value(const ByteStringLike& source, semantic_tag tag, const ser_context& context, std::error_code& ec); (28) (since 0.152.0) template bool byte_string_value(const ByteStringLike& source, uint64_t ext_tag, const ser_context& context, std::error_code& ec); (29) (since 0.152.0) bool uint64_value(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (30) bool int64_value(int64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (31) bool half_value(uint16_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (32) bool double_value(double value, semantic_tag tag, const ser_context& context, std::error_code& ec); (33) template bool typed_array(const span& data, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (34) bool typed_array(half_arg_t, const span& s, semantic_tag tag = semantic_tag::none, const ser_context& context = ser_context()); (35) bool begin_multi_dim(const span& shape, semantic_tag tag, const ser_context& context); (36) bool end_multi_dim(const ser_context& context=ser_context()); (37) template bool typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (38) bool typed_array(half_arg_t, const span& s, semantic_tag tag, const ser_context& context, std::error_code& ec); (39) bool begin_multi_dim(const span& shape, semantic_tag tag, const ser_context& context, std::error_code& ec); (40) bool end_multi_dim(const ser_context& context, std::error_code& ec); (41) (1) Flushes whatever is buffered to the destination. (2) Indicates the begining of an object of indefinite length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (3) Indicates the begining of an object of known length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (4) Indicates the end of an object. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (5) Indicates the beginning of an indefinite length array. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (6) Indicates the beginning of an array of known length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (7) Indicates the end of an array. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (8) Writes the name part of an object name-value pair. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (9) Writes a null value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (10) Writes a boolean value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (11) Writes a text string value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (12) Writes a byte string value `source` with a generic tag. Type `ByteStringLike` must be a container that has member functions `data()` and `size()`, and member type `value_type` with size exactly 8 bits (since 0.152.0.) Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (13) Writes a byte string value `source` with a format specific tag, `ext_tag`. Type `ByteStringLike` must be a container that has member functions `data()` and `size()`, and member type `value_type` with size exactly 8 bits (since 0.152.0.) Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (14) Writes a non-negative integer value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (15) Writes a signed integer value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (16) Writes a half precision floating point value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (17) Writes a double precision floating point value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (18)-(33) Same as (2)-(17), except sets `ec` and returns `false` on parse errors. #### Private virtual functions virtual void visit_flush() = 0; (1) virtual bool visit_begin_object(semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; (2) virtual bool visit_begin_object(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec); (3) virtual bool visit_end_object(const ser_context& context, std::error_code& ec) = 0; (4) virtual bool visit_begin_array(semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; (5) virtual bool visit_begin_array(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec); (6) virtual bool visit_end_array(const ser_context& context, std::error_code& ec) = 0; (7) virtual bool visit_key(const string_view_type& name, const ser_context& context, std::error_code&) = 0; (8) virtual bool visit_null(semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; (9) virtual bool visit_bool(bool value, semantic_tag tag, const ser_context& context, std::error_code&) = 0; (10) virtual bool visit_string(const string_view_type& value, semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; (11) virtual bool visit_byte_string(const byte_string_view& value, semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; (12) virtual bool visit_byte_string(const byte_string_view& value, uint64_t ext_tag, const ser_context& context, std::error_code& ec); (13) virtual bool visit_uint64(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; (14) virtual bool visit_int64(int64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; (15) virtual bool visit_half(uint16_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (16) virtual bool visit_double(double value, semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; (17) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (18) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (19) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (20) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (21) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (22) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (23) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (24) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (25) virtual bool visit_typed_array(half_arg_t, const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (26) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (27) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (28) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (29) virtual bool visit_begin_multi_dim(const span& shape, semantic_tag tag, const ser_context& context, std::error_code& ec); (30) virtual bool visit_end_multi_dim(const ser_context& context, std::error_code& ec); (31) (1) Allows producers of json events to flush any buffered data. (2) Handles the beginning of an object of indefinite length. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (3) Handles the beginning of an object of known length. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (4) Handles the end of an object. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (5) Handles the beginning of an array of indefinite length. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (6) Handles the beginning of an array of known length. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (7) Handles the end of an array. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (8) Handles the name part of an object name-value pair. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (9) Handles a null value. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (10) Handles a boolean value. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (11) Handles a string value. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (12) Handles a byte string value associated with a generic tag. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (13) Handles a byte string value associated with a format specific tag. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (14) Handles a non-negative integer value. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (15) Handles a signed integer value. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (16) Handles a half precision floating point value. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (17) Handles a double precision floating point value. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. #### Parameters `tag` - a jsoncons semantic tag `context` - parse context information including line and column number `ec` - a parse error code #### Exceptions The overloads that do not take a `std::error_code&` parameter throw a [ser_error](ser_error.md) on parse errors, constructed with the error code as the error code argument and line and column from the `context`. The overloads that take a `std::error_code&` parameter set it to the error code and return `false` on parse errors. ### Examples #### Rename object member names with the built in filter [rename_object_key_filter](rename_object_key_filter.md) ```cpp #include #include #include using namespace jsoncons; int main() { std::string s = R"({"first":1,"second":2,"fourth":3,"fifth":4})"; json_stream_encoder encoder(std::cout); // Filters can be chained rename_object_key_filter filter2("fifth", "fourth", encoder); rename_object_key_filter filter1("fourth", "third", filter2); // A filter can be passed to any function that takes // a json_visitor ... std::cout << "(1) "; std::istringstream is(s); //json_reader reader(is, filter1); // (until 0.164.0) json_stream_reader reader(is, filter1); // (since 0.164.0) reader.read(); std::cout << '\n'; // or a json_visitor std::cout << "(2) "; ojson j = ojson::parse(s); j.dump(filter1); std::cout << '\n'; } ``` Output: ```json (1) {"first":1,"second":2,"third":3,"fourth":4} (2) {"first":1,"second":2,"third":3,"fourth":4} ``` #### Fix up names in an address book JSON file Input JSON file `address-book.json`: ```json { "address-book" : [ { "name":"Jane Roe", "email":"jane.roe@example.com" }, { "name":"John", "email" : "john.doe@example.com" } ] } ``` Suppose you want to break the name into a first name and last name, and report a warning when `name` does not contain a space or tab separated part. You can achieve the desired result by subclassing the [basic_json_filter](basic_json_filter.md) class, overriding the default methods for receiving name and string value events, and passing modified events on to the parent [json_visitor](basic_json_visitor.md) (which in this example will forward them to a [basic_json_encoder](basic_json_encoder.md).) ```cpp #include #include #include using namespace jsoncons; class name_fixup_filter : public json_filter { std::string member_name_; public: name_fixup_filter(json_visitor& visitor) : json_filter(visitor) { } private: bool visit_key(const string_view_type& name, const ser_context& context, std::error_code&) override { member_name_ = name; if (member_name_ != "name") { this->destination().key(name, context); } return true; } bool visit_string(const string_view_type& s, const ser_context& context, std::error_code&) override { if (member_name_ == "name") { std::size_t end_first = val.find_first_of(" \t"); std::size_t start_last = val.find_first_not_of(" \t", end_first); this->destination().key("first-name", context); string_view_type first = val.substr(0, end_first); this->destination().value(first, context); if (start_last != string_view_type::npos) { this->destination().key("last-name", context); string_view_type last = val.substr(start_last); this->destination().value(last, context); } else { std::cerr << "Incomplete name \"" << s << "\" at line " << context.line() << " and column " << context.column() << '\n'; } } else { this->destination().value(s, context); } return true; } }; ``` Configure a [rename_object_key_filter](rename_object_key_filter.md) to emit json events to a [basic_json_encoder](basic_json_encoder.md). ```cpp std::ofstream os("output/new-address-book.json"); json_stream_encoder encoder(os); name_fixup_filter filter(encoder); ``` Parse the input and send the json events through the filter ... ```cpp std::cout << "(1) "; std::ifstream is("input/address-book.json"); //json_reader reader(is, filter); // (until 0.164.0) json_stream_reader reader(is, filter); // (since 0.164.0) reader.read(); std:: << "\n"; ``` or read into a json value and write to the filter ```cpp std::cout << "(2) "; json j; is >> j; j.dump(filter); std:: << "\n"; ``` Output: ``` (1) Incomplete name "John" at line 9 and column 26 (2) Incomplete name "John" at line 0 and column 0 ``` Note that when filtering `json` events written from a `json` value to an output visitor, contexual line and column information in the original file has been lost. ``` The output JSON file `address-book-new.json` with name fixes is ```json { "address-book": [ { "first-name":"Jane", "last-name":"Roe", "email":"jane.roe@example.com" }, { "first-name":"John", "email":"john.doe@example.com" } ] } ``` ### See also [basic_json_visitor](basic_json_visitor.md) [byte_string_view](byte_string_view.md) jsoncons-1.3.2/doc/ref/corelib/basic_json_options.md000066400000000000000000000375241477700171100225400ustar00rootroot00000000000000### jsoncons::basic_json_options ```cpp #include template< typename CharT > class basic_json_options; ```
![basic_json_options](./diagrams/basic_json_options.png) Specifies options for reading and writing JSON text. Option|Reading|Writing|Default ------|-------|-------|------- nan_to_str|Substitute string with `NaN`, if enabled|Sets a string replacement for `NaN` when writing JSON|Unenabled inf_to_str|Substitute string with `infinity`, if enabled|Sets a string replacement for infinity when writing JSON|Unenabled neginf_to_str|Substitute string with `negative infinity`, if enabled|Sets a string replacement for negative infinity when writing JSON|Unenabled nan_to_num| |Sets a number replacement for `NaN` when writing JSON|Unenabled inf_to_num| |Sets a number replacement for `Infinity` when writing JSON|Unenabled neginf_to_num| |Sets a number replacement for `Negative Infinity` when writing JSON|Unenabled max_nesting_depth|Maximum nesting depth allowed when parsing JSON|Maximum nesting depth allowed when serializing JSON|1024 lossless_number|If `true`, parse numbers with exponents and fractional parts as strings with semantic tagging `semantic_tag::bigdec`.| |`false` allow_comments (since 1.3.0)|If 'true', allow (and ignore) comments when parsing JSON| |`true` allow_trailing_comma (since 1.3.0)|If 'true', an extra comma at the end of a list of JSON values in an object or array is allowed (and ignored)| |false err_handler (since 0.171.0)|Defines an [error handler](err_handler.md) for parsing JSON.| |`default_json_parsing` indent_size| |The indent size|4 spaces_around_colon| |Indicates [space option](spaces_option.md) for name separator (`:`).|space after spaces_around_comma| |Indicates [space option](spaces_option.md) for array value and object name/value pair separators (`,`).|space after pad_inside_object_braces| |Pad inside object braces|`false` pad_inside_array_brackets| |Pad inside array brackets|`false` bigint_format| |Specifies which [bigint format](bigint_chars_format.md) to use when serializing json.|`bignum_format_kind::raw` (since 1.0.0) bignum_format| |Specifies which [bignum format](bignum_format_kind.md) to use when serializing json. |`bignum_format_kind::raw` byte_string_format| |Overrides [byte string format](byte_string_chars_format.md) when serializing json. |[byte_string_chars_format::base64url](byte_string_chars_format.md) float_format| |Overrides [floating point format](float_chars_format.md) when serializing to JSON. |[float_chars_format::general](float_chars_format.md) precision| |Overrides floating point precision when serializing json.|shortest representation escape_all_non_ascii| |Escape all non-ascii characters. |`false` escape_solidus| |Escape the solidus ('/') character. |`false` new_line_chars| |New line characters|"\n" line_length_limit| |Line length limit|120 object_object_line_splits| |For an object whose parent is an object, set whether that object is split on a new line, or if its members are split on multiple lines. |[line_split_kind::multi_line](line_split_kind.md) array_object_line_splits| |For an object whose parent is an array, set whether that object is split on a new line, or if its members are split on multiple lines. |[line_split_kind::multi_line](line_split_kind.md) object_array_line_splits| |For an array whose parent is an object, set whether that array is split on a new line, or if its elements are split on multiple lines. |[line_split_kind::same_line](line_split_kind.md) array_array_line_splits| |For an array whose parent is an array, set whether that array is split on a new line, or if its elements are split on multiple lines. |[line_split_kind::new_line](line_split_kind.md) The default floating point format is [float_chars_format::general](float_chars_format.md). The default precision is shortest representation, e.g. 1.1 read will remain `1.1` when written, and not become `1.1000000000000001` (an equivalent but longer representation.) Trailing zeros are removed, except one immediately following the decimal point. The period character (.) is always used as the decimal point, non English locales are ignored. Aliases for common character types are provided: Type |Definition --------------------|------------------------------ `json_options` |`basic_json_options` `wjson_options` |`basic_json_options` #### Member constants static const uint8_t indent_size_default = 4; The default size indent is 4 static const size_t line_length_limit_default = 120; The default line length limit is 120 Member type |Definition ------------------------------------|------------------------------ `char_type`|`CharT` `string_type`|`std::basic_string` #### Constructors basic_json_options() Constructs a `basic_json_options` with default values. basic_json_options(const basic_json_options& other) Copy constructor. basic_json_options(basic_json_options&& other) Move constructor. #### Modifiers void max_nesting_depth(int depth) The maximum nesting depth allowed when decoding and encoding JSON. Default is 1024. Parsing can have an arbitrarily large depth limited only by available memory. Serializing a [basic_json](basic_json.md) to JSON is limited by stack size. basic_json_options& decode_escaped_unicode(bool value); Indicates whether to interpret escaped unicode in JSON strings. Defaults to true. basic_json_options& nan_to_str(const string_type& value, bool enable_inverse = true); Sets a string replacement for `NaN` when writing JSON, and indicate whether it is also to be used when reading JSON. basic_json_options& inf_to_str(const string_type& value, bool enable_inverse = true); Sets a string replacement for infinity when writing JSON, and indicate whether it is also to be used when reading JSON. basic_json_options& neginf_to_str(const string_type& value, bool enable_inverse = true); Sets a string replacement for negative infinity when writing JSON, and indicate whether it is also to be used when reading JSON. basic_json_options& nan_to_num(const string_type& value); Sets a number replacement for `NaN` when writing JSON basic_json_options& inf_to_num(const string_type& value); Sets a number replacement for `Infinity` when writing JSON basic_json_options& neginf_to_num(const string_type& value); Sets a number replacement for `Negative Infinity` when writing JSON basic_json_options& lossless_number(bool value); If set to `true`, parse numbers with exponents and fractional parts as strings with semantic tagging `semantic_tag::bigdec`. Defaults to `false`. basic_json_options& allow_comments(bool value); If set to `true`, an extra comma at the end of a list of JSON values in an object or array is allowed (and ignored). Defaults to `true`. basic_json_options& allow_trailing_comma(bool value); If set to `true`, an extra comma at the end of a list of JSON values in an object or array is allowed (and ignored). Defaults to `false`. basic_json_options& indent_size(uint8_t value) The indent size, the default is 4. basic_json_options& spaces_around_colon(spaces_option value) Indicates [space option](spaces_option.md) for name separator (`:`). Default is space after. basic_json_options& spaces_around_comma(spaces_option value) Indicates [space option](spaces_option.md) for array value and object name/value pair separators (`,`). Default is space after. basic_json_options& pad_inside_object_braces(bool value) Default is `false` basic_json_options& pad_inside_array_brackets(bool value) Default is `false` basic_json_options& bignum_format(bignum_format_kind value) Overrides [bignum format](bignum_format_kind.md) when serializing json. The default is [bignum_format_kind::base10](bignum_format_kind.md). basic_json_options& byte_string_format(byte_string_chars_format value) Overrides [byte string format](byte_string_chars_format.md) when serializing json. The default is [byte_string_chars_format::base64url](byte_string_chars_format.md). basic_json_options& float_format(float_chars_format value); Overrides [floating point format](float_chars_format.md) when serializing to JSON. The default is [float_chars_format::general](float_chars_format.md). basic_json_options& precision(int8_t value) Overrides floating point precision when serializing json. The default is shortest representation. basic_json_options& escape_all_non_ascii(bool value) Escape all non-ascii characters. The default is `false`. basic_json_options& escape_solidus(bool value) Escape the solidus ('/') character. The default is `false`. basic_json_options& new_line_chars(const string_type& value) Defaults to "\n" basic_json_options& line_length_limit(std::size_t value) basic_json_options& object_object_line_splits(line_split_kind value) For an object whose parent is an object, set whether that object is split on a new line, or if its members are split on multiple lines. The default is [line_split_kind::multi_line](line_split_kind.md). basic_json_options& array_object_line_splits(line_split_kind value) For an object whose parent is an array, set whether that object is split on a new line, or if its members are split on multiple lines. The default is [line_split_kind::multi_line](line_split_kind.md). basic_json_options& object_array_line_splits(line_split_kind value) For an array whose parent is an object, set whether that array is split on a new line, or if its elements are split on multiple lines. The default is [line_split_kind::same_line](line_split_kind.md). basic_json_options& array_array_line_splits(line_split_kind value) For an array whose parent is an array, set whether that array is split on a new line, or if its elements are split on multiple lines. The default is [line_split_kind::new_line](line_split_kind.md). ### Examples #### Default NaN and inf replacement ```cpp json obj; obj["field1"] = std::sqrt(-1.0); obj["field2"] = 1.79e308*1000; obj["field3"] = -1.79e308*1000; std::cout << obj << '\n'; ``` Output: ```json {"field1":null,"field2":null,"field3":null} ``` #### User specified `Nan` and `Inf` replacement ```cpp json obj; obj["field1"] = std::sqrt(-1.0); obj["field2"] = 1.79e308*1000; obj["field3"] = -1.79e308*1000; auto options = json_options{} .nan_to_num("null"); // default is "null" .inf_to_num("1e9999"); // default is "null" std::cout << pretty_print(obj,options) << '\n'; ``` Output: ```json { "field1":null, "field2":1e9999, "field3":-1e9999 } ``` #### Decimal precision By default, jsoncons parses a number with an exponent or fractional part into a double precision floating point number. If you wish, you can keep the number as a string with semantic tagging `bigdec`, using the `lossless_number` option. You can then put it into a `float`, `double`, a boost multiprecision number, or whatever type you want. ```cpp int main() { std::string s = R"( { "a" : 12.00, "b" : 1.23456789012345678901234567890 } )"; // Default json j = json::parse(s); std::cout.precision(15); // Access as string std::cout << "(1) a: " << j["a"].as() << ", b: " << j["b"].as() << "\n"; // Access as double std::cout << "(2) a: " << j["a"].as() << ", b: " << j["b"].as() << "\n\n"; // Using lossless_number option auto options = json_options{} .lossless_number(true); json j2 = json::parse(s, options); // Access as string std::cout << "(3) a: " << j2["a"].as() << ", b: " << j2["b"].as() << "\n"; // Access as double std::cout << "(4) a: " << j2["a"].as() << ", b: " << j2["b"].as() << "\n\n"; } ``` Output: ``` (1) a: 12.0, b: 1.2345678901234567 (2) a: 12, b: 1.23456789012346 (3) a: 12.00, b: 1.23456789012345678901234567890 (4) a: 12, b: 1.23456789012346 ``` #### Object-array block formatting ```cpp json j; j["verts"] = json(json_array_arg, {1, 2, 3}); j["normals"] = json(json_array_arg, {1, 0, 1}); j["uvs"] = json(json_array_arg, {0, 0, 1, 1}); std::cout << "Default (same line)" << '\n'; std::cout << pretty_print(j) << '\n'; std::cout << "New line" << '\n'; auto options1 = json_options{} .object_array_line_splits(line_split_kind::new_line); std::cout << pretty_print(j,options1) << '\n'; std::cout << "Multi line" << '\n'; auto options2 = json_options{} .object_array_line_splits(line_split_kind::multi_line); std::cout << pretty_print(j,options2) << '\n'; ``` Output: Default (same line) ```json { "normals": [1,0,1], "uvs": [0,0,1,1], "verts": [1,2,3] } ``` New line ```json { "normals": [ 1,0,1 ], "uvs": [ 0,0,1,1 ], "verts": [ 1,2,3 ] } ``` Multi line ```json { "normals": [ 1, 0, 1 ], "uvs": [ 0, 0, 1, 1 ], "verts": [ 1, 2, 3 ] } ``` #### Array-array block formatting ```cpp json j; j["data"]["id"] = json(json_array_arg, {0,1,2,3,4,5,6,7}); j["data"]["item"] = json(json_array_arg, {json(json_array_arg, {2}), json(json_array_arg, {4,5,2,3}), json(json_array_arg, {4}), json(json_array_arg, {4,5,2,3}), json(json_array_arg, {2}), json(json_array_arg, {4,5,3}), json(json_array_arg, {2}), json(json_array_arg, {4,3})}); std::cout << "Default (new line)" << '\n'; std::cout << pretty_print(j) << '\n'; std::cout << "Same line" << '\n'; auto options1 = json_options{} .array_array_line_splits(line_split_kind::same_line); std::cout << pretty_print(j, options1) << '\n'; std::cout << "Multi line" << '\n'; auto options2 = json_options{} .array_array_line_splits(line_split_kind::multi_line); std::cout << pretty_print(j, options2) << '\n'; ``` Output: Default (new line) ```json { "data": { "id": [0,1,2,3,4,5,6,7], "item": [ [2], [4,5,2,3], [4], [4,5,2,3], [2], [4,5,3], [2], [4,3] ] } } ``` Same line ```json { "data": { "id": [0,1,2,3,4,5,6,7], "item": [[2],[4,5,2,3],[4],[4,5,2,3],[2],[4,5,3],[2],[4,3]] } } ``` Multi line ```json { "data": { "id": [ 0,1,2,3,4,5,6,7 ], "item": [ [ 2 ], [ 4, 5, 2, 3 ], [ 4 ], [ 4, 5, 2, 3 ], [ 2 ], [ 4, 5, 3 ], [ 2 ], [ 4, 3 ] ] } } ``` #### Allow trailing commas ```cpp int main() { std::string s = R"( { "first" : 1, "second" : 2, } )"; // Default try { auto j = json::parse(s); } catch (const ser_error& e) { std::cout << "(1) " << e.what() << "\n\n"; } // Allow trailing commas // until 0.170.0 // auto j = json::parse(s, allow_trailing_commas()); // since 0.171.0 // auto options = json_options{} // .err_handler(allow_trailing_commas()); // auto j = json::parse(s, options); // since 1.3.0 auto options = json_options{} .allow_trailing_comma(true)); auto j = json::parse(s, options); std::cout << "(2)" << j << "\n\n"; } ``` Output: ``` (1) Extra comma at line 5 and column 5 (2) {"first":1,"second":2} ``` jsoncons-1.3.2/doc/ref/corelib/basic_json_parser.md000066400000000000000000000173341477700171100223360ustar00rootroot00000000000000### jsoncons::basic_json_parser ```cpp #include template< typename CharT, typename TempAllocator = std::allocator > class basic_json_parser; ``` A `basic_json_parser` is an incremental json parser. It can be fed its input in chunks, and does not require an entire file to be loaded in memory at one time. `basic_json_parser` is used by the push parser [basic_json_reader](basic_json_reader.md), and by the pull parser [basic_json_cursor](basic_json_cursor.md). `basic_json_parser` is noncopyable and nonmoveable. Aliases for common character types are provided: Type |Definition --------------------|------------------------------ json_parser |`jsoncons::basic_json_parser>` wjson_parser |`jsoncons::basic_json_parser>` #### Member types Type |Definition ---------------------------|------------------------------ char_type |CharT temp_allocator_type |TempAllocator #### Constructors basic_json_parser(const TempAllocator& temp_alloc = TempAllocator()); (1) basic_json_parser(const basic_json_decode_options& options, const TempAllocator& temp_alloc = TempAllocator()); (2) basic_json_parser(std::function err_handler, const TempAllocator& temp_alloc = TempAllocator()); (3) (deprecated since 0.171.0) basic_json_parser(const basic_json_decode_options& options, std::function err_handler, (4) (deprecated since 0.171.0) const TempAllocator& temp_alloc = TempAllocator()); (1) Constructs a `json_parser` that uses default [basic_json_options](basic_json_options.md) and a default [err_handler](err_handler.md). (2) Constructs a `json_parser` that uses the specified [basic_json_options](basic_json_options.md) and a default [err_handler](err_handler.md). (3) Constructs a `json_parser` that uses default [basic_json_options](basic_json_options.md) and a specified [err_handler](err_handler.md). (4) Constructs a `json_parser` that uses the specified [basic_json_options](basic_json_options.md) and a specified [err_handler](err_handler.md). #### Member functions void update(const string_view_type& sv) void update(const CharT* data, std::size_t length) (until 1.0.0, since 1.1.0) Update the parser with a chunk of JSON bool done() const Returns `true` when the parser has consumed a complete JSON text, `false` otherwise bool stopped() const Returns `true` if the parser is stopped, `false` otherwise. The parser may enter a stopped state as a result of a visitor function returning `false`, an error occurred, or after having consumed a complete JSON text. bool finished() const Returns `true` if the parser is finished parsing, `false` otherwise. bool source_exhausted() const Returns `true` if the input in the source buffer has been exhausted, `false` otherwise void parse_some(json_visitor& visitor) Parses the source until a complete json text has been consumed or the source has been exhausted. Parse events are sent to the supplied `visitor`. Throws a [ser_error](ser_error.md) if parsing fails. void parse_some(json_visitor& visitor, std::error_code& ec) Parses the source until a complete json text has been consumed or the source has been exhausted. Parse events are sent to the supplied `visitor`. Sets `ec` to a [json_errc](jsoncons::json_errc.md) if parsing fails. void finish_parse(json_visitor& visitor) Called after `source_exhausted()` is `true` and there is no more input. Repeatedly calls `parse_some(visitor)` until `finished()` returns `true` Throws a [ser_error](ser_error.md) if parsing fails. void finish_parse(json_visitor& visitor, std::error_code& ec) Called after `source_exhausted()` is `true` and there is no more input. Repeatedly calls `parse_some(visitor)` until `finished()` returns `true` Sets `ec` to a [json_errc](jsoncons::json_errc.md) if parsing fails. void skip_bom() Reads the next JSON text from the stream and reports JSON events to a [basic_json_visitor](basic_json_visitor.md), such as a [json_decoder](json_decoder.md). Throws a [ser_error](ser_error.md) if parsing fails. void check_done() Throws if there are any unconsumed non-whitespace characters in the input. Throws a [ser_error](ser_error.md) if parsing fails. void check_done(std::error_code& ec) Sets `ec` to a [json_errc](jsoncons::json_errc.md) if parsing fails. void reset() const Resets the state of the parser to its initial state. In this state `stopped()` returns `false` and `done()` returns `false`. void restart() const Resets the `stopped` state of the parser to `false`, allowing parsing to continue. ### Examples #### nan, inf, and -inf substitition ```cpp int main() { std::string s = R"( { "A" : "NaN", "B" : "Infinity", "C" : "-Infinity" } )"; auto options = json_options{} .nan_to_str("NaN") .inf_to_str("Infinity"); json_parser parser(options); jsoncons::json_decoder decoder; try { parser.update(s); parser.parse_some(decoder); parser.finish_parse(decoder); parser.check_done(); } catch (const ser_error& e) { std::cout << e.what() << '\n'; } json j = decoder.get_result(); // performs move if (j["A"].is()) { std::cout << "A: " << j["A"].as() << '\n'; } if (j["B"].is()) { std::cout << "B: " << j["B"].as() << '\n'; } if (j["C"].is()) { std::cout << "C: " << j["C"].as() << '\n'; } } ``` Output: ``` A: nan B: inf C: -inf ``` #### Incremental parsing (until 1.0.0, since 1.1.0) ```cpp #include #include int main() { jsoncons::json_decoder decoder; jsoncons::json_parser parser; try { parser.update("[fal"); parser.parse_some(decoder); std::cout << "(1) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n"; parser.update("se,"); parser.parse_some(decoder); std::cout << "(2) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n"; parser.update("9"); parser.parse_some(decoder); std::cout << "(3) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n"; parser.update("0]"); parser.parse_some(decoder); std::cout << "(4) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n"; parser.finish_parse(decoder); std::cout << "(5) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n"; parser.check_done(); std::cout << "(6) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n"; jsoncons::json j = decoder.get_result(); std::cout << "(7) " << j << "\n\n"; } catch (const jsoncons::ser_error& e) { std::cout << e.what() << '\n'; } } ``` Output: ``` (1) done: false, source_exhausted: true (2) done: false, source_exhausted: true (3) done: false, source_exhausted: true (4) done: false, source_exhausted: true (5) done: true, source_exhausted: true (6) done: true, source_exhausted: true (7) [false,90] ``` jsoncons-1.3.2/doc/ref/corelib/basic_json_reader.md000066400000000000000000000222001477700171100222700ustar00rootroot00000000000000### jsoncons::basic_json_reader ```cpp #include template< typename CharT, typename Source=jsoncons::stream_source, typename TempAllocator=std::allocator > class basic_json_reader ``` `basic_json_reader` uses the incremental parser [basic_json_parser](basic_json_parser.md) to read arbitrarily large files in chunks. A `basic_json_reader` can read a sequence of JSON texts from a stream, using `read_next()`, which omits the check for unconsumed non-whitespace characters. `basic_json_reader` is noncopyable and nonmoveable. A number of specializations for common character types are defined: Type |Definition ---------------------------|------------------------------ `json_string_reader` |`basic_json_reader>` (since 0.164.0) `wjson_string_reader` |`basic_json_reader>` (since 0.164.0) `json_stream_reader` |`basic_json_reader>` (since 0.164.0) `wjson_stream_reader` |`basic_json_reader>` (since 0.164.0) `json_reader` |Constructible from either a string or stream (deprecated since 0.164.0) `wjson_reader` |Constructible from either a wide character string or stream (deprecated since 0.164.0) #### Member types Type |Definition ---------------------------|------------------------------ char_type |CharT source_type |Source string_view_type | #### Constructors template explicit basic_json_reader(Sourceable&& source, (1) const TempAllocator& alloc = TempAllocator()); template basic_json_reader(Sourceable&& source, const basic_json_options& options, const TempAllocator& alloc = TempAllocator()); (2) template basic_json_reader(Sourceable&& source, std::function err_handler, (3) (deprecated in 0.171.0) const TempAllocator& alloc = TempAllocator()); template basic_json_reader(Sourceable&& source, const basic_json_options& options, (4) (deprecated in 0.171.0) std::function err_handler, const TempAllocator& alloc = TempAllocator()); template basic_json_reader(Sourceable&& source, (5) basic_json_visitor& visitor, const TempAllocator& alloc = TempAllocator()); template basic_json_reader(Sourceable&& source, basic_json_visitor& visitor, (6) const basic_json_options& options, const TempAllocator& alloc = TempAllocator()); template basic_json_reader(Sourceable&& source, basic_json_visitor& visitor, (7) (deprecated in 0.171.0) std::function err_handler, const TempAllocator& alloc = TempAllocator()); template basic_json_reader(Sourceable&& source, basic_json_visitor& visitor, (8) (deprecated in 0.171.0) const basic_json_options& options, std::function err_handler, const TempAllocator& alloc = TempAllocator()); Constructors (1)-(4) use a default [basic_json_visitor](basic_json_visitor.md) that discards the JSON parse events, and are for validation only. (1) Constructs a `basic_json_reader` that reads from a character sequence or stream `source`, uses default [options](basic_json_options.md) and a default [JSON parsing error handling](err_handler.md). (2) Constructs a `basic_json_reader` that reads from a character sequence or stream `source`, uses the specified [options](basic_json_options.md) and a default [JSON parsing error handling](err_handler.md). (3) Constructs a `basic_json_reader` that reads from a character sequence or stream `source`, uses default [options](basic_json_options.md) and a specified [JSON parsing error handling](err_handler.md). (4) Constructs a `basic_json_reader` that reads from a character sequence or stream `source`, uses the specified [options](basic_json_options.md) and a specified [JSON parsing error handling](err_handler.md). Constructors (5)-(8) take a user supplied [basic_json_visitor](basic_json_visitor.md) that receives JSON parse events, such as a [json_decoder](json_decoder). (5) Constructs a `basic_json_reader` that reads from a character sequence or stream `source`, emits JSON parse events to the specified [basic_json_visitor](basic_json_visitor.md), and uses default [options](basic_json_options.md) and a default [JSON parsing error handling](err_handler.md). (6) Constructs a `basic_json_reader` that reads from a character sequence or stream `source`, emits JSON parse events to the specified [basic_json_visitor](basic_json_visitor.md) and uses the specified [options](basic_json_options.md) and a default [JSON parsing error handling](err_handler.md). (7) Constructs a `basic_json_reader` that reads from a character sequence or stream `source`, emits JSON parse events to the specified [basic_json_visitor](basic_json_visitor.md) and uses default [options](basic_json_options.md) and a specified [JSON parsing error handling](err_handler.md). (8) Constructs a `basic_json_reader` that reads from a character sequence or stream `source`, emits JSON parse events to the specified [basic_json_visitor](basic_json_visitor.md) and uses the specified [options](basic_json_options.md) and a specified [JSON parsing error handling](err_handler.md). Note: It is the programmer's responsibility to ensure that `basic_json_reader` does not outlive any source or visitor passed in the constuctor, as `basic_json_reader` holds pointers to but does not own these resources. #### Parameters `source` - a value from which a `source_type` is constructible. #### Member functions bool eof() const Returns `true` when there are no more JSON texts to be read from the stream, `false` otherwise void read(); (1) void read(std::error_code& ec); (2) Reads the next JSON text from the stream and reports JSON events to a [basic_json_visitor](basic_json_visitor.md), such as a [json_decoder](json_decoder.md). Override (1) throws if parsing fails, or there are any unconsumed non-whitespace characters left in the input. Override (2) sets `ec` to a [json_errc](jsoncons::json_errc.md) if parsing fails or if there are any unconsumed non-whitespace characters left in the input. void read_next() void read_next(std::error_code& ec) Reads the next JSON text from the stream and reports JSON events to a [basic_json_visitor](basic_json_visitor.md), such as a [json_decoder](json_decoder.md). Override (1) throws [ser_error](ser_error.md) if parsing fails. Override (2) sets `ec` to a [json_errc](jsoncons::json_errc.md) if parsing fails. void check_done(); (1) void check_done(std::error_code& ec); (2) Override (1) throws if there are any unconsumed non-whitespace characters in the input. Override (2) sets `ec` to a [json_errc](jsoncons::json_errc.md) if there are any unconsumed non-whitespace characters left in the input. std::size_t line() const std::size_t column() const ### Examples #### Parsing JSON text with exceptions ``` std::string input = R"({"field1"{}})"; json_decoder decoder; json_string_reader reader(input,decoder); try { reader.read(); json j = decoder.get_result(); } catch (const ser_error& e) { std::cout << e.what() << '\n'; } ``` Output: ``` Expected name separator ':' at line 1 and column 10 ``` #### Parsing JSON text with error codes ``` std::string input = R"({"field1":ru})"; std::istringstream is(input); json_decoder decoder; json_stream_reader reader(is,decoder); std::error_code ec; reader.read(ec); if (!ec) { json j = decoder.get_result(); } else { std::cerr << ec.message() << " at line " << reader.line() << " and column " << reader.column() << '\n'; } ``` Output: ``` Expected value at line 1 and column 11 ``` #### Reading a sequence of JSON texts from a stream `jsoncons` supports reading a sequence of JSON texts, such as shown below (`json-texts.json`): ```json {"a":1,"b":2,"c":3} {"a":4,"b":5,"c":6} {"a":7,"b":8,"c":9} ``` This is the code that reads them: ```cpp std::ifstream is("json-texts.json"); if (!is.is_open()) { throw std::runtime_error("Cannot open file"); } json_decoder decoder; json_stream_reader reader(is,decoder); while (!reader.eof()) { reader.read_next(); // until 1.0.0 //if (!reader.eof()) //{ // json j = decoder.get_result(); // std::cout << j << '\n'; //} // since 1.0.0 json j = decoder.get_result(); std::cout << j << '\n'; } ``` Output: ```json {"a":1,"b":2,"c":3} {"a":4,"b":5,"c":6} {"a":7,"b":8,"c":9} ``` jsoncons-1.3.2/doc/ref/corelib/basic_json_visitor.md000066400000000000000000000522171477700171100225400ustar00rootroot00000000000000### jsoncons::basic_json_visitor ```cpp #include template < typename CharT > class basic_json_visitor ``` Defines an interface for producing and consuming JSON events. Aliases for common character types are provided: Type |Definition --------------------|------------------------------ json_visitor |`basic_json_visitor` wjson_visitor |`basic_json_visitor` #### Member types Member type |Definition ------------------------------------|------------------------------ `char_type`|CharT `string_view_type`|A non-owning view of a string, holds a pointer to character data and length. Supports conversion to and from strings. Will be typedefed to the C++ 17 [std::string view](http://en.cppreference.com/w/cpp/string/basic_string_view) if C++ 17 is detected or if `JSONCONS_HAS_STD_STRING_VIEW` is defined, otherwise proxied. #### Public event producer interface void flush(); (1) bool begin_object(semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (2) bool begin_object(std::size_t length, semantic_tag tag=semantic_tag::none, const ser_context& context = ser_context()); (3) bool end_object(const ser_context& context = ser_context()); (4) bool begin_array(semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (5) bool begin_array(std::size_t length, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (6) bool end_array(const ser_context& context=ser_context()); (7) bool key(const string_view_type& name, const ser_context& context=ser_context()); (8) bool null_value(semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (9) bool bool_value(bool value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (10) bool string_value(const string_view_type& value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (11) bool byte_string_value(const byte_string_view& source, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (12) (until 0.152.0) template bool byte_string_value(const ByteStringLike& souce, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (12) (since 0.152.0) template bool byte_string_value(const ByteStringLike& souce, uint64_t ext_tag, const ser_context& context=ser_context()); (13) (since 0.152.0) bool uint64_value(uint64_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (14) bool int64_value(int64_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (15) bool half_value(uint16_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (16) bool double_value(double value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (17) bool begin_object(semantic_tag tag, const ser_context& context, std::error_code& ec); (18) bool begin_object(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec); (19) bool end_object(const ser_context& context, std::error_code& ec); (20) bool begin_array(semantic_tag tag, const ser_context& context, std::error_code& ec); (21) bool begin_array(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec); (22) bool end_array(const ser_context& context, std::error_code& ec); (23) bool key(const string_view_type& name, const ser_context& context, std::error_code& ec); (24) bool null_value(semantic_tag tag, const ser_context& context, std::error_code& ec); (25) bool bool_value(bool value, semantic_tag tag, const ser_context& context, std::error_code& ec); (26) bool string_value(const string_view_type& value, semantic_tag tag, const ser_context& context, std::error_code& ec); (27) bool byte_string_value(const byte_string_view& source, semantic_tag tag, const ser_context& context, std::error_code& ec); (28) (until 0.152.0) template bool byte_string_value(const ByteStringLike& source, semantic_tag tag, const ser_context& context, std::error_code& ec); (28) (since 0.152.0) template bool byte_string_value(const ByteStringLike& source, uint64_t ext_tag, const ser_context& context, std::error_code& ec); (29) (since 0.152.0) bool uint64_value(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (30) bool int64_value(int64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (31) bool half_value(uint16_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (32) bool double_value(double value, semantic_tag tag, const ser_context& context, std::error_code& ec); (33) template bool typed_array(const span& data, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (34) bool typed_array(half_arg_t, const span& s, semantic_tag tag = semantic_tag::none, const ser_context& context = ser_context()); (35) bool begin_multi_dim(const span& shape, semantic_tag tag, const ser_context& context); (36) bool end_multi_dim(const ser_context& context=ser_context()); (37) template bool typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (38) bool typed_array(half_arg_t, const span& s, semantic_tag tag, const ser_context& context, std::error_code& ec); (39) bool begin_multi_dim(const span& shape, semantic_tag tag, const ser_context& context, std::error_code& ec); (40) bool end_multi_dim(const ser_context& context, std::error_code& ec); (41) (1) Flushes whatever is buffered to the destination. (2) Indicates the begining of an object of indefinite length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (3) Indicates the begining of an object of known length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (4) Indicates the end of an object. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (5) Indicates the beginning of an indefinite length array. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (6) Indicates the beginning of an array of known length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (7) Indicates the end of an array. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (8) Writes the name part of an object name-value pair. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (9) Writes a null value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (10) Writes a boolean value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (11) Writes a text string value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (12) Writes a byte string value `source` with a generic tag. Type `ByteStringLike` must be a container that has member functions `data()` and `size()`, and member type `value_type` with size exactly 8 bits (since 0.152.0.) Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (13) Writes a byte string value `source` with a format specific tag, `ext_tag`. Type `ByteStringLike` must be a container that has member functions `data()` and `size()`, and member type `value_type` with size exactly 8 bits (since 0.152.0.) Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (14) Writes a non-negative integer value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (15) Writes a signed integer value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (16) Writes a half precision floating point value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (17) Writes a double precision floating point value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (18)-(33) Same as (2)-(17), except sets `ec` and returns `false` on parse errors. #### Private event consumer interface virtual void visit_flush() = 0; (1) virtual bool visit_begin_object(semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; (2) virtual bool visit_begin_object(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec); (3) virtual bool visit_end_object(const ser_context& context, std::error_code& ec) = 0; (4) virtual bool visit_begin_array(semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; (5) virtual bool visit_begin_array(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec); (6) virtual bool visit_end_array(const ser_context& context, std::error_code& ec) = 0; (7) virtual bool visit_key(const string_view_type& name, const ser_context& context, std::error_code&) = 0; (8) virtual bool visit_null(semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; (9) virtual bool visit_bool(bool value, semantic_tag tag, const ser_context& context, std::error_code&) = 0; (10) virtual bool visit_string(const string_view_type& value, semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; (11) virtual bool visit_byte_string(const byte_string_view& value, semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; (12) virtual bool visit_byte_string(const byte_string_view& value, uint64_t ext_tag, const ser_context& context, std::error_code& ec); (13) virtual bool visit_uint64(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; (14) virtual bool visit_int64(int64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; (15) virtual bool visit_half(uint16_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (16) virtual bool visit_double(double value, semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; (17) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (18) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (19) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (20) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (21) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (22) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (23) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (24) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (25) virtual bool visit_typed_array(half_arg_t, const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (26) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (27) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (28) virtual bool visit_typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (29) virtual bool visit_begin_multi_dim(const span& shape, semantic_tag tag, const ser_context& context, std::error_code& ec); (30) virtual bool visit_end_multi_dim(const ser_context& context, std::error_code& ec); (31) (1) Allows producers of json events to flush any buffered data. (2) Handles the beginning of an object of indefinite length. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (3) Handles the beginning of an object of known length. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (4) Handles the end of an object. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (5) Handles the beginning of an array of indefinite length. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (6) Handles the beginning of an array of known length. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (7) Handles the end of an array. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (8) Handles the name part of an object name-value pair. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (9) Handles a null value. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (10) Handles a boolean value. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (11) Handles a string value. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (12) Handles a byte string value associated with a generic tag. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (13) Handles a byte string value associated with a format specific tag. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (14) Handles a non-negative integer value. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (15) Handles a signed integer value. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (16) Handles a half precision floating point value. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. (17) Handles a double precision floating point value. Returns `true` if the producer should generate more events, `false` otherwise. Sets `ec` and returns `false` on parse errors. #### Parameters `tag` - a jsoncons semantic tag `context` - parse context information including line and column number `ec` - a parse error code #### Exceptions The overloads that do not take a `std::error_code&` parameter throw a [ser_error](ser_error.md) on parse errors, constructed with the error code as the error code argument and line and column from the `context`. The overloads that take a `std::error_code&` parameter set it to the error code and return `false` on parse errors. ### See also [semantic_tag](semantic_tag.md) [basic_default_json_visitor](basic_default_json_visitor.md) [basic_json_filter](basic_json_filter.md) [byte_string_view](../byte_string_view.md) jsoncons-1.3.2/doc/ref/corelib/basic_staj_event.md000066400000000000000000000060521477700171100221460ustar00rootroot00000000000000### jsoncons::basic_staj_event ```cpp #include template class basic_staj_event ``` A JSON-like parse event. Aliases for common character types are provided: Type |Definition --------------------|------------------------------ staj_event |`basic_staj_event` wstaj_event |`basic_staj_event` The `event_type()` function returns the [event type](doc/ref/corelib/staj_event_type.md). You can use the `get()` function to access a string, number, or boolean value. | Event type | Sample data | Valid accessors | |-------------------|------------------------|-----------------| | begin_object | | | | end_object | | | | begin_array | | | | end_array | | | | key | "foo" | `get()`
`get`
`get()` | | string_value | "1000" | `get()`
`get`
`get()`
`get()`
`get()` | | byte_string_value | 0x660x6F0x6F | `get()`
`get()` | | int64_value | -1000 | `get()`
`get()`
`get`
`get()` | | uint64_value | 1000 | `get()`
`get()`
`get()`
`get()`
`get()` | | half_value | 1.5 (as double) | `get()`
`get()`
`get()` | | double_value | 125.72 | `get()`
`get()` | | bool_value | true | `get()`
`get()` | | null_value | | `get()` | #### Member functions staj_event_type event_type() const noexcept; Returns a [staj_event_type](staj_event_type.md) for this event. semantic_tag tag() const noexcept; Returns a [semantic_tag](semantic_tag.md) for this event. uint64_t ext_tag() const If `tag()` == `semantic_tag::ext`, returns a format specific tag associated with a byte string value, otherwise return 0. An example is a MessagePack `type` in the range 0-127 associated with the MessagePack ext format family, or a CBOR tag preceeding a byte string. size_t size() const If `event_type()` is a `staj_event_type::key` or a `staj_event_type::string_value` or a `staj_event_type::byte_string_value`, returns the size of the key or string or byte string value. If `event_type()` is a `staj_event_type::begin_object` or a `staj_event_type::begin_array`, returns the size of the object or array if known, otherwise 0. For all other event types, returns 0. template T get() const; Attempts to convert the json value to the template value type. template T get(std::error_code& ec) const; Attempts to convert the json value to the template value type. jsoncons-1.3.2/doc/ref/corelib/bigint_chars_format.md000066400000000000000000000040331477700171100226440ustar00rootroot00000000000000### jsoncons::bigint_chars_format (deprecated in 1.0.0) ```cpp #include enum class bigint_chars_format : uint8_t {number, base10, base64, base64url}; (until 1.0.0) using bigint_chars_format= bignum_format_kind; (since 1.0.0) ``` Specifies `bigint` formatting. ### Examples #### Initializing with bigint ```cpp #include using namespace jsoncons; int main() { std::string s = "-18446744073709551617"; json j(bigint::from_string(s.c_str())); std::cout << "(1) " << print(j) << "\n\n"; auto options2 = json_options{} .bigint_format(bigint_chars_format::number); std::cout << "(2) " << print(j, options2) << "\n\n"; auto options3 = json_options{} .bigint_format(bigint_chars_format::base64); std::cout << "(3) " << print(j, options3) << "\n\n"; auto options4 = json_options{} .bigint_format(bigint_chars_format::base64url); std::cout << "(4) " << print(j, options4) << "\n\n"; } ``` Output: ``` (1) "-18446744073709551617" (until 1.0.0) (1) -18446744073709551617 (since 1.0.0) (2) -18446744073709551617 (3) "~AQAAAAAAAAAA" (4) "~AQAAAAAAAAAA" ``` #### Integer overflow during parsing ```cpp #include using namespace jsoncons; int main() { std::string s = "-18446744073709551617"; json j = json::parse(s); std::cout << "(1) " << print(j) << "\n\n"; auto options2 = json_options{} .bigint_format(bigint_chars_format::number); std::cout << "(2) " << print(j, options2) << "\n\n"; auto options3 = json_options{} .bigint_format(bigint_chars_format::base64); std::cout << "(3) " << print(j, options3) << "\n\n"; auto options4 = json_options{} .bigint_format(bigint_chars_format::base64url); std::cout << "(4) " << print(j, options4) << "\n\n"; } ``` Output: ``` (1) "-18446744073709551617" (until 1.0.0) (1) -18446744073709551617 (since 1.0.0) (2) -18446744073709551617 (3) "~AQAAAAAAAAAA" (4) "~AQAAAAAAAAAA" ``` jsoncons-1.3.2/doc/ref/corelib/bignum_format_kind.md000066400000000000000000000034601477700171100225010ustar00rootroot00000000000000### jsoncons::bignum_format_kind ```cpp #include enum class bignum_format_kind : uint8_t {raw, number=raw, (deprecated) base10, base64, base64url}; ``` Specifies `bignum` formatting. ### Examples #### Initializing with bigint ```cpp #include using namespace jsoncons; int main() { std::string s = "-18446744073709551617"; json j(bigint::from_string(s.c_str())); std::cout << "(1) " << print(j) << "\n\n"; auto options2 = json_options{} .bignum_format(bignum_format_kind::raw); std::cout << "(2) " << print(j, options2) << "\n\n"; auto options3 = json_options{} .bignum_format(bignum_format_kind::base64); std::cout << "(3) " << print(j, options3) << "\n\n"; auto options4 = json_options{} .bignum_format(bignum_format_kind::base64url); std::cout << "(4) " << print(j, options4) << "\n\n"; } ``` Output: ``` (1) -18446744073709551617 (2) -18446744073709551617 (3) "~AQAAAAAAAAAA" (4) "~AQAAAAAAAAAA" ``` #### Integer overflow during parsing ```cpp #include using namespace jsoncons; int main() { std::string s = "-18446744073709551617"; json j = json::parse(s); std::cout << "(1) " << print(j) << "\n\n"; auto options2 = json_options{} .bignum_format(bignum_format_kind::raw); std::cout << "(2) " << print(j, options2) << "\n\n"; auto options3 = json_options{} .bignum_format(bignum_format_kind::base64); std::cout << "(3) " << print(j, options3) << "\n\n"; auto options4 = json_options{} .bignum_format(bignum_format_kind::base64url); std::cout << "(4) " << print(j, options4) << "\n\n"; } ``` Output: ``` (1) -18446744073709551617 (2) -18446744073709551617 (3) "~AQAAAAAAAAAA" (4) "~AQAAAAAAAAAA" ``` jsoncons-1.3.2/doc/ref/corelib/byte_string.md000066400000000000000000000045641477700171100212020ustar00rootroot00000000000000### jsoncons::byte_string ```cpp #include typedef basic_byte_string> byte_string; ``` The `byte_string` class is an instantiation of the `basic_byte_string` class template that uses `std::allocator` as the allocator type. #### Member types Member type |Definition ------------------------------------|------------------------------ `const_iterator`| `iterator`|Same as `const_iterator` `size_type`|std::size_t #### Constructor byte_string(); explicit byte_string(const Allocator& alloc); byte_string(std::initializer_list init); byte_string(std::initializer_list init, const Allocator& alloc); explicit byte_string(const byte_string_view& v); byte_string(const byte_string_view& v, const Allocator& alloc); byte_string(const char* s); byte_string(const byte_string& s); byte_string(byte_string&& s) noexcept; #### Assignment byte_string& operator=(const byte_string& s); byte_string& operator=(byte_string&& s) noexcept; #### Iterators const_iterator begin() const noexcept; const_iterator end() const noexcept; #### Element access const uint8_t* data() const; uint8_t operator[](size_type pos) const; operator byte_string_view() const noexcept; #### Capacity std::size_t size() const; #### Non-member functions bool operator==(const byte_string& lhs, const byte_string& rhs); bool operator!=(const byte_string& lhs, const byte_string& rhs); template friend std::ostream& operator<<(std::ostream& os, const byte_string& o); ### Examples #### Byte string from initializer list ```cpp json j(byte_string{'H','e','l','l','o'}); byte_string bytes = j.as(); std::cout << "(1) "<< bytes << "\n\n"; std::cout << "(2) "; for (auto b : bytes) { std::cout << (char)b; } std::cout << "\n\n"; std::cout << "(3) " << j << '\n'; ``` Output: ``` (1) 48 65 6c 6c 6f (2) Hello (3) "SGVsbG8" ``` #### Byte string from char array ```cpp json j(byte_string{'H','e','l','l','o'}); byte_string bytes = j.as(); std::cout << "(1) "<< bytes << "\n\n"; std::cout << "(2) "; for (auto b : bytes) { std::cout << (char)b; } std::cout << "\n\n"; std::cout << "(3) " << j << '\n'; ``` Output: ``` (1) 48 65 6c 6c 6f (2) Hello (3) "SGVsbG8" ``` jsoncons-1.3.2/doc/ref/corelib/byte_string_arg.md000066400000000000000000000004111477700171100220160ustar00rootroot00000000000000### jsoncons::byte_string_arg ```cpp #include constexpr byte_string_arg_t byte_string_arg{}; ``` A constant of type [byte_string_arg_t](byte_string_arg_t.md) used as first argument to disambiguate constructor overloads for byte strings. jsoncons-1.3.2/doc/ref/corelib/byte_string_arg_t.md000066400000000000000000000004611477700171100223460ustar00rootroot00000000000000### jsoncons::byte_string_arg_t ```cpp #include struct byte_string_arg_t {explicit byte_string_arg_t() = default;}; ``` `byte_string_arg_t` is an empty class type used to disambiguate constructor overloads for byte strings. ### See also [byte_string_arg](byte_string_arg.md) jsoncons-1.3.2/doc/ref/corelib/byte_string_chars_format.md000066400000000000000000000020741477700171100237240ustar00rootroot00000000000000### jsoncons::byte_string_chars_format ```cpp #include enum class byte_string_chars_format : uint8_t {base16, base64, base64url}; ``` Specifies byte string formatting. ### Examples #### Byte string formatting ```cpp #include using namespace jsoncons; int main() { std::vector bytes = {'H','e','l','l','o'}; json j(byte_string(bytes.data(),bytes.size())); // default std::cout << "(1) "<< j << "\n\n"; // base16 auto options2 = json_options{} .byte_string_format(byte_string_chars_format::base16); std::cout << "(2) "<< print(j, options2) << "\n\n"; // base64 auto options3 = json_options{} .byte_string_format(byte_string_chars_format::base64); std::cout << "(3) "<< print(j, options3) << "\n\n"; // base64url auto options4 = json_options{} .byte_string_format(byte_string_chars_format::base64url); std::cout << "(4) "<< print(j, options4) << "\n\n"; } ``` Output: ``` (1) "SGVsbG8" (2) "48656C6C6F" (3) "SGVsbG8=" (4) "SGVsbG8" ``` jsoncons-1.3.2/doc/ref/corelib/byte_string_view.md000066400000000000000000000052621477700171100222300ustar00rootroot00000000000000### jsoncons::byte_string_view ```cpp #include class byte_string_view; ``` A `byte_string_view` refers to a constant contiguous sequence of byte-like objects with the first element of the sequence at position zero. It holds two members: a pointer to constant `uint8_t*` and a size. #### Member types Member type |Definition ------------------------------------|------------------------------ `const_iterator`| `iterator`|Same as `const_iterator` `size_type`|`std::size_t` `value_type`|`uint8_t` `reference`|`uint8_t&` `const_reference`|`const uint8_t&` `difference_type`|`std::ptrdiff_t` `pointer`|`uint8_t*` `const_pointer`|`const uint8_t*` #### Constructor constexpr byte_string_view() noexcept; constexpr byte_string_view(const uint8_t* data, std::size_t length) noexcept; template constexpr explicit byte_string_view(const Container& cont); constexpr byte_string_view(const byte_string_view&) noexcept = default; constexpr byte_string_view(byte_string_view&& other) noexcept; #### Assignment byte_string_view& operator=(const byte_string_view& s) noexcept = default; byte_string_view& operator=(byte_string_view&& s) noexcept; #### Iterators constexpr const_iterator begin() const noexcept; constexpr const_iterator end() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cend() const noexcept; #### Element access constexpr const uint8_t* data() const noexcept; constexpr uint8_t operator[](size_type pos) const; constexpr byte_string_view substr(size_type pos) const; constexpr byte_string_view substr(size_type pos, size_type n) const; #### Capacity constexpr size_t size() const noexcept; #### Non-member functions bool operator==(const byte_string_view& lhs, const byte_string_view& rhs); bool operator!=(const byte_string_view& lhs, const byte_string_view& rhs); template friend std::ostream& operator<<(std::ostream& os, const byte_string_view& o); ### Examples #### Display bytes ```cpp std::vector v = {'H','e','l','l','o',' ','W','o','r','l','d'}; std::cout << "(1) " << byte_string_view(v) << "\n\n"; std::cout << "(2) " << byte_string_view(v).substr(0, 5) << "\n\n"; ``` Output: ``` (1) 48,65,6c,6c,6f,20,57,6f,72,6c,64 (2) 48,65,6c,6c,6f ``` #### Display bytes from std::string ```cpp std::string s = {'H','e','l','l','o',' ','W','o','r','l','d'}; std::cout << "(1) " << byte_string_view(s) << "\n\n"; std::cout << "(2) " << byte_string_view(s).substr(0, 5) << "\n\n"; ``` Output: ``` (1) 48,65,6c,6c,6f,20,57,6f,72,6c,64 (2) 48,65,6c,6c,6f ``` jsoncons-1.3.2/doc/ref/corelib/conv_error.md000066400000000000000000000032111477700171100210130ustar00rootroot00000000000000### jsoncons::conv_error ```cpp #include ```
`jsoncons::conv_error` defines an exception type for reporting serialization and deserialization failures. ![conv_error](./diagrams/conv_error.png) std::exception #### Constructors conv_error(std::error_code ec); conv_error(std::error_code ec, std::size_t position); conv_error(std::error_code ec, std::size_t line, std::size_t column); conv_error(const conv_error& other); #### Member functions std::size_t line() const noexcept Returns the line number to the end of the text where the exception occurred. Line numbers start at 1. std::size_t column() const noexcept Returns the column number to the end of the text where the exception occurred. Column numbers start at 1. const char* what() const noexcept Constructs an error message, including line and column position #### Inherited from std::system_error const std::error_code code() const noexcept Returns an error code for this exception ### Example ```cpp #include using jsoncons::json; int main() { string s = "[1,2,3,4,]"; try { jsoncons::json j = jsoncons::json::parse(s); } catch(const jsoncons::conv_error& e) { std::cout << "Caught conv_error with category " << e.code().category().name() << ", code " << e.code().value() << " and message " << e.what() << '\n'; } } ``` Output: ``` Caught conv_error with category json_input, code 1 and message Unexpected value separator ',' at line 1 and column 10 ``` jsoncons-1.3.2/doc/ref/corelib/data-model.md000066400000000000000000000164001477700171100206500ustar00rootroot00000000000000### jsoncons data model The jsoncons data model supports the familiar JSON types - nulls, booleans, numbers, strings, arrays, objects - plus byte strings. Type|Description ----|----------- null| bool| uint64| int64| half|Half precision floating point double|Double precision floating point string| byte string| array| object| In addition, jsoncons supports semantic tagging of values, allows it to preserve these type semantics when parsing JSON-like data formats such as CBOR that have them. Tag|Description ---|----------- undefined | datetime | epoch_second | epoch_milli | epoch_nano | bigint | bigdec | float128 | bigfloat | base16 | base64 | base64url | uri | clamped | multi_dim_row_major | multi_dim_column_major | ext | id | regex | code | ### Examples #### Mappings between CBOR and jsoncons data items CBOR data item|CBOR tag | jsoncons data item|jsoncons tag ---------------|------------------------------------------------| --------------|------------------ null |  | null | undefined |  | null | undefined true or false |  | bool | unsigned or negative integer |  | int64 | unsigned or negative integer | 1 (epoch-based date/time) | int64 | seconds unsigned integer |  | uint64 | unsigned integer | 1 (epoch-based date/time) | uint64 | seconds half-precision float, float, or double |  | half | float or double |  | double | double | 1 (epoch-based date/time) | double | seconds string |  | string | byte string | 2 (positive bignum) or 2 (negative bignum) | string | bigint array | 4 (decimal fraction) | string | bigdec array | 5 (bigfloat) | string | bigfloat string | 0 (date/time string) | string | datetime string | 32 (uri) | string | uri string | 33 (base64url) | string | base64url string | 34 (base64) | string | base64 byte string |  | byte_string | byte string | 21 (Expected conversion to base64url encoding) | byte_string | base64url byte string | 22 (Expected conversion to base64 encoding) | byte_string | base64 byte string | 23 (Expected conversion to base16 encoding) | byte_string | base16 array |  | array | map |  | object | #### json value to CBOR item ```cpp #include #include using namespace jsoncons; int main() { json j(json_array_arg); j.emplace_back("foo"); std::vector bstr = {'b','a','r'}; j.emplace_back(byte_string_arg, bstr); j.emplace_back("-18446744073709551617", semantic_tag::bigint); j.emplace_back("273.15", semantic_tag::bigdec); j.emplace_back("2018-10-19 12:41:07-07:00", semantic_tag::datetime); j.emplace_back(1431027667, semantic_tag::epoch_second); j.emplace_back(-1431027667, semantic_tag::epoch_second); j.emplace_back(1431027667.5, semantic_tag::epoch_second); std::cout << "(1)\n" << pretty_print(j) << "\n\n"; std::vector bytes; cbor::encode_cbor(j, bytes); std::cout << "(2)\n" << byte_string_view(bytes) << "\n\n"; /* 88 -- Array of length 8 63 -- String value of length 3 666f6f -- "foo" 43 -- Byte string value of length 3 626172 -- 'b''a''r' c3 -- Tag 3 (negative bignum) 49 Byte string value of length 9 010000000000000000 -- Bytes content c4 - Tag 4 (decimal fraction) 82 -- Array of length 2 21 -- -2 19 6ab3 -- 27315 c0 -- Tag 0 (date-time) 78 19 -- Length (25) 323031382d31302d31392031323a34313a30372d30373a3030 -- "2018-10-19 12:41:07-07:00" c1 -- Tag 1 (epoch time) 1a -- uint32_t 554bbfd3 -- 1431027667 c1 3a 554bbfd2 c1 fb 41d552eff4e00000 */ } ``` Output ``` (1) [ "foo", "YmFy", "-18446744073709551617", "273.15", "2018-10-19 12:41:07-07:00", 1431027667, -1431027667, 1431027667.5 ] (2) 88,63,66,6f,6f,43,62,61,72,c3,49,01,00,00,00,00,00,00,00,00,c4,82,21,19,6a,b3,c0,78,19,32,30,31,38,2d,31,30,2d,31,39,20,31,32,3a,34,31,3a,30,37,2d,30,37,3a,30,30,c1,1a,55,4b,bf,d3,c1,3a,55,4b,bf,d2,c1,fb,41,d5,52,ef,f4,e0,00,00 ``` #### CBOR item to json value ```cpp #include #include using namespace jsoncons; void main() { std::vector bytes; cbor::cbor_bytes_encoder encoder(bytes); encoder.begin_array(); // indefinite length outer array encoder.string_value("foo"); encoder.byte_string_value(byte_string{'b','a','r'}); encoder.string_value("-18446744073709551617", semantic_tag::bigint); encoder.string_value("273.15", semantic_tag::bigdec); encoder.string_value("2018-10-19 12:41:07-07:00", semantic_tag::datetime) ; encoder.int64_value(1431027667, semantic_tag::epoch_second); encoder.int64_value(-1431027667, semantic_tag::epoch_second); encoder.double_value(1431027667.5, semantic_tag::epoch_second); encoder.end_array(); encoder.flush(); std::cout << "(1)\n" << byte_string_view(bytes) << "\n\n"; /* 9f -- Start indefinite length array 63 -- String value of length 3 666f6f -- "foo" 43 -- Byte string value of length 3 626172 -- 'b''a''r' c3 -- Tag 3 (negative bignum) 49 Byte string value of length 9 010000000000000000 -- Bytes content c4 - Tag 4 (decimal fraction) 82 -- Array of length 2 21 -- -2 19 6ab3 -- 27315 c0 -- Tag 0 (date-time) 78 19 -- Length (25) 323031382d31302d31392031323a34313a30372d30373a3030 -- "2018-10-19 12:41:07-07:00" c1 -- Tag 1 (epoch time) 1a -- uint32_t 554bbfd3 -- 1431027667 c1 3a 554bbfd2 c1 fb 41d552eff4e00000 ff -- "break" */ json j = cbor::decode_cbor(bytes); std::cout << "(2)\n" << pretty_print(j) << "\n\n"; ``` Output: ``` (1) 9f,63,66,6f,6f,43,62,61,72,c3,49,01,00,00,00,00,00,00,00,00,c4,82,21,19,6a,b3,c0,78,19,32,30,31,38,2d,31,30,2d,31,39,20,31,32,3a,34,31,3a,30,37,2d,30,37,3a,30,30,c1,1a,55,4b,bf,d3,c1,3a,55,4b,bf,d2,c1,fb,41,d5,52,ef,f4,e0,00,00,ff (2) [ "foo", "YmFy", "-18446744073709551617", "273.15", "2018-10-19 12:41:07-07:00", 1431027667, -1431027667, 1431027667.5 ] ``` jsoncons-1.3.2/doc/ref/corelib/decode_json.md000066400000000000000000000071501477700171100211170ustar00rootroot00000000000000### jsoncons::decode_json Decodes a JSON data format to a C++ data structure. `decode_json` will work for all C++ classes that have [json_type_traits](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/json_type_traits.md) defined. ```cpp #include template T decode_json(const Source& s, const basic_json_decode_options& options = basic_json_decode_options()); (1) template T decode_json(std::basic_istream& is, const basic_json_decode_options& options = basic_json_decode_options()); (2) template T decode_json(Iterator first, Iterator last, const basic_json_decode_options& options = basic_json_decode_options()); (3) template T decode_json(const allocator_set& alloc_set, const Source& s, const basic_json_decode_options& options = basic_json_decode_options()); (4) (since 0.171.0) template T decode_json(const allocator_set& alloc_set, std::basic_istream& is, const basic_json_decode_options& options = basic_json_decode_options()); (5) (since 0.171.0) ``` (1) Reads JSON from a contiguous character sequence provided by `s` into a type T, using the specified (or defaulted) [options](basic_json_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). (2) Reads JSON from an input stream into a type T, using the specified (or defaulted) [options](basic_json_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). (3) Reads JSON from the range [first,last) into a type T, using the specified (or defaulted) [options](basic_json_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). Functions (1)-(3) perform encodings using the default json type `basic_json`. Functions (4)-(5) are identical to (1)-(2) except an [allocator_set](allocator_set.md) is passed as an additional argument and provides allocators for result data and temporary allocations. #### Exceptions Throws a [ser_error](ser_error.md) if parsing fails, and a [conv_error](conv_error.md) if type conversion fails.Throws a [ser_error](ser_error.md) if parsing fails, and a [conv_error](conv_error.md) if type conversion fails, and a [conv_error](conv_error.md) if type conversion fails. ### Examples #### Map with string-tuple pairs ```cpp #include #include #include #include int main() { using employee_collection = std::map>; std::string s = R"( { "Jane Doe": ["Commission","Sales",20000.0], "John Smith": ["Hourly","Software Engineer",10000.0] } )"; employee_collection employees = jsoncons::decode_json(s); for (const auto& pair : employees) { std::cout << pair.first << ": " << std::get<1>(pair.second) << '\n'; } } ``` Output: ``` Jane Doe: Sales John Smith: Software Engineer ``` ### See also [allocator_set](allocator_set.md) [encode_json](encode_json.md) jsoncons-1.3.2/doc/ref/corelib/diagrams/000077500000000000000000000000001477700171100201055ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/corelib/diagrams/basic_default_json_visitor.png000066400000000000000000000127671477700171100262250ustar00rootroot00000000000000PNG  IHDReUtEXtmxfile%3Cmxfile%20modified%3D%222020-03-31T16%3A09%3A00.483Z%22%20host%3D%22app.diagrams.net%22%20agent%3D%22Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F80.0.3987.149%20Safari%2F537.36%22%20etag%3D%22MQ85Md0t-WDJENPmkaOC%22%20version%3D%2212.9.2%22%20type%3D%22device%22%3E%3Cdiagram%20id%3D%22iK-0d-7Yl-5MlnfMu26I%22%20name%3D%22Page-1%22%3EzVbBctowEP0aH9OxrUDhmABNW4ZMUzoDOWUUa7HVyhKVBZh%2BfSUsYcs2k2SaQ7mgfatdSW%2FfSg7QJC%2FvJN5mC0GABXFIygBNgziOQjTSfwY5Vsj12AKppMROqoEl%2FQMu0qI7SqDwJiohmKJbH0wE55AoD8NSioM%2FbSOYv%2BoWp9ABlglmXXRFicoqdDQIa%2Fwz0DRzK0eh9eTYTbZAkWEiDg0IzQI0kUKoapSXE2CGPMdLFffpgve8MQlcvSZgdv%2Bj5POHZRZPfs%2FVapE%2Fll%2BvbJY9Zjt74Gdc0OTpZyH4054WVAkZxEOmV7h9NqPUjOyB1NGxJMWOEzALhdp9yKiC5RYnxnvQutBYpnKmregc3dy42wVIBWUDsge5A5GDkkc9xXqvLadWVJHj%2BFCXKBpaLGuUx8Vhq4r0nLkmTg8sd2%2Fg8eMFHgls8I6pFp%2F%2Fwt6GMjYRTKcxsQhOP40XSopf0PCgIRoj8j58x6P%2FjfBRh%2FAOrcDJjbkBtJUwXOhy%2BExCSdXakm7Gj2b8YWCtadlwTY%2FO4Hrza5fAGI0oY9ZhJ8vFXaxBIXYygZeVpbBMQb3cyUC8%2B6xb0UbFBj0Fc5gEhhXd%2B7dgXxXtCt8E1Se71KAxaumgOrYNal5arTzjlu5GrTwVLZ08J0mdD%2F0qlaX7RRbP79f4O6RXq4c57OfQ09ZfeAaSKsx10fSrRnEqcd6Rnm4r5YvNb08uOLR62UKY0ZQbxWqhgMZvTZNS%2FR7dWEdOCTHL9N4T%2Fk3yDo0ftRo%2FDnsaH%2FXoKH5742uzfg2rCtbfFGj2Fw%3D%3D%3C%2Fdiagram%3E%3C%2Fmxfile%3E3)NIDATx^[U-QZ)чED_VX# R/x H(D,^jA1,X56Z{97g9_c y*|%0N?4t_xӧOyLpeAwKMk/~93RD|i @q}(">~nE"Gk @AG"GPD|)">~ѺD}(">~nE"Gk @AG"GPD|)">~ѺD}(">~nE"Gk @AG"GPD|)">~ѺD}(">~nE"GkhD̙3rAٳg <صWʆ d߾}2lذz,]T͛''Oʶ鋫r۽{3FΝ۴+=XD{Dƒw#"O<իW˜9s7pٳrٺuK0֮]O>_~t,\7}ty>cv5/۷o;wʃZ?wuvlpq>ORD<@RݴiSjWD|O)ol_4|ٴov:r!#v".::th42m49|pIܿ?{>vX֍7ڵk8׭[<~ǓץKd…m0)1 _'qƕSׯٳ[Ր!C 8ʘh&{ﹿM2%{O׍1Ç3N>3 QX D䏞?ܗ~|w=Y7|e,gR0gw۶m5jێ=[j*xX_},믳{/\|r{9 NJ+>l #{'O7|md׉8L/k2k GlS~؄\u >T4^[>pPẇݻ2qĮ2˨DO#+^˖-˂ԩSdٻwܻwUõׯgvZϋ/~G nEZb><%/1o߾Ӆ @p0aB#ZW%) := ʖ-[ʕ+-m9KEn<;ԗA7y܇"2/Im:"r,h"\Rvؑ-[Fom7ndA67o5kȵkZ,x0Y`A!b*"/W_}%:O` "R31RFOsN BkQn >וAJLDG ]f9(ko+;FYO$1wOCE"+A >È_G%iyҤIwϕӰ;^j鵄Bc?qDKh |aE&U4!""UXί3\dg̘DdӲ"bŨ\p>4 VGdQmBe,–ylmX[<:ur>,gٖʄ9Ќ#R[Z2T`^n Ɖސ2"J\T'ފ-JUԍd[afhJwJ/DEYW[nJBѣGS]rh#}*"bj٣mFRDY +>n<㴔Dlb[d"tVE*"F`n1[ꔉD("`HVGD4OFz&ȔӋLD"ġنC+DSwY鬲L̚5K._ T,>bRNH% jOdѢEYAEj;wԎ _AIH{(MTV^* z"uDD{JaI?nj'h鬊bRGD0>U4WÜz"/;jai'{Mf6 LQ(EO :1eIe32oO_βlI )ڸO,Ox*O)GJYuDD oiOꫬgOnJ@D{"mYE'p cSx\LxV>J-UO z{: EPrA^>El&y=a['09e_}?%h͖:RZҒf3폄'l9KMtV"ReÞ/6 uFt#"u7Q'җmf΋r̙3+7¤=*s| Eķ{HQ[WZ>R6# Bcŋҍwr~磛^ԵRD^l[L"3bߪh H*;Տ6"Gk @AG"GPD|)">~ѺD}(">~nE"Gk @AG"GPD|)">~ѺD}(">~nE"Gk @AG"GPD|)">~ѺD}Z"$&gC@m@[3~xzC$@I$]tH"@k? $E"vY E$7$@$HREgIH .ސ @R("Im% PDzC$@I$]tH"@k? $E"vY E$7$@$HREgIH .ސ @R("Im% PDzC$@I$]tH"@k? $E"vY E$7$@$HREgIH .ސ @R("Im% PDzC$@I$]tH"@k? $E"vY E$7$@$HREgIH .ސ @R("Im% PDzC$@I$]tH"@k? $E"vY E$7$@$HREgIH .ސ @R("Im% PDzC$@I$]tH"@k? $E"vY E$7$@$HRەDdlmV0.fܯ"GDȕ֜\*"EdkZ#ш"!@d#})"cyRyܗs.Hr\%`=l>cɯ#oEa9E"3 vhkc= (1etv"\1͋FxS޷&l#Բٲ|pB"Tu}~H%@i'+ Д'rƊDDKAƸxD _% DDLĊ1!UGǴQFqr o .7}Lh^,{[z[΂Xip/Xyd&~:DD("6J"(N# OC`AAgXLO9EB;d)e"-?Eoaޱ"|ODԓdE73́~dz"eKlGǴQFqr0Ͳʚ=@;$/YtĻW3Ȁz.H("~H,Ȁz.H("~H,Yn`IENDB`jsoncons-1.3.2/doc/ref/corelib/diagrams/basic_json_encoder.png000066400000000000000000000120321477700171100244220ustar00rootroot00000000000000PNG  IHDRUep7tEXtmxfile%3Cmxfile%20modified%3D%222020-03-31T16%3A11%3A54.501Z%22%20host%3D%22app.diagrams.net%22%20agent%3D%22Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F80.0.3987.149%20Safari%2F537.36%22%20etag%3D%22VTUKiqHc5ztnxOYR1OBc%22%20version%3D%2212.9.2%22%20type%3D%22device%22%3E%3Cdiagram%20id%3D%22iK-0d-7Yl-5MlnfMu26I%22%20name%3D%22Page-1%22%3EvVZNc9owEP01PqZjW0DhmABNW4ZMUzoDOWUUa2OrlSUqCzD99ZWwhC3bachMplzQvtXq4%2B3blQM0zctbibfZUhBgQRySMkCzII6jEI31n0GOFTKYWCCVlNhJNbCif8BFWnRHCRTeRCUEU3Trg4ngHBLlYVhKcfCnPQvm77rFKXSAVYJZF11TorIKHQ%2FDGv8MNM3czlFoPTl2ky1QZJiIQwNC8wBNpRCqGuXlFJghz%2FFSxX16wXs%2BmASuLgmY3%2F0o%2BeJ%2BlcXT3wu1XuYP5dcru8oes5298BMuaPL4sxD8cU8LqoQM4hHTO9w8mVFqRvZC6uhYkmLHCZiNQu0%2BZFTBaosT4z1oXWgsUznTVnSObh7cnQKkgrIB2YvcgshByaOeYr1jy6kVVeQ4PtQpikYWyxrpGVgMW1Wk55Vr4vTAcvcGHj%2F%2Bi0fgia6Ld%2BfxmTI2FUwnyMQiOP00XigpfkHDg0Zogsj7MH8R9YP%2FSf24Q32HVuDk2vQCbSUMFzoxPpNQUrWxpJvxgxl%2FGFprVjZcs6MzuD78xi1gjEaUMeuwk%2BXiXsxBIXYygdc1prBMQb1e00C8ztbNaCNjw56EOUwCw4ru%2FX7Yl0W7wzdB9c3Oghn4eolRSwfVtW1Qs3211pm0dDdurVPR0lnnJKnzpS9SWbpfZvHiboO%2FQ3q1vl%2FAfgE9Bf6FZyCpwlwnTb9vFKcS5x3p6bJSvtj88uSCQ6uWLYQZTblRrBaKbh7oxhQp1S%2FTtXXklBCzTW%2Bf8DvJOxR%2B1EpAHPYUPurRUfz2wtdm%2FS5WGay%2FLtD8Lw%3D%3D%3C%2Fdiagram%3E%3C%2Fmxfile%3E@IDATx^_T?ZT(bPDD% Ji*}IBZ0BPPHU'jcbЇ-$/*bm EE)T_;5s33g sg^{o;k}zI*0ӗy u}ĚH 7'yFx5T/A֣/~$;z6TMCU@P65㘠:8HAr1 'Hڒ\: PU6{+5oCAU'CJ )eOcT4qrPAU'FT{9PjbT{ Qq* ƙJPt'|PP?GjutdT$DA'kR!%Ք٧}8] =OQhzU={Ƙ1c: ݻسg; &dٳgظq#V\4u;tf̘+VJW qCWhbO_wu\pѣ; oॗ^jϱ}v,_jKc`j~A:ue:5Iv"H?ݷo_JP%L=NAbcj PA5TǏ]/^gGҥKIw^ܹ3{Oڵkaǟyg}6֮]۴+"rdٳggʬYJO޽{XlY;vlVA駟W^~3g6MOyV][ }Q6}MU|kecL'gS|gCl{EU M6eXpalÆ 8r>|hݻwc8[u벟 9U?q7m>x ͛78sfO2q(J_hX/^@˛ o2;vヒ;w4|LJazS'T;r+Ss[Lln]c*/h.]gy [l-K˖|ehw陭*/ϖ!B|2X0a /7nEsM7 B>V'olə3g{U`N:?\ KQAp괬 ~N^mT쳒A㰪*mT5_EZ_B=[n5zzWh=Uڵr~zB5.#mp))xH[z冒ZOzDOR%l%8@ "l#(+Of@H>韀(Zs7d@@5Tm%87;ċ6lhOj= Zf7ۭo=(T ʲ]%yldO4𩚺ۍR4RHy/F.X1@BWa^dI卭*i6P[ETy|Zo|EZ4i^Ze+G?gXU\ :'RR@PM)}ڧۅ :1zȁTkSS@PmO7SA5μ W@;`Sj9Tk#%ae' =]zU)) >EPBU=W@Py @ 5)S) Fũg^+Auҝ|j)?@A5 4Z}]Q~WwbJ'5vdT(b) RP@PM!A HhTIR FA5T) RP@PM!A HhTIR FA5T) RP@PM!A HhTIR FA5T) RP@PM!A HhTIR FA5T) RP@PM!A HhTIR FA5T) RP@PM!A HhTIR FA5T) RP@PM!A HhTIR FA5T) RP@PM!A HhTIR FA5T) RP@PM!A HhTIR FA5T) RP@PM!A HhTIR FA5T) RP@PM!A HhTIR FA5T) RP@PM!b=62+?fGL18 Nyۜa+,ϫmY )( )1PVw$3aPHNW@PM?|`o~.XprWp%s+2^<py|-`$`6@,v;O8MY7;;s-L9#TPM4aAsρ9xOɏ < .4\1sk6ؠ@Q}/2!v3!|a{W>n)eqW7Ns? F*&Ԓjme_H[6w'WZu^B|UhC {a3٠jq7lcdp#Tk4bsEP5?7l* u |kA5\b[{6ˍjK~7nTvmZaS>U!T='F|t⚠ډz5.eWU[:N<*̛UERr j@nR7'S'S[AT}`PEV|UJlv}ŲJh^&aU~ ve=U+zePmTqj-\Ag9<E 8VePmO8;iO*[V_DD=A5*)`UxT&P@P<*n>#ը#礀7~˘R jը#礀7~˘R j^P?lIENDB`jsoncons-1.3.2/doc/ref/corelib/diagrams/basic_json_filter.png000066400000000000000000000120371477700171100242750ustar00rootroot00000000000000PNG  IHDR_e# tEXtmxfile%3Cmxfile%20modified%3D%222020-03-31T16%3A05%3A50.312Z%22%20host%3D%22app.diagrams.net%22%20agent%3D%22Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F80.0.3987.149%20Safari%2F537.36%22%20etag%3D%22kh8uf5VxpCrAb6xssNHN%22%20version%3D%2212.9.2%22%20type%3D%22device%22%3E%3Cdiagram%20id%3D%22iK-0d-7Yl-5MlnfMu26I%22%20name%3D%22Page-1%22%3EvVbBctowEP0aH9OxLUjhmABNWoZMUzoDOWVUa2OrlSUqCzD9%2BkpYwpbtNGSaCRe0b7Ur6e1byQGa5OWNxJtsIQiwIA5JGaBpEMdRiEb6zyCHChmMLZBKSuykGljSP%2BAiLbqlBApvohKCKbrxwURwDonyMCyl2PvTngTzV93gFDrAMsGsi64oUVmFjoZhjd8CTTO3chRaT47dZAsUGSZi34DQLEATKYSqRnk5AWbIc7xUcZ%2Be8Z42JoGrcwJmd99LPr9fZvHk91ytFvlD%2BeXCZtlhtrUH%2FoELmjz%2BLAR%2F3NGCKiHt9tXBcSLFlhMwacMAXe8zqmC5wYnx7rUKNJapnGkr0sPuNt2aIBWUDchu%2BwZEDkoe9BTrHVkGrYQix%2Bi%2BLkh0abGsUYyBxbDVQHrKXNOkB5apV7D28V%2BsPVGm4D9J0znYRDDNvYlFcPxpvFBS%2FIKGB12iMSJvQ%2FNZPA%2Ffk%2BdRh%2BcOrcDJlWlzbSUMF7oKPpNQUrW2pJvxgxl%2FGFprWjZc04MzuN782iUwRiPKmHXY0XJxz9agEFuZwMuCUlimoF5uVyDepdWtaKNifQVzmASGFd35V11fFe0KXwXVJzsJZuDrJUYtHVTHtkHNm6mVZ9zS3aiVp6Klk%2BcoqdOhz1JZultk8fxujb9BerG6n8NuDj3d%2FJlnIKnCXBdNP10UpxLnHenptlK%2B2Pz25IJDq5cthBlNuVGsFoq%2BKtC1aVKqH50r68gpIWaZ3nvCv0neoPGjVgHisKfxUY%2BO4tc3vjbrJ6%2BqYP3hgGZ%2FAQ%3D%3D%3C%2Fdiagram%3E%3C%2Fmxfile%3E6MwIDATx^[NLJܠPPK % .I.Pr k93)HBv( jvAI$?74{X3g}Y9|sAD~ 7Hׯ. CW3o5gn":t, ƿqb1E(yf֔o՜J&RʷXܵmPmÕf( N3|$|NtlIYXΔoNSoE03H>/G(zr|3vB8|+AXr @K/Ww|Nt\$@r x')<|=@gHV\$@r x')<Ȍ|߿/OHΝKBsټy>|XzYX߾}˗˜9sc˽s<,}Ie֬YJO?Ǐʕ+tOJxBv%{=zn:9s==z$ϟ;vHN >sҤI2dYl`oܸQn8pZJ֬Y# (&cR^Hf m۪F.>; .j/Ľx;|aE-֭ݻW&N(gϞu]5wMW 6!\ϣ#ɓ'RWWVq#yv9:t H(*MK1cFҥȏ;9scP̛7ߍ3LǏn^^W; Ν;]kˊ|G!ׯwɓ'sUN+F|V>| ȝ;wr䫮m*R;>U1:u έmڵ2n8n:u\rō.xz'QʚT QT $lNcǎu.]*wZwӦM2|wŋ`kա/VW^n.hMO$R>|{MMMbwl@刱Gq2.:C}vyYn#GlmN,BӧOU /γ- Ņu ҃/Ŋ_cފk1T( ϫW\M}VV۷osþX`CK,qU/_ Kk;(}1-rLj7 L|mk唦$ߤ!UVq'o//Nvo1'N?bVUxiիbhcjm#Q޽UVz*|u|{[h/9IqCp?aÆ#mE%E}>cVr={KGf{,*ƻw~m;č"m Bژ<^l DIE\dၢ.|/>LܲPZIZFo Jӧ2w\Wbj_۪9 c+7o6ׯ_[OcіEnhEɷ-ɔ|mŨ;t萻MA刷lkV`v׾4~\k/"ik߶Z|&_h=Z?~kA=u?gI[J}!nʷM+([#r䫽RG{ .t}U/$5*r]{6@Rjo[|GۻwѣGso2U}^^v-'_:!=<-{nMj[ڞo[mUvY1rH6iL׾`J}C-ChEVOVIfƵlik;\|ٵ`Io;d]V||m}s- h3ܺu˵ f} "o hkŽ$ *nmvE[1mKI_(C:b vq$ do|+VѸ2eJtiB =41>ovΞ}HXǬk}\4N \|]eȄs*[:CP"ʷD<]|iISu>M:o:Nܫ PmCgS(p53pP3dK/WD(zr|3vB8|+A|>B$@x33囱T[ ʗkZ|"`pP3$v ||? cW/;3#`$@~P~3* @('CÝQI'@> J$87I|pgT P/O$; N |0} ?(_?H po !@Ψ$@|_LHwF%`$@~P~3* @('CÝQI'@> J$87I|pgT P/O$; N |0} ?(_?H po !@Ψ$@|_LHwF%`$@~P~3* @('CÝQI'@> J$87I|pgT P/O$; N |0} ?(_?H po xbټy 4(1ϟ}>,={,ηod2gqBτ ӧOUvh|{.ߵkWo7J?_~#Gd۶md92M|YqEgSS,Zȉ$$9477^~-K.J2zرc/ׯ_[.0ȑ#c9M > m;ࢠsA[V6oxMw.]cnc$O d W%aVO>{e+uJLKMj;W_y|y|]X!.Wjѥ/?cf5kW '_NT[TBĉĉB7zkm /V@t>}X$7mm}IN[HoVLU. Phe$-;$J?_7(4/|U܅T"vJ(2/v8OZ1S.|m}QG+ȴݛ{&UqqlmzV]to|Gʷgb6o U\AeC'F6ՀAjIVĽlC/^Ț5kr<͌-[ȹsr;k1ߗ/_r=_v|Q|Ir @OzVP5po N Ό{Nm  |ˎ @(q (;ʷH9 NF?(IENDB`jsoncons-1.3.2/doc/ref/corelib/diagrams/basic_json_options.png000066400000000000000000000270201477700171100245010ustar00rootroot00000000000000PNG  IHDRctEXtmxfile%3Cmxfile%20host%3D%22www.draw.io%22%20modified%3D%222019-11-01T19%3A48%3A34.521Z%22%20agent%3D%22Mozilla%2F5.0%20(Windows%20NT%206.1%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F77.0.3865.120%20Safari%2F537.36%22%20etag%3D%22UBlelfW8G_eCJfBtvKqt%22%20version%3D%2212.1.9%22%20type%3D%22device%22%20pages%3D%221%22%3E%3Cdiagram%20id%3D%22yA7M8pUu49T19xTu_T4b%22%20name%3D%22Page-1%22%3EzVhNc9owEP01PraDbWzgGCClOaTDlJk2yYVR7MVWK0seWcQmv75yLOFPPsJ0DCe0T6uV%2FPZJWmHYsyhbcBSHj8wHYlgDPzPsuWFZ5sAayp8c2RXIcOwWQMCxr5xKYIXfQY9U6Bb7kNQcBWNE4LgOeoxS8EQNQ5yztO62YaQ%2Ba4wCaAErD5E2%2Bhv7IizQsTMo8e%2BAg1DPbA5UT4S0swKSEPksrUD2vWHPOGOiaEXZDEhOnualGPftQO9%2BYRyoOGfAyF6Gj3jhRL9eFg6g13g6Z19UlDdEtuqDX1GCvfWfhNE1iwVmNFHLFzvNCWdb6kMedmDY0zTEAlYx8vLeVKpAYqGIiLRM2WwvU88JXEBWgdSyF8AiEHwnXVSvoylUGjJdZadlRkztE1ayMVQYUiII9qFLnmRDUfUJ2qxjtPngyW1wM%2BxZ4wZ7Vgd7bp%2Fs2cfYA3rT7FmDa7M3PGPLrj0WRYxenT37jI076pM8p0VeiyOg%2Fl1%2BcUjLIyiR1NZpgQyLJ8Vg3n7O218dZc2zStd8pw0qF%2F%2BkA%2BRGZVRulsM%2BLD3uYAoStuUenN5jAvEAxGk1gV%2B7BtsJrWTM6UiYxjgQJPBb%2FfLsyqKaYcmw%2FLJDerHNhg6Kz1aDqnddI05z07qNOAUtrTgfktp%2F9OUqc6%2BjssvVYt2UCvbHhD427AtlsD%2BsdaBxvzoY%2FwcdXHhy9KsfXZmfOm1uS2eO2ThuLtWZ0xCs1bPOJtfT2UHNnNSCfVtaaL4xmik8Wwtmb1r4iUbP1uTHzA1NczNJRw%2Fv5rLjRfdAQ%2BBYICq3sHyIYxRwFLUEIis6UZdEIjj7CzNGGJcIZVR6TjeYkAaECA5orispAZD4NK8PsXxC36mOCPt%2BPk1nwVkvSY3uArNDYUdqzkYCJme%2BFq3PF53SLB%2FwRQbLv0Hs%2B38%3D%3C%2Fdiagram%3E%3C%2Fmxfile%3ESs IDATx^_UGIL&Ubo#Am&jHQ@mh/@țTP" (cl5 p1}>gܻZΙ]f}}}} 5DOaau ƪc,ݢ<.򏜀@s125 bX {"qp0 1/€,eS%E Дb@  jd]$<yA1E0%bYNe@"@H$" ,nF1VJX M,#e|,B1VB ,*R3ɿH[@ /CcSȿ:D@ǽa L/Vicd K2Q"cEq/!bH"54UXi(`176uCXz @H$" ,nF1VJX M,#e|,B1VB Í7ѣGܹsjǎjРA{ZrZp|U"랞k.՜Ǐ+Y۷o5k֨M6K.5)ϟ?jzaO[m1voݺDݻW6rHm#(b}]-Ox*>-k׮5d,{QSׯ_˖-\cVRC I;whqm0 #dG0jjMŘ.f+Ntmf"%W$mVnUUmRcl.]Q=nR!4UE}#~~`@y8N▕C16k֬TEI5S~Æ -NWgΜE\1&믿V?C 8P͞=[IEH1VǨsDjS)ʘM6Qurb)ۃ4eʘ+rOc*cI4W2d7Oe̮|SKcv:E+'[/G}T=#CK@+V9 &ŒĘ鵒MuG6[_?ޚCB+g2UpbFo3W,Ӄf|L_D2VsѣWv/^yRUXR<KcG0k'|z-}D^?՟-~c2#0i~g2Oߙ ;9- lY&[T2' hMeq5f1w<ٖꫯRO>L~4ˬfS6wsR4e6P0'mlSEq}>_~Y >LWx DYu'\!XoVΝ;ŋU3p-kWr_7暕R/դIt/Y2L DmhYb,R&A@AOY)sC>EQii/\b3Sl@O*e2E ƲJF@Dܶm2VZN1R(+ nb`@t[!]i1(7Xb,'@!Ft?z-nG[lo~u)^{M?'̪?*s&#jܬC#(=jܕb,/1@?_712@բ۟Ց̈z=Ha 2=0]!P(_W 2Cc$E0:aGm߾]7S &-0Q&U~NY'{:W D&m@ ԇm۶+W|#I @%:W)<&G(^`1|%iQV矯jF>@02"L#WZz`2 N>|=O1F&C",Pc('`Dى's~_WϿ'Ʈ@u3A#DXh?آϿvl@u93I hͺ~hd4oӍlG B2X!ߌ>DhF7nP/zŋa  +vEb׈cb+ 5i$u%ۑRjT1WU,c @آlڴi9ezcvuf1qF5zh5>^|Y_^ٳG 6,x<ςZp]r V6VȪ/ğ\bرcZ >\ &cԩSĐk.u֭~D*h)/]Ըjgic2>$ׯ_A>cȑ#2)Fl6$%/aM)}M=˖-\%Rz\?$Id\G6mtWc }e\l3qM3麲 *Vُ?PD͞=[- L2#_W%Yw{}ӬyW&/A<]=5kO2B(m$.2V_'bO^eJ?}tS}aK!z;;D(Ae1OyzXR s64?lJ^|3aȣV^y38qbC+XwRz /~m6v\ma&v6 ,I֗^zIHD`Dl zΝjݙX޵c63{ "Bk-Ɨ5\3D36a؜9sZ)E$኱` 崟4I{ d/[Fӏ,2&YOg'> )iJ5[UjN+$HӔf14GΝ;4 & :|;[-_\b8a_g Tƕ#+%#A 7Ԯ]U!ʪZ I n" b,ao(۶mZln9rd}bq (ʿw^ݘ/ۑҘ?tРXal= w@EYÊ2:"w?DIYM HTH@D<corC ZhCcu& L.e wUwV}}}HDT;vL/ÇעJĘ|ӣǐE֮?~\b.*[O6mR.]jlS?ž`bիߺuKػw2MR!~@;my0>׿0x2z۷o"cU^=NX-k׮5kew3IҶ)얃":9 zƖp?}tCĻ&blԨQZٳg<:@1\Fmٲ f ]X5[nՋ&Ɨ4I,B.}3"ms4?uT-D^:35rV 8v<؜9svO8 w'blժU[wQ/R)}yshTcQg L6.fLFvmf"Ul\1 '*e#6o̙ q4޸qCz%BSU47Gƶ]Nf `o'q!5kV"Ƥ)UaÆۆj+[ۆ\4ou'{-cveLM֨: }RRDقAS*RsENIvĘnt"%YZa26橌x\ת2&hu1V,@1VB ĘLuG6[rM%}NJ{LEAZ/-xȈ{V=cyŘ3&lvcRX{G&^ٽxfӰL$٣Fd,sv<KcG9kz,Ntbth%w4}NN}z,E%/sέ[N ڂl\Ncxv[Ze,4iӔ2lK~WTlN(9ݜ9MM)lSzFnj` Ƃ C ;yeWf9m2!_0l15 bhW\cƌQӧOl!seXYuEFu"" @u/C 1/``D ]G΄@0̅@;X ۡ=e "8@YEŐtW%}b,(a# `1,  @ ȸCrJ_;(HŰ @n/D+k@1V "X Ɂ* Ug B6B Â>nX `1$$@UIC  !JX BȿBc52IDAT.BŐW%}b,(a# `1,  @ ȸCrJ_;(H@C^@___37&:<@@cG @b` @@a @k1Ãq N1{  ƼA ;X?@&:<@@cG @b` @@a @k1Ãq N1{  ƼA ;X?@&:<@@cG @b` @@a @k1Ãq N1{  ƼA ;X?@&:<@@cG @b` @@a @k1Ãq N1{  ƼA ;X?@&:<@@cG @b` @@a @k1Ãq N1{  ƼA ;X?@&:<@@cG @b` @@a @k1Ãq N1{  ƼA ;X?@&:<@@cG @b` @@a @k1Ãq N1{  ƼA ;X?T@СCʕ+jڵMg߸q=z?~V;wN8p@رC?~<ӼmO۷ok cAr@c1G Pn1Ŭv -&Oܭib,a.B `"\ٳG}a5~xu5vX%'O6lhTяN8m.Y$iێ;x.^Ǐ'?O2%zjҞSΞ'ي;w}N,ZHP䘶{ne:H91L$eHE,>̋żlBzͅߞ/@\fʷ÷ž} E43;clٲDLxȻ۷O[n.XD|#n:nziZB$ɞN'KݻeDkKlCނH͔… ',H,"(8p  Yw dޕ ؝&/;9&c'0&^DCD XB䧦f ߴ(HOHy1V"\MČy\҉7x#)R}Z$dŀn.FWh#V<;|nDgI#O_X"OZa2 ZKi;k֬$'>Y)Duw_ ej ۂ^K1I y'gz  lU:[]8/3id5Ơ"!+ם"ӱ'% c%]_ҽ,$Ng Y`'_ӵtc?b7s][ײ~۷ꚄD n/ykN:>[fMB:Mn}uuMB: ̖ŖMn Q0ٚ"!x1㚊$kČ1?YYz dڎ|U%N(zo *]~̧l5c=VձYO7X"/g(ya_yOB0tK/IO [ofI}vtV(ܐ~ʊuWjpˠ%DB1k4]{\ k0"XIJ.^W=.fY6$*Iyj<<{Fn%^yBb-ŽW*^>'2 `KGH%f%hޤXY\~,o'ؖu`_{WB[ -VRᇒiI?}haWO(mI`,EBgmKx> ٢x#("{Gl I}?qa[s ͱ2J el]_i3=@ B$ 'q#`MBGL"^O "'l""f67IKPZC/ h#+A+oBR@$v8eD'q eh5/05?xHh'0"{Uo: 3Kx> ٢QK-%DB;DB;  @Jvgz xF߂@$Nv8  -l|`!&#Tz8   Op 0<"- Pb@h@"w L/ P"̪{#8@h@f z gz WK$߿__~?h֭w3~[/M6'Z*96k>zP?>lr_jFW_ջᆱ/| z뭷lٲx@?o|CopB۷Oe8Z&J-\2Twu5mٲEN{1;{ҥoI_61_N&nGlWL>h&{mmrOcߛ0۬_O'$moC$%~  6C^qwݿ5#衇oSb&q<.M& 3cƌ Heoݺ Y w "aX@m->w VnlK;p~{ޤo1ѣG1&N|!g.L$8)38 m6@@UII 6!=k,]zUk֬XjT  L"jq F5Dk5 DSSO=Uh` Ddk 8B@Y'!ɞn*7X&!=yO6t?Vje]1Ddb%kr@s {.y1 @ W 1"!P` 1 Pš7.㡆H C@EK k8 PD 7B5IWLBjA$g@9wE'C5CnG{؀H^c Y' P"FHHxQDB;L[  D3ƅ"! O$j-- F@ѱg DB@nA$XiarC#X)7^ "!phP$4VZ 0"0: q!H K "atBk `;0)7Cgz8@$Dgz<H`A$ CFP[#G )FRZ+74FG`o @$!DJ KS cv  ZC=yGDK =$Hh.mCb C$̑ I_t3Օ>{Pk! R"$0vJ@$"ᇒiI?nO+!VZhv^" 5@$%~)9IJ#K4Z@@% Jcw@B"ʕ+ڹs>3f ֝1߼y{"გKz@Je~+S쮟"~?B"aBy"2(z-Aҷ9"$PH$ԩSi&=z4ĉZzu dɒu϶ٳ}]!iڶJ냷.^Ǐ'mO2E'OիWٳxbݹsgs7Egu)͜93ٳg|rڵK/r?R8H$LI}/MI:;3 gΜOʷn?{RVґ#G`0ؼysm6$~d27o^m߸q:9s3qa+VW^ }lcmwgfʕ+s%v^~_b u J =@%Y%=+Ȩ~"HXJ$0lw?vXҥKs6lH&A"M[;vХK-XfM۬?D@z?8!bn/._\83D)tV[   $".fӓ?p@ˈ'|r-o iQi`2… ',H,", &^gHdwmce8@%O.+`wۃ2 UDv?k֬$Sde2~II(;NDB`gDd "sB 2EΝ/]PvLOqF^˖-K>XaڵIJ O{Yܭre˖d=yt{";}i GTбpd8e c@ "K/SŻ9P&t @IKB}ud ޱ`  Mҥ6 ڠL_E$< {!6DB@A$HLA$D(̄@ 93"10@$8DB@ΈDB$LDJ 9#S 8 3!)DB@C$HLA$D(̄@ 93"10@$8DB@ΈDB$LDJ 9#S 8 3!)DB@C$HLA$D(̄@ 93"10@$8DB@ΈDB$LDJ 9#S 8 3!)ewٻ5`(ABO2@@ 59@@W I@"f4@ DBW<8 @5@$ @]!H' @f @+ ]$ LP3P t"+d jJs @$tœ P3DB@i xq@j&H(ABO2@@ 59@@W I@"f4@ DBW<8 @5@$ @]!H' @f @+ ]$ LP3P t"+d jJs @$tœ P3DB@i xq@j&H(ABO2@@ 59@@W I@"f4@ DBW<8 @5@$ @]!H' @f @+ ]$ LP3P t"+d jJs @$tœi3$SҕAҭFMtPqI [JTVIzv^AA@$ @"v~DD&Iw옾 v Mo';v]I.𦤗$]>,twQI6f}TN_sSIIs$߶%uJ|I_ɚ~6HIJoDovH:kA󹮗7°@$L @H0Cm_ Hol2ߛloC6J򅆛,Mt+7cڶߵ7ߩtUc66)_M_n0lrmDqJwQ"!Fa(d7ߙmewkz"^-ߥwnu]P_1?K.?Omk'k@ߝHpNu\&hB,Ɍ"F@$Ԏ;J K$1=Fp1=YZJZKtJߕ3ABWHc.Dze(\teͽ\"-|Qt|h +,5K$wn(;DB u"Cd(C$yۻ ;"&-^]>/կ~i_?ln[޺^L&!O$ "pq#H  P@"!4lsjVMSf=`Y;β y"aS ~zٓ~?AI/xIpv'1vHJևkoM_nK ƇH( @I.KXds4I$]چ@z1"4 .  DB$L@@ m?@@$ 8 3!@m@$M @?"(%gIENDB`jsoncons-1.3.2/doc/ref/corelib/diagrams/json_decoder.png000066400000000000000000000117161477700171100232570ustar00rootroot00000000000000PNG  IHDR_e# tEXtmxfile%3Cmxfile%20modified%3D%222020-03-31T16%3A17%3A57.228Z%22%20host%3D%22app.diagrams.net%22%20agent%3D%22Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F80.0.3987.149%20Safari%2F537.36%22%20etag%3D%22IMpW-rBlLAYR1BFgObnB%22%20version%3D%2212.9.2%22%20type%3D%22device%22%3E%3Cdiagram%20id%3D%22iK-0d-7Yl-5MlnfMu26I%22%20name%3D%22Page-1%22%3EvVZNc9owEP01PqZjW0DhmABJW4ZMUzoDOWUUa2OrlSUqCzD99ZWwhC3bmZCZTLmgfavVx9u3Kwdompd3Em%2BzpSDAgjgkZYBmQRxHIRrrP4McK2QwsUAqKbGTamBF%2F4KLtOiOEii8iUoIpujWBxPBOSTKw7CU4uBPexHM33WLU%2BgAqwSzLrqmRGUVOh6GNf4FaJq5naPQenLsJlugyDARhwaE5gGaSiFUNcrLKTBDnuOlirt9xXs%2BmASuLgmY3%2F8s%2BeJhlcXTPwu1XuaP5bcru8oes5298DMuaPL0qxD8aU8LqoQM4hHTO9w8m1FqRvZC6uhYkmLHCZiNQu0%2BZFTBaosT4z1oXWgsUznTVnSObh7cnQKkgrIB2YvcgchByaOeYr1jy6kVVeQ4PtQpikYWyxrpGVgMW1Wk55Vr4vTAcvcOHj93eDwxSCDRFfHhDL5QxqaC6dSYWASnn8YLJcVvaHjQCE0Q%2BRjOLyJ9%2BD9JH3dI79AKnFybLqCthOFCS9tnEkqqNpZ0M340409Da83Khmt2dAbXh9%2B4BYzRiDJmHXayXNyrOSjETibwtroUlimot6sZiNfTuhltZKwvYQ6TwLCie78T9mXR7vBdUH2zs2AGvl5i1NJBdW0b1GxcrXUmLd2NW%2BtUtHTWOUnqfOmLVJbul1m8uN%2FgH5BerR8WsF9AT2l%2F5RlIqjDXSdMvG8WpxHlHerqslC82vzy54NCqZQthRlNuFKuFopsHujFFSvWbdG0dOSXEbNPbJ%2FxO8gGFH7USEIc9hY96dBS%2Fv%2FC1Wb%2BIVQbr7wo0%2Fwc%3D%3C%2Fdiagram%3E%3C%2Fmxfile%3E}IDATx^Mh[Ǐ14 %$(q!(o],\B'~&j6@LED10 .t /3.DD7*Aň.w8MY]ݯuoxê{ۿ:u|_ $H/wܿ=A2z$G2|MdԨQ؀΢|o_'sP3w#&jwĤ ɂ,:4(ߡQ&@/|H3 @rK$NM< o9`/w(_ؚ)_p B-fN#Ǭ;fױ0|  (_ M< o9%v ʗ{ q|OHtNʗ{(_ M< .RTTPxB>,2qĬm۶Imm̛7/s}puܚ\V\Ptt\xQv11˗/ԩSr0aB"_.<'NȘ1c,B3d  <"[(xs#_HogѣŤ^.7)&b)S;n8ill%KHGG\?~h;w. RWWgp>X1皚קoӎ(*n:;;R"2Aibݯ^T_\\l* .q^jh;w\Yfo6|;]78&+|UuɓuB'~eڕ/ʕ+f ++V0?zH.]j_z'Olo>ٵkWF:̙3e…y15[n &^>}uɽ{dѢE:րٳA;ڳgJȸpJJBkΝF ,0l"---ÇT:tH֮]kӶߴiTŹ /))15ݻwFO<R2.a9[*Gyto6BE^š<3TȽ7ϟT?~0!<'.{~;vȋ3ϬY2^uJvŨm ]}T[`_||H"YzG? sg[mLk@=߸o- Ү|oӰ9*\+lɎjavJ+xaWUBR8xqJzu|6 Ug"_N4)rԓ *_|!ly4uT !n7[gthְ{vox馷- Z~-uNyh( iS ?nahVGmF{!a:0GXۡ۴`'!vp]ol(}O{![bl{<|HV+ꉋ-{uˮD3C70)FקlsJ^Hx @(s(_ P>fݱ5S%[̜$ʗGYwl͔c a8!@3'a=@ P`x @(sJ>=@/@X&7蜒/ P`x @(sJV$/Q@_H2ECA`/wPc (_H#@sHI`$@|9WL$ׁ$0 P+&p@ (_r 8@u H?9I @:@$׿s$@|HC _ιb P$! G/\1 (_H#@sHI`$@|9WL$ׁ$0 P+&p@ (_r 8@u H?9I @:@$׿s$@|HC _ιb P$! G/\1 (_H#@sHI`$@|9WL$ׁ$0 P+&p@ (_r 8@u H?9I @:@$׿s$@|HB!BlڴI>,Sx*'N)ٶmʌ3b͛D9!===r ٿs޼y9H 7on܆Y 'mnnBN͹H Ed3,++3iii RWW'ZΙ3Go.Օ߿/7_^ 00^9ݻr56_/\DV\)w wxz{{S)⪩ԼgX~<5j@U ({xžOü/_{8Ɍ#GHgggygmq`Tn;حt|=yY&=@YЪ>C,⡞|=\~fLnff<"373#A$@y'@)$ (̌x wH2KVȍp$IENDB`jsoncons-1.3.2/doc/ref/corelib/diagrams/rename_object_key_filter.png000066400000000000000000000161421477700171100256310ustar00rootroot00000000000000PNG  IHDREeCMtEXtmxfile%3Cmxfile%20modified%3D%222020-03-31T16%3A21%3A06.117Z%22%20host%3D%22app.diagrams.net%22%20agent%3D%225.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F80.0.3987.149%20Safari%2F537.36%22%20etag%3D%22eQPi2CJdmI7oH4YWq3ap%22%20version%3D%2212.9.6%22%20type%3D%22device%22%3E%3Cdiagram%20id%3D%22iK-0d-7Yl-5MlnfMu26I%22%20name%3D%22Page-1%22%3E5VdNU9swEP01OdKxLRzCEZKU0gy0NMwAvWSEvdgCWUplJXH49ZViybZsUyhlSmeaS7RPWn28fbubDNA4K04EXqZnPAY6CLy4GKDJIAh8D43Ul0a2JRLuH5RAIkhsFtXAnDyC9TToisSQOwsl51SSpQtGnDGIpINhIfjGXXbHqXvqEifQAeYRpl30isQyLdFR6NX4JyBJak%2F2PTOTYbvYAHmKY75pQGg6QGPBuSxHWTEGqsmzvJR%2BH5%2BYrS4mgMmXOEzPLws2u5inwfjHTF6dZTfF5z2zyxrTlXnwLc5JtLjPOVvcESpBDIIhVQcc3%2BpRokfmPXJrSRJ8xWLQ53hqepMSCfMljvTsRslCYanMqLL8yrt5b3sJEBKKBmTecQI8Aym2aomZDfYNp0ZUvuV4U4fIHxosbYTH%2BmGjiqTauiZODQx3v8HjwRM8qkfiDBb89l6Jc%2FEA24rUP6FQ7UHHnHKx80Ww%2Byg8l4I%2FQGMGDdEhit%2BG9P2XkD76m6SPOqR3aAUWH%2BkqoKyI4lyFxGUSCiKvDel6fKPHH0JjTYrG1GRrDaYuf2030EbDS5u1286yfk%2FGIOcrEcHz6pJYJCCfz2aInZrWjWgjYmFPwCwmgGJJ1m4l7IuiOeErJ%2BpldZZ6rmAC1BJC%2BW7j1axc7Y3ClvJGrY1KYjob7URVPftFOkvWZ2kwO7%2FG3yDZu7qYwXoGPcl9ylIQRGKmwqZ6G8GJwFlHfCqxpCs3N0EZZ9DKZgNhShKmNaukoooFOtZpSlRXOjITGYljfUxvpXBryVvU2zB0I%2Bn1pD7qUVLwBqk%2FvPlyuef7%2BfftkfeIitP1wTDt6Vu2TeVLzGyjavSyNcmJ5FUzU4c2F757R3vPhtZLcPC%2F1Fb7o7JRW3%2BluH%2Bkto5apfXwlaW1ylq7UVtQry6tyqx%2F25bL638IaPoT%3C%2Fdiagram%3E%3C%2Fmxfile%3E =-IDATx^_Ƿ CHH$tP.! QfhZfie4LR#2Į$a|eof;fw wk}֚39x@ MaÆ &,6!"`|%E a9ǔJ(:z\GQԘpto>QUeEeEX @Qd! oݾO[?SQR5*6>[fTiUYEQYf;PYBm>[铼(lE MgUZUGQTVَEpkx$(J> EQmY냾ulFVEzQicE(4냾u>ɻo=(OF9HQԨpto>QUeEeEX @Qd! oݾO[?SQR5*6>[fTiUYEQYf;PYBm>[铼(lE MgUZUGQTVَEpkx$(J>Qt1{nuV7|pi~z}v7zںr[|[h1cFGז}rۖ-[܄ ܂ 6eH+7[o'|rHm(j2X̙3ɓO? i&fN4-]ԏ'Nmy}z?+;Gq?σ۷oFi(*3 ujkƍɈ"!$믿*WGꢨW\wϞ=r]Q(&WRv(E%Q/_|=sW_} Qt:dΜ9*=.\ߡC|~oذ]B`ݺu>7Sŋ QSsVLm,*T8dfVC1Ϟ=͛תx1Wv~w=yJǓC=4;>s3ϸUVy1a=?+p E(ݧ~UTp3;[oƍBvr~~~ ?QFKW=t =>qd !믾j߆ Νb2j&!Pl'<޽{*ESNUa yA^ޘa0Bʕ+`6k,/0b۶m/ɒ~_'g.hQk3f6ϟ?ŖL tLm;vlKe%T,ߡ^(A bzgK/,63m;vglgS1_t"O&TĹUQd~ȑV"'e{w/Hk$R8%KV#K,`KE.τlaOz\"QI"qAr8@_}U?ɒx@T q^6|{ꩧիM7ݔP&n%09=z2gx|ǽm8履~ciB `0{;5<&&\+  ?', J A )vKZ?Vy-K@/| Q&)Q=*"G"=kh٫'Ǥ 5Gׂ̤e"ļ=E> ^ >&>_L`V3B"JJH9x~<ɵPe!!'9;vR'Hb`-[q]ƻ_ X'==iI [/>@:'w Lz&D'ZOR;[07mh<KF[["/ 6 a֬=I,AL{[Ka8 ԩ(B\G"uSHo^Хt2kQa'NEЬE`<#.P<)"]9n"ca#*Ex@jHLEQTv䜵:kQ] Zåj<ͣ $DKEڏE.>as*E=EZ (1EPG.h1Z<䆿1(q.]H uE$Т&OR%=T`Dj"\7rHw=xYWogt8m(մ )Qc(!d@{"{REOyKz#1!HXiL/YERអvC+E'N{A\Tr雛yB&JQ(M2⋋\gyO}DR9YJI4k ,H%fbӔDQޒ[^YR@Qn/+;b+E"Vd`EFMv?|cN(mň=S })-Cb DK֞",A[yU~=E+ ooz=EVE5V+Ez/ 8p%J17cS]UDѣ>F)=EC-,{n0˅˚?KGQ qExޣo|֞"mezKK/=;zr+EZIu"P-S4?SՀG=E_ <,!"(v~E~KL/aĉ̘eShFV߸I] ·#D Z>d7iyoYEZwYۚbo`Z H{2oҕQ1m=~ cPu'q:οS>o%2%61c< k ط2SX^?J#B_cg}~{s moo>}}p"E8,oTlI(`x&ӯQ.)ΔX|\2[?#-r- ym7RQWs-嗵)Y;FH*>[oc+Ga_vK{TNPn}gA c& ̲AF!ITvVxML'E!^_[*=U~ו-EݒCFoݾ! 6AzYE&E# JQK 냾uJAzQ1mS"@QR4kAߺ}5 ;͎$`=("jAaJH냾uzg=()(J)5oݾfGEi @QT0mAߺ}igEєP͚b}зn_MN# X?@Z(E6oݾY?"hJ(RfM}>[aّEQd yZ-P"Lii}зn_AEs4%E)EXWӰH(2<(j>[/w󏢈9YS_iiv$GQHV -QT kidI  D`X;.%HHH4"q$@$@$@U(4!  0Mtxh @U("~HHHL(2G$@$@$PH   (LƑ TE*HHH4"q$@$@$@U(4!  0Mtxh @U("~HHHL(2G$@$@$PH   (LƑ TE*HHH4"q$@$@$@U(4!  0Mtxh @U("~HHHL(2G$@$@$PH   (LƑ TE*HHH4"q$@$@$@U(4!  0Mtxh @U("~HHHL(2G$@$@$PH   (LƑ TE*HHH4"q$@$@$@U(4!  0Mtxh @U("~HHHL(2G$@$@$PH   (LƑ TE*HHH4"q$@$@$@U(4!  0Mtxh @U("~HHHL(2$.\pK.uׯw'Nu۷ѣG ѕ+WݢEܤITGhϞ=ȑ#nӦMn͚53f 5^F$@q(8,rU"LlC@u h֭nUv;HLhq2~x_;v[n7tÆ nڵN*EӦMs+Vp'OvkU;fΜYx.^=|ۿ7oΝ;[3-X:t(QFq=zU]wNj AeOБ]w.]4R Zp׏9ҭ\߰"4;v7zV 2 PIm@D9y[d48 >VZ'wLϟ;w-[m۶ia%" *oL5koBG+`ӄ ԩS3 A2e/dp35ˋQKzEQ5ᮣ$ПE3H )R\tHTEdc$@ no " O1$@$@$@%(*"   ?ǐ @lHHHŽ#IENDB`jsoncons-1.3.2/doc/ref/corelib/diagrams/ser_error.png000066400000000000000000000217151477700171100226230ustar00rootroot00000000000000PNG  IHDR M,RtEXtmxfile%3Cmxfile%20modified%3D%222020-09-26T21%3A53%3A16.780Z%22%20host%3D%22app.diagrams.net%22%20agent%3D%225.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F85.0.4183.102%20Safari%2F537.36%22%20etag%3D%22qt9_wQHkXH4J__FItSaH%22%20version%3D%2213.7.1%22%20type%3D%22device%22%3E%3Cdiagram%20id%3D%22iK-0d-7Yl-5MlnfMu26I%22%20name%3D%22Page-1%22%3E7Vhdb9owFP01PHYicaDw2FLWbYhqHdtonyoruU28OTZzDIT%2B%2BtnE%2BXCSUlqhFq1DSPge29fOufdc7HTQKE4vBV5EUx4A7bjdIO2gi47rOl00UD8a2WSINzRAKEhgBpXAjDxAPtOgSxJAYg2UnFNJFjboc8bAlxaGheBre9g9p%2FaqCxxCA5j5mDbROQlklKGDXrfEPwEJo3xlp2t6YpwPNkAS4YCvKxAad9BIcC6zVpyOgGrycl6yeR8f6S02JoDJfSaMr76nbHI9i9zRn4mcT%2BPb9MuJ8bLCdGkeOJFq%2FJn6QurDQhLOzPblJudE8CULQLvtdtD5OiISZgvs6961ygKFRTKmynJUs7nNfE0QEtIKZLZ9CTwGKTZqiOntGwZNCg2NuS7jUbAeVWLhGQybFAgLxyVLqmGIegZpp4%2BTJpZMkhjuQKWeeHPi3O6RMTdoMNfgCFhwpnWrLJ%2FiJCG%2BTQukRN4YBnX7Vrc%2F9Ix1kVa6Lja5wdTmb3IH2qjM0mY5bWvl8x4NQcKXwoenU0RiEYJ8Wn8QWFWoGdBKxHotAcsxARRLsrJrV1sUzQpfOVFPVuSLZ6dLUbpyD9ljm0nVUlPzM7T9OKc1PxktDT%2FblCoeeq8sC1fTyJ1c3eBvEJ7MryewmsCuopZsEgnxkcgTeW8nz1bi3H9Qnrsy5El5nv6X5%2BHliZryBHEISd4TSkecKjd6LoLtR%2BGJFPw3VHpQHw1RcBgRe3U23aaKh68p4v57ETFqiniX2I9ExKh2mi1Ot89VsefUHDmvK%2BPmKfgzi0AQiZkKm7rxERwKHDeST%2BlK2ulm65NxBjUxGwhTEjKdsypVQOHnWqVE3dXOTEdMgkAv01oo7FJyAOUXGZEHALX8f6OWTKrX7ZdI37l3lw90czdzk%2F5i%2FGPwczxqu839Sji7O56bXP3E4%2FRe8cjTStm7OfK0VMtdOXQk1dKr3WBRvcjtXS3rYq2X3RdXS2WWL3Gy4eWrMDT%2BCw%3D%3D%3C%2Fdiagram%3E%3C%2Fmxfile%3EEIDATx^יǿ.t7XEXڲ"6A@6HnKYm&66R *T&TچVJ+dK5$,eKswr3sg33 3<<3;sf)n-4SB3ȳx 9Kx> ٢%dnci۷)S7䓘x %X,P)KBDB`$F$3K@Έ%e""!0Gp#% gD`J2#8  3"0%xxHĈbx AD@qLD$NbDB@1CL ^"8^&"w'1"!!^rFD/P/ ;P/9#S"(IH(f)KDDB`$F$3K@Έ%e""!0Gp#% gD`J2#8  3"0%xxHĈbx AD@qLD$NbDB@1CL ^"8^&"w'1"!!^rFD/P/k 7oc͝;wIݪUuV-Z(Xʗ/_N?|nܸBPbl3gNrچHG"!xŪywH9'-I%MmÖ> M Q Hh/z JOEm۶%vڥM6iƍ:z͛'Ojٽ֮]W&~2Ynw/Nڶ8 .رcS&wW\Issܹ$[q֭^ ';s̙3Zlvܩ&Ydeڸg͚5ldNb'6J2_@gIR,Ǐk,#rJ]x1wYe\ܼI+:uV^Xqӓs~KXo߾u%68]d?[ ,xm5lotGs=y6]9.m*f,sqwv K/vMqOc=~zzqc$~%VK*J"N7a۷k͚5I/7$o'N 6СC=a]bkMDvb0 ?`fǚ6 ؤc]WXkٳ׮][npݑ#Gd' 86E- w9pcoJY_SOiϞ=4fM6N$ݻ'̗7ob.ϗ6qXt4k߹r,Yd`ɢXA$4xUpC?Qݠg/yL$vOݞu?[qfO@3o~w5 ;W[aк"q^_W䘶}ve6H91L$eHE,>̋żlBvͅߞ/@\fʷ÷ž>c}DBd :ҥKqwC3!zw^mٲwgȺc v$k OHp'{6-矨.u* ]/y "V:7S , HND$m vVP5 ~)[1ˈY)Duw_&$,/&!chx"W"!/N/S0H4dUlwя.^"hdѯ_7 b {ݩ*|7+^|J,KISe{Dɒ"2kkvמM}̓'[okZïcvV]АHp 4oM´i&gˬIf)Э/qnIb^!ٲزw$ &[P@$/f\S1}嗓q7~g3K~9]\aLB۱/JGIn-^/c?+`J" e?iߧl5C=TձnpݱnE_p'Q*tC"lI @a>r8fn'E?5lmkIgP&w-} OTYJ n `cH2^\=ub?3b͕r㚽k}3H0n:V2"I'-1*-Abe`@BH]s̓'aTƱ_⥘׋,$,R{es,` >b[/-1+鍸Gu@$&Ţ_hf|+;#^vܻMh$8 ?Hq P/ X0]q*.!{'<ۈ|E}e_H;l%$>&ޚDžm@$4ǶR\+aۃu}WS@ B$ 'q#`MBGL"^7S5H qu EIu1dS0y+[ #.'qΪHƭFvњe% '5yh<l0tcd"&#awed%DB;Hhs^j>K]pgDBAPmFA;}4/#)A ډIDB;KI\;# @jk-x;Iϴ"&DB;Hhs^+AōoL 0z~H#@  ."% *A q"@ ,A 7"*9 6-A @/!L/ P{JMڲeo'=zTg?O:^{M>?>O7Zt^|Es=I_V ,?~.^8tU#P@WϿ+ʏj;^͛7뭷3<~:OӇ>D|ԗg;ffmn CI: )$\H(DBUr@mh"|NJykl̀[O EDBvMeLX Ddk_Q8${DꫯN(7dɄiӦ%N * OW Uq  4E7.6EB 8!nȾcg `4 "_, 3G@CPi&޸SK@T@(.- F;}"FǞ!0.n@#jg$RVIoTLBjA$g@9oF'CS$`"#vKx*7( +~,"8+@$TQ# C@$4igz8@$EB-D0: q!H-ZK "atB[ VZ%i[@Snh+v  @$ J dF@dFǞ!0. yxi0B$==C`\ t"}{&vh#L/g_Hx8}P/D "azŏE$gŞ@5j9jH0B^@4xnƇ"! _!FVZXHK3hF; F^Z|T$DBti@$}DlIEI}7)߼ySO=#Kɯ\RG{`ӦMglbI~ݺudXa͚5IJ NyYޭr}޼ys2:$'"!3&0s 9s 1E߭I%ݬhTI$t`t*IK$m7|8"!h`\@ &*'6JfK.oz?Y_KKڕiݒ\&5IK(i}X$\zQI6f>(QIzܐtBҲ~ߑd۶X7NJ'k|?{Mn?Ϗ$'෕߄tvHڟkA󹮓5eaX t &IH0Cm/H:w6K';f͖tHIpywٴm]{)YMW$G=f9atb/+Nxw}@ b6@?&3wf?aT$<]Mkk"g eVYmDvMBvsRd|_ى7_ϵa&Ē(b>!P;DBHi79f'3[.f'KKIkҴkoHȦ]9ԯ-4̮!p%=2OLd.Z•_MWؔv2YC$tDcXa@$ @]"vEݑ+*NeٓBLc" 2_lz"C${`Y :L(:D_[#/*l2 5X0/'rMyk|nI ƇHh4iw #PH>M`ܤگ&S1 }J,K`Y!O$ zO;{Oҳ{I+҆a[Ƞ!-{A`(q0 P˒-V,CM@$4I!#]; DB0 6DB  DB$L@@ m?@@$M4i" IENDB`jsoncons-1.3.2/doc/ref/corelib/encode_json.md000066400000000000000000000137111477700171100211310ustar00rootroot00000000000000### jsoncons::encode_json Encode a C++ data structure to a JSON formatted string or stream. `encode_json` will work for all types that have [json_type_traits](https://github.com/danielaparker/jsoncons/blob/master/doc/ref/corelib/json_type_traits.md) defined. ```cpp #include template void encode_json(const T& val, CharContainer& cont, const basic_json_encode_options& options = basic_json_encode_options(), indenting indent = indenting::no_indent); (1) template void encode_json(const T& val, std::basic_ostream& os, const basic_json_encode_options& options = basic_json_encode_options(), indenting indent = indenting::no_indent); (2) template void encode_json_pretty(const T& val, CharContainer& cont, const basic_json_encode_options& options = basic_json_encode_options()); (3) (since 0.155.0) template void encode_json_pretty(const T& val, std::basic_ostream& os, const basic_json_encode_options& options = basic_json_encode_options()); (4) (since 0.155.0) template void encode_json(const T& val, basic_json_visitor& encoder); (5) template void encode_json(const allocator_set& alloc_set, const T& val, CharContainer& cont, const basic_json_encode_options& options = basic_json_encode_options(), indenting indent = indenting::no_indent); (6) (since 0.171.0) template void encode_json(const allocator_set& alloc_set, const T& val, std::basic_ostream& os, const basic_json_encode_options& options = basic_json_encode_options(), indenting indent = indenting::no_indent); (7) (since 0.171.0) ``` (1) Encode `val` into a character container with the specified (or defaulted) [options](basic_json_options.md). (2) Encode `val` to an output stream with the specified (or defaulted) [options](basic_json_options.md). Functions (3)-(4) are identical to (1)-(2) except indenting is on. (5) Transform `val` into json events and stream through an encoder. Functions (6)-(7) are identical to (1)-(2) except an [allocator_set](allocator_set.md) is passed as an additional argument. #### Parameters
val C++ data structure
visitor JSON output visitor
options Serialization options
os Output stream
indenting indenting::indent to pretty print, indenting::no_indent for compact output
#### Return value None ### Examples #### Map with string-tuple pairs ```cpp #include #include #include #include using namespace jsoncons; int main() { using employee_collection = std::map>; employee_collection employees = { {"John Smith",{"Hourly","Software Engineer",10000}}, {"Jane Doe",{"Commission","Sales",20000}} }; std::cout << "(1)\n" << '\n'; encode_json(employees,std::cout); std::cout << "\n\n"; std::cout << "(2) Again, with pretty print\n" << '\n'; encode_json(employees, std::cout, indenting::indent); } ``` Output: ``` (1) {"Jane Doe":["Commission","Sales",20000.0],"John Smith":["Hourly","Software Engineer",10000.0]} (2) Again, with pretty print { "Jane Doe": ["Commission","Sales",20000.0], "John Smith": ["Hourly","Software Engineer",10000.0] } ``` #### Contain JSON output in an object (prettified output) ```cpp #include #include #include #include using namespace jsoncons; int main() { std::map> employees = { {"John Smith",{"Hourly","Software Engineer",10000}}, {"Jane Doe",{"Commission","Sales",20000}} }; json_stream_encoder encoder(std::cout); encoder.begin_object(); encoder.key("Employees"); encode_json(employees, encoder); encoder.end_object(); encoder.flush(); } ``` Output: ```json { "Employees": { "Jane Doe": ["Commission","Sales",20000.0], "John Smith": ["Hourly","Software Engineer",10000.0] } } ``` #### Contain JSON output in an object (compressed output) ```cpp #include #include #include #include using namespace jsoncons; int main() { std::map> employees = { {"John Smith",{"Hourly","Software Engineer",10000}}, {"Jane Doe",{"Commission","Sales",20000}} }; compact_json_stream_encoder encoder(std::cout); encoder.begin_object(); encoder.key("Employees"); encode_json(employees, encoder); encoder.end_object(); encoder.flush(); } ``` Output: ```json {"Employees":{"Jane Doe":["Commission","Sales",20000.0],"John Smith":["Hourly","Software Engineer",10000.0]}} ``` ### See also [basic_json_visitor](basic_json_visitor.md) [basic_json_options](basic_json_options.md) [basic_json_encoder](basic_json_encoder.md) [decode_json](decode_json.md) jsoncons-1.3.2/doc/ref/corelib/err_handler.md000066400000000000000000000020131477700171100211210ustar00rootroot00000000000000### JSON Parsing Error Handling ```cpp #include // (until 0.171.0) #include // (since 0.171.0) std::function ```
JSON parsing error handling is defined by a function object that receives arguments `std::error_code` and const `ser_context&`, and returns a `bool`. The JSON parser will report all errors through the function object. If the function object returns `true`, the parser will make an attempt to recover from recoverable errors. If the error is non-recoverable of if the function object returns `false`, the parser will stop. The jsoncons library comes with three built-in function objects for JSON parsing error handling: - `default_json_parsing`, which returns `true` if the error code indicates a comment, otherwise `false` - `strict_json_parsing`, which always returns `false` - `allow_trailing_commas`, which returns `true` if the error code indicates a comment or an extra comma, otherwise `false` jsoncons-1.3.2/doc/ref/corelib/float_chars_format.md000066400000000000000000000003201477700171100224700ustar00rootroot00000000000000### jsoncons::float_chars_format ```cpp #include enum class float_chars_format : uint8_t {general,fixed,scientific,hex}; ``` A type used to specify floating-point formatting. jsoncons-1.3.2/doc/ref/corelib/half_arg.md000066400000000000000000000003771477700171100204120ustar00rootroot00000000000000### jsoncons::half_arg ```cpp #include constexpr half_arg_t half_arg{}; ``` A constant of type [half_arg_t](half_arg_t.md) used as first argument to disambiguate constructor overloads for half precision floating point numbers. jsoncons-1.3.2/doc/ref/corelib/half_arg_t.md000066400000000000000000000004401477700171100207240ustar00rootroot00000000000000### jsoncons::half_arg_t ```cpp #include struct half_arg_t {explicit half_arg_t() = default;}; ``` `half_arg_t` is an empty class type used to disambiguate constructor overloads for half precision floating point numbers. ### See also [half_arg](half_arg.md) jsoncons-1.3.2/doc/ref/corelib/indenting.md000066400000000000000000000003071477700171100206170ustar00rootroot00000000000000### jsoncons::indenting ```cpp #include enum class indenting {no_indent, indent} ``` Specifies indentation options for the [basic_json_encoder](basic_json_encoder.md) jsoncons-1.3.2/doc/ref/corelib/json.md000066400000000000000000000044041477700171100176130ustar00rootroot00000000000000### jsoncons::json ```cpp #include typedef basic_json> json ``` The class `json` is an instantiation of the [basic_json](basic_json.md) class template that uses `char` as the character type. The order of an object's name/value pairs is not preserved, they are sorted alphabetically by name. If you want to preserve the original insertion order, use [ojson](ojson.md) instead. ### See also [ojson](ojson.md) constructs a utf8 character json value that preserves the original insertion order of an object's name/value pairs [wjson](wjson.md) constructs a wide character json value that sorts name-value members alphabetically [wojson](wojson.md) constructs a wide character json value that preserves the original insertion order of an object's name/value pairs ### Examples #### Accessors and defaults ```cpp json j; j["field1"] = 1; j["field3"] = "Toronto"; double x1 = obj.contains("field1") ? j["field1"].as() : 10.0; double x2 = obj.contains("field2") ? j["field2"].as() : 20.0; std::string x3 = obj.get_value_or("field3","Montreal"); std::string x4 = obj.get_value_or("field4","San Francisco"); std::cout << "x1=" << x1 << '\n'; std::cout << "x2=" << x2 << '\n'; std::cout << "x3=" << x3 << '\n'; std::cout << "x4=" << x4 << '\n'; ``` Output: ```cpp x1=1 x2=20 x3=Toronto x4=San Francisco ``` #### Nulls ```cpp json j; j["field1"] = json::null(); std::cout << j << '\n'; ``` Output: ```json {"field1":null} ``` #### Constructing json structures ```cpp json doc; doc["persons"] = json(json_array_arg); json person; person["first_name"] = "John"; person["last_name"] = "Smith"; person["birth_date"] = "1972-01-30"; json address; address["city"] = "Toronto"; address["country"] = "Canada"; person["address"] = std::move(address); doc["persons"].push_back(std::move(person)); std::cout << pretty_print(doc) << '\n'; ``` Output: ```cpp { "persons": [ { "address": { "city":"Toronto", "country":"Canada" }, "birth_date":"1972-01-30", "first_name":"John", "last_name":"Smith" } ] } ``` jsoncons-1.3.2/doc/ref/corelib/json/000077500000000000000000000000001477700171100172675ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/corelib/json/allocators.md000066400000000000000000000320271477700171100217600ustar00rootroot00000000000000### Allocators The class `basic_json` has an `Allocator` template parameter and an `allocator_type` member that indicates that it is allocator aware. `Allocator` must be a Scoped Allocator, that is, an allocator that applies not only to a `basic_json`'s data member, but also to its data member's elements. In particular, `Allocator` must be either a stateless allocator, a std::pmr::polymorphic_allocator, or a std::scoped_allocator_adaptor. Non-propagating stateful allocators, such as the [Boost.Interprocess allocators](https://www.boost.org/doc/libs/1_82_0/doc/html/interprocess/allocators_containers.html#interprocess.allocators_containers.allocator_introduction), must be wrapped by a [std::scoped_allocator_adaptor](https://en.cppreference.com/w/cpp/memory/scoped_allocator_adaptor). Every constructor has a version that accepts an allocator argument, this is required for allocator propogation. A long string, byte string, array or object makes use of the allocator argument to allocate storage. For the other data members (short string, number, boolean, or null) the allocator argument is ignored. A long string, byte string, array and object data member all contain a pointer `ptr` obtained from an earlier call to `allocate`. `ptr` points to storage that contains both the data representing the long string, byte string, array or object, and the allocator used to allocate that storage. To later deallocate that storage, the allocator is retrieved with `ptr->get_allocator()`. #### Propagation The allocator applies not only to a `basic_json`'s data member, but also to its data member's elements. For example: ```cpp char buffer[1024]; std::pmr::monotonic_buffer_resource pool{ std::data(buffer), std::size(buffer) }; std::pmr::polymorphic_allocator alloc(&pool); std::string key = "key too long for short string"; std::string value = "string too long for short string"; jsoncons::pmr::json j{ jsoncons::json_object_arg, alloc }; assert(j.get_allocator().resource() == &pool); j.try_emplace(key, value); auto it = std::search(std::begin(buffer), std::end(buffer), key.begin(), key.end()); assert(it != std::end(buffer)); it = std::search(std::begin(buffer), std::end(buffer), value.begin(), value.end()); assert(it != std::end(buffer)); ``` #### Copy construction The copy constructor ``` Json j1(j); ``` constructs `j1` from the contents of `j`. If `j` holds a long string, bytes string, array or object, copy construction applies allocator traits `select_on_container_copy_construction` to the allocator from `j` (since 0.178.0) For example: ```cpp char buffer[1024]; std::pmr::monotonic_buffer_resource pool{ std::data(buffer), std::size(buffer) }; std::pmr::polymorphic_allocator alloc(&pool); jsoncons::pmr::json j{ "String too long for short string", alloc }; assert(j.is_string()); assert(j.get_allocator().resource() == &pool); jsoncons::pmr::json j1(j); assert(j1 == j); assert(j1.get_allocator() == std::allocator_traits>:: select_on_container_copy_construction(j.get_allocator())); assert(j1.get_allocator() == std::pmr::polymorphic_allocator{}); // expected result for pmr allocators ``` #### Allocator-extended copy construction The allocator-extended copy constructor ``` Json j1(j, alloc); ``` constructs `j1` from the contents of `j` using `alloc` as the allocator. If `j` holds a long string, bytes string, array or object, copy construction uses allocator `alloc` for allocating storage, otherwise `alloc` is ignored. For example: ```cpp char buffer[1024]; std::pmr::monotonic_buffer_resource pool{ std::data(buffer), std::size(buffer) }; std::pmr::polymorphic_allocator alloc(&pool); char buffer1[1024]; std::pmr::monotonic_buffer_resource pool1{ std::data(buffer1), std::size(buffer1) }; std::pmr::polymorphic_allocator alloc1(&pool1); jsoncons::pmr::json j{ "String too long for short string", alloc }; assert(j.is_string()); assert(j.get_allocator().resource() == &pool); jsoncons::pmr::json j1(j, alloc1); assert(j1 == j); assert(j1.get_allocator().resource() == &pool1); ``` #### Move construction The move constructor ``` Json j1(std::move(j)); ``` constructs `j1` by taking the contents of `j`, which has either a pointer or a trivially copyable value, and replaces it with `null`. For example: ``` char buffer[1024]; std::pmr::monotonic_buffer_resource pool{ std::data(buffer), std::size(buffer) }; std::pmr::polymorphic_allocator alloc(&pool); jsoncons::pmr::json j{ "String too long for short string", alloc}; assert(j.is_string()); assert(j.get_allocator().resource() == &pool); jsoncons::pmr::json j1(std::move(j)); assert(j1.is_string()); assert(j1.get_allocator().resource() == &pool); assert(j.is_null()); ``` #### Allocator-extended move construction The allocator-extended move constructor ``` Json j1(std::move(j), alloc); ``` constructs `j1` with a copy of the data member `j`, using `alloc` as the allocator. For example: ```cpp char buffer[1024]; std::pmr::monotonic_buffer_resource pool{ std::data(buffer), std::size(buffer) }; std::pmr::polymorphic_allocator alloc(&pool); char buffer1[1024]; std::pmr::monotonic_buffer_resource pool1{ std::data(buffer1), std::size(buffer1) }; std::pmr::polymorphic_allocator alloc1(&pool1); jsoncons::pmr::json j{ "String too long for short string", alloc }; assert(j.is_string()); assert(j.get_allocator().resource() == &pool); jsoncons::pmr::json j1(std::move(j), alloc1); assert(j1.is_string()); assert(j1.get_allocator().resource() == &pool1); ``` #### Copy assignment If the left side is a long string, byte string, array or object, uses its allocator, otherwise, if the right side is a long string, byte string, array or object, constructs a copy of the right side as if using copy construction, i.e. applies allocator traits `select_on_container_copy_construction` to the right side allocator. For example: ```cpp char buffer[1024]; std::pmr::monotonic_buffer_resource pool{ std::data(buffer), std::size(buffer) }; std::pmr::polymorphic_allocator alloc(&pool); char buffer1[1024]; std::pmr::monotonic_buffer_resource pool1{ std::data(buffer1), std::size(buffer1) }; std::pmr::polymorphic_allocator alloc1(&pool1); jsoncons::pmr::json j{ "String too long for short string", alloc }; assert(j.is_string()); assert(j.get_allocator().resource() == &pool); // copy long string to number jsoncons::pmr::json j1{10}; j1 = j; assert(j1.is_string()); assert(j1.get_allocator() == std::allocator_traits>:: select_on_container_copy_construction(j.get_allocator())); assert(j1.get_allocator() == std::pmr::polymorphic_allocator{}); // copy long string to array jsoncons::pmr::json j2{ jsoncons::json_array_arg, {1,2,3,4}, jsoncons::semantic_tag::none, alloc1}; j2 = j; assert(j2.is_string()); assert(j2.get_allocator().resource() == &pool1); ``` `basic_json` does not check allocator traits `propagate_on_container_copy_assignment`. In the case of arrays and objects, `basic_json` leaves it to the implementing types (by default `std::vector`) to conform to the traits. #### Move assignment If either `j` or `j1` are a long string, byte string, array, or object, `basic_json` move assignment ``` j1 = std::move(j); ``` swaps the two data member values, such that two pointers are swapped or a pointer and a trivially copyable value are swapped. Otherwise, move assignment copies `j`'s value to `j1` and leaves `j` unchanged. For example: ```cpp char buffer[1024]; std::pmr::monotonic_buffer_resource pool{ std::data(buffer), std::size(buffer) }; std::pmr::polymorphic_allocator alloc(&pool); jsoncons::pmr::json j{ "String too long for short string", alloc }; assert(j.is_string()); assert(j.get_allocator().resource() == &pool); jsoncons::pmr::json j1{10}; assert(j1.is_number()); j1 = std::move(j); assert(j1.is_string()); assert(j1.get_allocator().resource() == &pool); assert(j.is_number()); ``` `basic_json` does not check allocator traits `propagate_on_container_move_assignment`. It simply swaps pointers, or a pointer and a trivial value, or copies a trivial value. #### Fancy pointers `basic_json` is compatible with boost [boost::interprocess::offset_ptr](https://www.boost.org/doc/libs/1_86_0/doc/html/interprocess/offset_ptr.html), provided that the implementing containers for arrays and objects are also compatible. In the example below, boost containers are used. ```cpp #include #include #include #include #include //std::system #include #include using shmem_allocator = boost::interprocess::allocator; using cust_allocator = std::scoped_allocator_adaptor; struct boost_sorted_policy { template using object = jsoncons::sorted_json_object; template using array = jsoncons::json_array; template using member_key = boost::interprocess::basic_string; }; using cust_json = jsoncons::basic_json; int main(int argc, char *argv[]) { typedef std::pair MyType; if (argc == 1) // Parent process { //Remove shared memory on construction and destruction struct shm_remove { shm_remove() { boost::interprocess::shared_memory_object::remove("MySharedMemory"); } ~shm_remove() noexcept { boost::interprocess::shared_memory_object::remove("MySharedMemory"); } } remover; //Construct managed shared memory boost::interprocess::managed_shared_memory segment(boost::interprocess::create_only, "MySharedMemory", 65536); //Initialize shared memory STL-compatible allocator const shmem_allocator alloc(segment.get_segment_manager()); // Create json value with all dynamic allocations in shared memory cust_json* j = segment.construct("MyJson")(jsoncons::json_array_arg, alloc); j->push_back(10); cust_json o(jsoncons::json_object_arg, alloc); o.try_emplace("category", "reference"); o.try_emplace("author", "Nigel Rees"); o.insert_or_assign("title", "Sayings of the Century"); o.insert_or_assign("price", 8.95); j->push_back(o); cust_json a(jsoncons::json_array_arg, 2, cust_json(jsoncons::json_object_arg, alloc), jsoncons::semantic_tag::none, alloc); a[0]["first"] = 1; j->push_back(a); std::pair res; res = segment.find("MyJson"); std::cout << "Parent process:\n"; std::cout << pretty_print(*(res.first)) << "\n\n"; //Launch child process std::string s(argv[0]); s += " child "; if (0 != std::system(s.c_str())) return 1; //Check child has destroyed all objects if (segment.find("MyJson").first) return 1; } else // Child process { //Open managed shared memory boost::interprocess::managed_shared_memory segment(boost::interprocess::open_only, "MySharedMemory"); std::pair res; res = segment.find("MyJson"); if (res.first != nullptr) { std::cout << "Child process:\n"; std::cout << pretty_print(*(res.first)) << "\n"; } else { std::cout << "Result is null\n"; } //We're done, delete all the objects segment.destroy("MyJson"); } return 0; } ``` Output: ``` Parent process: [ 10, { "author": "Nigel Rees", "category": "reference", "price": 8.95, "title": "Sayings of the Century" }, [ { "first": 1 }, {} ] ] Child process: [ 10, { "author": "Nigel Rees", "category": "reference", "price": 8.95, "title": "Sayings of the Century" }, [ { "first": 1 }, {} ] ] ``` #### References [An allocator-aware variant type](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3153r0.html) [C++ named requirements: Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator) [std::allocator_traits](https://en.cppreference.com/w/cpp/memory/allocator_traits) [std::pmr::polymorphic_allocator](https://en.cppreference.com/w/cpp/memory/polymorphic_allocator) [std::scoped_allocator_adaptor](https://en.cppreference.com/w/cpp/memory/scoped_allocator_adaptor) [Towards meaningful fancy pointers](https://quuxplusone.github.io/draft/fancy-pointers.html) jsoncons-1.3.2/doc/ref/corelib/json/array_range.md000066400000000000000000000021411477700171100221010ustar00rootroot00000000000000### jsoncons::basic_json::array_range ```cpp array_range_type array_range(); const_array_range_type array_range() const; ``` Returns a [range](range.md) that supports a range-based for loop over the elements of a `json` array Throws `std::domain_error` if not an array. ### Examples #### Range-based for loop ```cpp json j(json_array_arg); j.push_back("Montreal"); j.push_back("Toronto"); j.push_back("Vancouver"); for (const auto& val : j.array_range()) { std::cout << val.as() << '\n'; } ``` Output: ```json Montreal Toronto Vancouver ``` #### Array iterator ```cpp json j(json_array_arg, {"Montreal", "Toronto", "Vancouver"}); for (auto it = j.array_range().begin(); it != j.array_range().end(); ++it) { std::cout << it->as() << '\n'; } ``` Output: ```json Montreal Toronto Vancouver ``` #### Reverse array iterator ```cpp json j(json_array_arg, {"Montreal", "Toronto", "Vancouver"}); for (auto it = j.array_range().rbegin(); it != j.array_range().rend(); ++it) { std::cout << it->as() << '\n'; } ``` Output: ```json Vancouver Toronto Montreal ``` jsoncons-1.3.2/doc/ref/corelib/json/as.md000066400000000000000000000071701477700171100202210ustar00rootroot00000000000000### jsoncons::basic_json::as ```cpp template T as() const; (1) template T as(byte_string_arg_t, semantic_tag hint) const; (2) ``` (1) Generic get `as` type `T`. Attempts to convert the json value to the template value type using [json_type_traits](../json_type_traits.md). std::string as() const noexcept If value is string, returns value, otherwise returns result of [dump](dump.md). as>() If the type `X` is not `std::basic_string` but otherwise satisfies [SequenceContainer](http://en.cppreference.com/w/cpp/concept/SequenceContainer), `as>()` returns the `json` value as an `X` if the `json` value is an array and each element is convertible to type `T`, otherwise throws. as>() If the type 'X' satisfies [AssociativeContainer](http://en.cppreference.com/w/cpp/concept/AssociativeContainer) or [UnorderedAssociativeContainer](http://en.cppreference.com/w/cpp/concept/UnorderedAssociativeContainer), `as>()` returns the `json` value as an `X` if the `json` value is an object and if each member value is convertible to type `T`, otherwise throws. (2) Get as byte string with hint. This overload only participates in overload resolution if `uint8_t` is convertible to `T::value_type`. If the json type is a string, converts string according to its `semantic_tag`, or if there is none, uses `hint`. ### Examples #### Accessing integral, floating point, and boolean values ```cpp json j = json::parse(R"( { "k1" : 2147483647, "k2" : 2147483648, "k3" : -10, "k4" : 10.5, "k5" : true, "k6" : "10.5" } )"); std::cout << "(1) " << j["k1"].as() << '\n'; std::cout << "(2) " << j["k2"].as() << '\n'; std::cout << "(3) " << j["k2"].as() << '\n'; std::cout << "(4) " << j["k3"].as() << '\n'; std::cout << "(5) " << j["k3"].as() << '\n'; std::cout << "(6) " << j["k4"].as() << '\n'; std::cout << "(7) " << j["k4"].as() << '\n'; std::cout << std::boolalpha << "(8) " << j["k5"].as() << '\n'; std::cout << "(9) " << j["k6"].as() << '\n'; ``` Output: ``` (1) 2147483647 (2) -2147483648 (3) 2147483648 (4) (5) 4294967286 (6) 10 (7) 10.5 (8) true (9) 10.5 ``` #### Accessing a `json` array value as a `std::vector` ```cpp std::string s = "{\"my-array\" : [1,2,3,4]}"; json val = json::parse(s); std::vector v = val["my-array"].as>(); for (std::size_t i = 0; i < v.size(); ++i) { if (i > 0) { std::cout << ","; } std::cout << v[i]; } std::cout << '\n'; ``` Output: ``` 1,2,3,4 ``` #### Use string_view to access the actual memory that's being used to hold a string You can use `j.as()`, e.g. ```cpp json j = json::parse("\"Hello World\""); auto sv = j.as(); ``` `jsoncons::string_view` supports the member functions of `std::string_view`, including `data()` and `size()`. If your compiler supports `std::string_view`, you can also use `j.as()`. #### Accessing a `json` byte string as a byte string ```cpp std::vector u = {'H','e','l','l','o'}; json j(byte_string_arg, u, semantic_tag::base64); auto bytes = j.as>(); std::cout << "(1) "; for (auto b : bytes) { std::cout << (char)b; } std::cout << "\n\n"; std::string s; encode_json(j, s); // tag information is lost std::cout << "(2) " << s << "\n\n"; auto sj = decode_json(s); // provide hint auto v = sj.as>(byte_string_arg, semantic_tag::base64); assert(v == u); ``` Output: ``` (1) Hello (2) "SGVsbG8=" ``` jsoncons-1.3.2/doc/ref/corelib/json/at.md000066400000000000000000000030461477700171100202200ustar00rootroot00000000000000### jsoncons::basic_json::at ```cpp basic_json& at(const string_view_type& name); (1) const basic_json& at(const string_view_type& name) const; (2) const basic_json& at_or_null(const string_view_type& name) const; (3) basic_json& at(std::size_t i); (4) const basic_json& at(std::size_t i) const; (5) ``` (1)-(2) return a reference to the value with the specifed name in a `basic_json` object. If not an object, an exception of type `std::domain_error` is thrown. if the object does not have a member with the specified name, an exception of type `std::out_of_range` is thrown. (3) returns a const reference to the value in a basic_json object if `name` matches the name of a member, otherwise returns a const reference to a null `basic_json` value. Throws `std::domain_error` if not an object or null value. (4)-(5) return a reference to the element at index `i` in a basic_json array. If not an array, an exception of type `std::domain_error` is thrown. if the index is outside the bounds of the array, an exception of type `std::out_of_range` is thrown. ### Examples #### Return a value if available, a null if not ```cpp #include int main() { json j(json_object_arg, {{"author","Evelyn Waugh"},{"title","Sword of Honour"}}); std::cout << "(1) " << j.at_or_null("author").as() << "\n"; std::cout << "(2) " << j.at_or_null("title").as() << "\n"; std::cout << "(3) " << j.at_or_null("category").as() << "\n"; } ``` Output: ``` (1) Evelyn Waugh (2) Sword of Honour (3) null ``` jsoncons-1.3.2/doc/ref/corelib/json/constructor.md000066400000000000000000000244261477700171100222060ustar00rootroot00000000000000### `jsoncons::basic_json::basic_json` ```cpp basic_json(); (1) basic_json(const basic_json& other); (2) basic_json(const basic_json& other, const allocator_type& alloc); (3) basic_json(basic_json&& other) noexcept; (4) basic_json(basic_json&& other, const allocator_type& alloc) noexcept; (5) template basic_json(const T& val); (6) template basic_json(const T& val, const Allocator& alloc = Allocator()); template basic_json(Unsigned val, semantic_tag tag); (7) template basic_json(Signed val, semantic_tag tag); (8) basic_json(half_arg_t, uint16_t value, semantic_tag tag = semantic_tag::none); (9) basic_json(double val, semantic_tag tag); (10) explicit basic_json(json_array_arg_t, const Allocator& alloc = Allocator()); (11) basic_json(json_array_arg_t, semantic_tag tag, const Allocator& alloc = Allocator()); (12) basic_json(json_array_arg_t, std::size_t count, const basic_json& value, semantic_tag tag = semantic_tag::none, const Allocator& alloc = Allocator()); (13) (since 0.178.0) template basic_json(json_array_arg_t, InputIt first, InputIt last, semantic_tag tag = semantic_tag::none, const Allocator& alloc = Allocator()); (14) basic_json(json_array_arg_t, std::initializer_list init, semantic_tag tag = semantic_tag::none, const Allocator& alloc = Allocator()); (15) explicit basic_json(json_object_arg_t, const Allocator& alloc = Allocator()); (16) basic_json(json_object_arg_t, semantic_tag tag, const Allocator& alloc = Allocator()); (17) template basic_json(json_object_arg_t, InputIt first, InputIt last, semantic_tag tag = semantic_tag::none, const Allocator& alloc = Allocator()); (18) basic_json(json_object_arg_t, std::initializer_list,basic_json>> init, semantic_tag tag = semantic_tag::none, const Allocator& alloc = Allocator()); (19) template basic_json(const T& val); (20) template basic_json(const T& val, const allocator_type& alloc); basic_json(const char_type* val); (21) basic_json(const char_type* val, const allocator_type& alloc); (22) template basic_json(byte_string_arg_t, const Source& source, semantic_tag tag = semantic_tag::none, const Allocator& alloc = Allocator()); (23) template basic_json(byte_string_arg_t, const Source& source, uint64_t ext_tag, const Allocator& alloc = Allocator()); (24) basic_json(json_const_pointer_arg, const basic_json* ptr); (25) (since 0.156.0) basic_json(json_pointer_arg, basic_json* ptr); (26) (since 1.0.0) ``` (1) Constructs an empty json object. (2) Constructs a copy of val (3) Copy with allocator (4) Acquires the contents of val, leaving val a `null` value (5) Move with allocator (6) Constructs a `basic_json` value for types supported in [json_type_traits](json_type_traits.md). (7) Constructs a `basic_json` value from an unsigned integer and a [semantic_tag](../semantic_tag.md). This overload only participates in overload resolution if `Unsigned` is an unsigned integral type. (8) Constructs a `basic_json` value from a signed integer and a [semantic_tag](../semantic_tag.md). This overload only participates in overload resolution if `Signed` is a signed integral type. (9) Constructs a `basic_json` value for a half precision floating point number. Uses [half_arg_t](../half_arg_t.md) as first argument to disambiguate overloads that construct half precision floating point numbers. (10) Constructs a `basic_json` value from a double and a [semantic_tag](../semantic_tag.md). (11)-(15) use [json_array_arg_t](../json_aray_arg_t.md) as first argument to disambiguate overloads that construct json arrays. (11) Constructs a json array with the provided allocator. (12) Constructs a json array with the provided [semantic_tag](../semantic_tag.md) and allocator. (13) Constructs a json array with `count` copies of elements with value `value`. (14) Constructs a json array with the contents of the range `[first,last]`. `std::iterator_traits::value_type` must be convertible to `basic_json`. (15) Constructs a json array with the contents of the initializer list `init`. (16)-(19) use [json_object_arg_t](../json_object_arg_t.md) as first argument to disambiguate overloads that construct json objects. (16) Constructs a json object with the provided allocator. (17) Constructs a json object with the provided [semantic_tag](../semantic_tag.md) and allocator. (18) Constructs a json object with the contents of the range `[first,last]`. (19) Constructs a json object with the contents of the initializer list `init`. (20) Constructs a `basic_json` value for types supported in [json_type_traits](json_type_traits.md) with allocator. (21) Constructs a `basic_json` value from a text string. (22) Constructs a `basic_json` value from a text string with supplied allocator. (23) Constructs a `basic_json` value for a byte string from a contiguous byte sequence provided by `source` with a generic tag. Type `Source` must be a contiguous container that has member functions `data()` and `size()`, and member type `value_type` with width of exactly 8 bits (since 0.152.0.) Any of the values types `int8_t`, `uint8_t`, `char`, `unsigned char` and `std::byte` (since C++17) are allowed. Uses [byte_string_arg_t](../byte_string_arg_t.md) as first argument to disambiguate overloads that construct byte strings. (24) Constructs a `basic_json` value for a byte string from a contiguous byte sequence provided by `source` with a format specific tag. Type `Source` must be a contiguous container that has member functions `data()` and `size()`, and member type `value_type` with width of exactly 8 bits (since 0.152.0.) Any of the values types `int8_t`, `uint8_t`, `char`, `unsigned char` and `std::byte` (since C++17) are allowed. Uses [byte_string_arg_t](../byte_string_arg_t.md) as first argument to disambiguate overloads that construct byte strings. (25) Constructs a `basic_json` value that provides a non-owning view of another `basic_json` value. If second argument `ptr` is null, constructs a `null` value. (26) Constructs a `basic_json` value that provides a non-owning view of another `basic_json` value. If second argument `ptr` is null, constructs a `null` value. ### Helpers Helper |Definition --------------------|------------------------------ [json_object_arg][../json_object_arg.md] | [json_object_arg_t][../json_object_arg_t.md] | json object construction tag [json_array_arg][../json_array_arg.md] | [json_array_arg_t][../json_array_arg_t.md] | json array construction tag [byte_string_arg][../byte_string_arg.md] | [byte_string_arg_t][../byte_string_arg_t.md] | byte string construction tag [half_arg][../half_arg.md] | [half_arg_t][../half_arg_t.md] | half precision floating point number construction tag ### Examples #### Basic examples ```cpp #include #include #include #include #include using namespace jsoncons; int main() { json j1; // An empty object std::cout << "(1) " << j1 << '\n'; json j2(json_object_arg, {{"baz", "qux"}, {"foo", "bar"}}); // An object std::cout << "(2) " << j2 << '\n'; json j3(json_array_arg, {"bar", "baz"}); // An array std::cout << "(3) " << j3 << '\n'; json j4(json::null()); // A null value std::cout << "(4) " << j4 << '\n'; json j5(true); // A boolean value std::cout << "(5) " << j5 << '\n'; double x = 1.0/7.0; json j6(x); // A double value std::cout << "(6) " << j6 << '\n'; json j8("Hello"); // A text string std::cout << "(8) " << j8 << '\n'; std::vector v = {10,20,30}; json j9 = v; // From a sequence container std::cout << "(9) " << j9 << '\n'; std::map m{ {"one", 1}, {"two", 2}, {"three", 3} }; json j10 = m; // From an associative container std::cout << "(10) " << j10 << '\n'; std::vector bytes = {'H','e','l','l','o'}; json j11(byte_string_arg, bytes); // A byte string std::cout << "(11) " << j11 << '\n'; json j12(half_arg, 0x3bff); std::cout << "(12) " << j12.as_double() << '\n'; } ``` Output: ``` (1) {} (2) {"baz":"qux","foo":"bar"} (3) ["bar","baz"] (4) null (5) true (6) 0.14285714285714285 (8) "Hello" (9) [10,20,30] (10) {"one":1,"three":3,"two":2} (11) "SGVsbG8" (12) 0.999512 ``` #### A json array that contains non-owning references to other json values ```cpp #include #include int main() { std::string input = R"( { "machines": [ {"id": 1, "state": "running"}, {"id": 2, "state": "stopped"}, {"id": 3, "state": "running"} ] } )"; json j = json::parse(input); json j_v(json_array_arg); for (const auto& item : j.at("machines").array_range()) { if (item.at("state").as() == "running") { j_v.emplace_back(json_const_pointer_arg, &item); } } std::cout << "\n(1)\n" << pretty_print(j_v) << "\n\n"; for (const auto& item : j_v.array_range()) { std::cout << "json type: " << item.type() << ", storage kind: " << item.storage() << "\n"; } json j2 = deep_copy(j_v); std::cout << "\n(2)\n" << pretty_print(j2) << "\n\n"; for (const auto& item : j2.array_range()) { std::cout << "json type: " << item.type() << ", storage kind: " << item.storage() << "\n"; } } ``` Output: ```json (1) [ { "id": 1, "state": "running" }, { "id": 3, "state": "running" } ] json type: object, storage kind: json const pointer json type: object, storage kind: json const pointer (2) [ { "id": 1, "state": "running" }, { "id": 3, "state": "running" } ] json type: object, storage kind: object json type: object, storage kind: object ``` jsoncons-1.3.2/doc/ref/corelib/json/destructor.md000066400000000000000000000002451477700171100220100ustar00rootroot00000000000000### `jsoncons::basic_json::basic_json` ```cpp ~basic_json() noexcept; ``` Destroys all values and deletes all memory allocated for strings, arrays, and objects. jsoncons-1.3.2/doc/ref/corelib/json/dump.md000066400000000000000000000076451477700171100205720ustar00rootroot00000000000000### `jsoncons::basic_json::dump` ```cpp template void dump(CharContainer& cont, const basic_json_encode_options& options = basic_json_encode_options(), indenting = indenting::no_indent) const; (1) template void dump(CharContainer& cont, indenting indent) const; void dump(std::basic_ostream& os, const basic_json_encode_options& options = basic_json_encode_options(), indenting = indenting::no_indent) const; (2) void dump(std::basic_ostream& os, indenting indent) const; template void dump_pretty(CharContainer& cont, const basic_json_encode_options& options = basic_json_encode_options()) const; (3) void dump_pretty(std::basic_ostream& os, const basic_json_encode_options& options = basic_json_encode_options()) const; (4) void dump(basic_json_visitor& visitor) const; (5) ``` (1) Dumps a json value to a character container with "minified" output. (2) Dumps a json value to an output stream with "minified" output. Functions (3)-(4) are identical to (1)-(2) except indenting is on. (5) Dumps a json value to the specified [visitor](../basic_json_visitor.md). #### Exceptions Throws [ser_error](ser_error.md) if there is a serialization error. ### Examples #### Dump json value to csv file ```cpp #include #include using namespace jsoncons; int main() { const json books = json::parse(R"( [ { "title" : "Kafka on the Shore", "author" : "Haruki Murakami", "price" : 25.17 }, { "title" : "Women: A Novel", "author" : "Charles Bukowski", "price" : 12.00 }, { "title" : "Cutter's Way", "author" : "Ivan Passer" } ] )"); auto options = csv_options{} .column_names("author,title,price"); csv_stream_encoder encoder(std::cout, options); books.dump(encoder); } ``` Output: ```csv author,title,price Haruki Murakami,Kafka on the Shore,25.17 Charles Bukowski,Women: A Novel,12.0 Ivan Passer,Cutter's Way, ``` #### Dump json content into a larger document ```cpp #include using namespace jsoncons; int main() { const json some_books = json::parse(R"( [ { "title" : "Kafka on the Shore", "author" : "Haruki Murakami", "price" : 25.17 }, { "title" : "Women: A Novel", "author" : "Charles Bukowski", "price" : 12.00 } ] )"); const json more_books = json::parse(R"( [ { "title" : "A Wild Sheep Chase: A Novel", "author" : "Haruki Murakami", "price" : 9.01 }, { "title" : "Cutter's Way", "author" : "Ivan Passer", "price" : 8.00 } ] )"); json_stream_encoder encoder(std::cout); // pretty print encoder.begin_array(); for (const auto& book : some_books.array_range()) { book.dump(encoder); } for (const auto& book : more_books.array_range()) { book.dump(encoder); } encoder.end_array(); encoder.flush(); } ``` Output: ```json [ { "author": "Haruki Murakami", "price": 25.17, "title": "Kafka on the Shore" }, { "author": "Charles Bukowski", "price": 12.0, "title": "Women: A Novel" }, { "author": "Haruki Murakami", "price": 9.01, "title": "A Wild Sheep Chase: A Novel" }, { "author": "Ivan Passer", "price": 8.0, "title": "Cutter's Way" } ] ``` jsoncons-1.3.2/doc/ref/corelib/json/emplace.md000066400000000000000000000016031477700171100212170ustar00rootroot00000000000000### jsoncons::basic_json::emplace ```cpp template array_iterator emplace(Args&&... args); template array_iterator emplace(const_array_iterator pos, Args&&... args); ``` Constructs a new json element at the specified position of a json array, shifting all elements currently at or above that position to the right. #### Parameters pos Iterator that identifies the position in the array to construct the new json value args Arguments to forward to the constructor of the json value #### Return value Array iterator pointing to the emplaced value. #### Exceptions Throws `std::domain_error` if not a json array. ### Example ```cpp json a(json_array_arg); a.emplace_back("Toronto"); a.emplace_back("Vancouver"); a.emplace(a.array_range().begin(),"Montreal"); std::cout << a << '\n'; ``` Output: ```json ["Montreal","Toronto","Vancouver"] ``` jsoncons-1.3.2/doc/ref/corelib/json/emplace_back.md000066400000000000000000000007671477700171100222110ustar00rootroot00000000000000### jsoncons::basic_json::emplace_back ```cpp template json& emplace_back(Args&&... args); ``` #### Parameters args Arguments to forward to the constructor of the json value #### Return value A reference to the emplaced json value. #### Exceptions Throws `std::domain_error` if not a json array. ### Example ```cpp json arr(json_array_arg); arr.emplace_back(10); arr.emplace_back(20); arr.emplace_back(30); std::cout << arr << '\n'; ``` Output: ```json [10,20,30] ``` jsoncons-1.3.2/doc/ref/corelib/json/erase.md000066400000000000000000000046121477700171100207130ustar00rootroot00000000000000### `jsoncons::basic_json::erase` ```cpp void erase(const_array_iterator pos); (1) (until 0.168.6) array_iterator erase(const_array_iterator pos); (1) (since 0.168.6) void erase(const_array_iterator first, const_array_iterator last); (2) (until 0.168.6) array_iterator erase(const_array_iterator first, const_array_iterator last); (2) (since 0.168.6) void erase(const_object_iterator pos); (3) (until 0.168.6) object_iterator erase(const_object_iterator pos); (3) (since 0.168.6) void erase(const_object_iterator first, const_object_iterator last); (4) (until 0.168.6) object_iterator erase(const_object_iterator first, const_object_iterator last); (4) (since 0.168.6) void erase(const string_view_type& name); (5) ``` (1) Remove an element from an array at the specified position. Throws `std::domain_error` if not an array. (2) Remove the elements from an array in the range '[first,last)'. Throws `std::domain_error` if not an array. (3) Remove a member from an object at the specified position. Throws `std::domain_error` if not an object. (4) Remove the members from an object in the range '[first,last)'. Throws `std::domain_error` if not an object. (5) Remove a member with the specified name from an object Throws `std::domain_error` if not an object. ### Examples #### Iterating an array and erasing elements (since 0.168.6) ```cpp #include using jsoncons::json; int main() { std::string input = R"( ["a","b","c","d","e","f"] )"; json j = json::parse(input); auto it = j.array_range().begin(); while (it != j.array_range().end()) { if (*it == "a" || *it == "c") { it = j.erase(it); } else { it++; } } std::cout << j << "\n\n"; } ``` Output: ```json ["b","d","e","f"] ``` #### Iterating an object and erasing members (since 0.168.6) ```cpp #include using jsoncons::json; int main() { std::string input = R"( {"a":1, "b":2, "c":3, "d":4} )"; json j = json::parse(input); auto it = j.object_range().begin(); while (it != j.object_range().end()) { if (it->key() == "a" || it->key() == "c") { it = j.erase(it); } else { it++; } } std::cout << j << "\n\n"; } ``` Output: ```json {"b":2,"d":4} ``` jsoncons-1.3.2/doc/ref/corelib/json/get_value_or.md000066400000000000000000000016201477700171100222630ustar00rootroot00000000000000### jsoncons::basic_json::get_value_or ```cpp template T get_value_or(const string_view_type& name, U&& default_value) const; ``` Returns a value in a basic_json object if `name` matches the name of a member, otherwise returns a default value. Throws `std::domain_error` if not an object or null value. ### Type requirements - `T` must meet the requirements of [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) - `U` must be convertible to `T` ### Examples #### Return a value if available, a default value if not ```cpp #include int main() { json j(json_object_arg, {{"author","Evelyn Waugh"},{"title","Sword of Honour"}}); std::cout << j.get_value_or("author","unknown") << "\n"; std::cout << j.get_value_or("category","fiction") << "\n"; } ``` Output: ``` Evelyn Waugh fiction ``` jsoncons-1.3.2/doc/ref/corelib/json/insert.md000066400000000000000000000063451477700171100211250ustar00rootroot00000000000000### jsoncons::basic_json::insert ```cpp template array_iterator insert(const_array_iterator pos, T&& val); (1) template array_iterator insert(const_array_iterator pos, InputIt first, InputIt last); (2) ``` (1) Adds a new json element at the specified position of a json array, shifting all elements currently at or above that position to the right. The argument `val` is forwarded to the `json` constructor as `std::forward(val)`. Returns an `array_iterator` that points to the new value Throws `std::domain_error` if not an array. (2) Inserts elements from range [first, last) before pos. ``` template void insert(InputIt first, InputIt last); (3) ``` (3) Inserts elements from range `[first, last)` into a json object. If multiple elements in the range have the same key, the first element in the range is inserted. The function template parameter `InputIt` represents an input iterator type that iterates over elements of type `key_value_type`, or alternatively over elements of type `std::pair` where `T1` is convertible to `key_type` and `T2` is convertible to `basic_json`. ### Examples #### Creating an array of elements ```cpp json cities(json_array_arg); // an empty array std::cout << cities << '\n'; // output is "[]" cities.push_back("Toronto"); cities.push_back("Vancouver"); // Insert "Montreal" at beginning of array cities.insert(cities.array_range().begin(),"Montreal"); std::cout << cities << '\n'; ``` Output: ``` [] ["Montreal","Toronto","Vancouver"] ``` #### Creating an array of elements with reserved storage ```cpp json cities(json_array_arg); cities.reserve(10); // storage is reserved std::cout << "capacity=" << cities.capacity() << ", size=" << cities.size() << '\n'; cities.push_back("Toronto"); cities.push_back("Vancouver"); cities.insert(cities.array_range().begin(),"Montreal"); std::cout << "capacity=" << cities.capacity() << ", size=" << cities.size() << '\n'; std::cout << cities << '\n'; ``` Output: ``` capacity=10, size=0 capacity=10, size=3 ["Montreal","Toronto","Vancouver"] ``` ### Copy two std::map's into a json ```cpp std::map m1 = {{"f",4},{"e",5},{"d",6}}; std::map m2 = {{"c",1},{"b",2},{"a",3}}; json j; j.insert(m1.begin(),m1.end()); j.insert(m2.begin(),m2.end()); std::cout << j << "\n"; ``` Output: ``` {"a":3.0,"b":2.0,"c":1.0,"d":6.0,"e":5.0,"f":4.0} ``` ### Copy two std::map's into an ojson ```cpp std::map m1 = {{"f",4},{"e",5},{"d",6}}; std::map m2 = {{"c",1},{"b",2},{"a",3}}; ojson j; j.insert(m1.begin(),m1.end()); j.insert(m2.begin(),m2.end()); std::cout << j << "\n"; ``` Output: ``` {"d":6.0,"e":5.0,"f":4.0,"a":3.0,"b":2.0,"c":1.0} ``` ### Move two std::map's into a json ```cpp std::map m1 = {{"a",1},{"b",2},{"c",3}}; std::map m2 = {{"d",4},{"e",5},{"f",6}}; json j; j.insert(std::make_move_iterator(m1.begin()),std::make_move_iterator(m1.end())); j.insert(std::make_move_iterator(m2.begin()),std::make_move_iterator(m2.end())); std::cout << j << "\n"; ``` Output: ``` {"a":1.0,"b":2.0,"c":3.0,"d":4.0,"e":5.0,"f":6.0} ``` ### See also [push_back](push_back.md) jsoncons-1.3.2/doc/ref/corelib/json/insert_or_assign.md000066400000000000000000000016431477700171100231650ustar00rootroot00000000000000### jsoncons::basic_json::insert_or_assign ```cpp template pair insert_or_assign(const string_view_type& key, T&& value); (1) template object_iterator insert_or_assign(const_object_iterator hint, const string_view_type& key, T&& value); (2) ``` #### Parameters key The member name used to look up and, if not found, to insert hint An object iterator that provides a hint where to insert the new json value value Value to insert or assign #### Return value (1) returns a pair consisting of first, an iterator to the inserted value or the already existing value, and second, a bool indicating whether the insertion took place (true for insertion, false for no insertion.) (2) returns an iterator to the inserted value or the already existing value. #### Exceptions Throws `std::domain_error` if not a json object. jsoncons-1.3.2/doc/ref/corelib/json/is.md000066400000000000000000000070651477700171100202340ustar00rootroot00000000000000### jsoncons::basic_json::is ```cpp template bool is(Args&&... args) const noexcept; (1) bool is_null() const noexcept; (2) bool is_string() const noexcept; (3) bool is_int64() const noexcept; (4) bool is_uint64() const noexcept; (5) bool is_double() const noexcept; (6) bool is_number() const noexcept; (7) bool is_bool() const noexcept; (8) bool is_byte_string() const; (9) bool is_bignum() const; (10) bool is_array() const noexcept; (11) bool is_object() const noexcept; (12) ``` (1) Generic `is` equivalent to type `T`. Returns `true` if the json value is the same as type `T` according to [json_type_traits](../json_type_traits.md), `false` otherwise. bool is> const noexcept If the type `X` is not `std::basic_string` but otherwise satisfies [SequenceContainer](http://en.cppreference.com/w/cpp/concept/SequenceContainer), `is>()` returns `true` if the json value is an array and each element is the "same as" type `T` according to [json_type_traits](json_type_traits.md), `false` otherwise. bool is> const noexcept If the type 'X' satisfies [AssociativeContainer](http://en.cppreference.com/w/cpp/concept/AssociativeContainer) or [UnorderedAssociativeContainer](http://en.cppreference.com/w/cpp/concept/UnorderedAssociativeContainer), `is>()` returns `true` if the json value is an object and each mapped value is the "same as" `T` according to [json_type_traits](json_type_traits.md), `false` otherwise. (2) Same as `is()`. Returns `true` if the json value is null, `false` otherwise. (3) Same as `is()`. Returns `true` if the json value is of string type, `false` otherwise. (4) Same as `is()`. Returns `true` if the json value is integral and within the range of `int64_t`, `false` otherwise. (5) Same as `is()`. Returns `true` if the json value is integral and within the range of `uint64_t`, `false` otherwise. (6) Same as `is()`. Returns `true` if the json value is floating point and within the range of `double`, `false` otherwise. (7) Same as `is() || is() || is()`. (8) Same as `is()`. Returns `true` if the json value is of boolean type, `false` otherwise. (10) Same as `is()`. Returns `true` if `is() || is() is `true`, or if `is()` is `true` and the string holds an integer value, otherwise `false`. (11) Returns `true` if the json value is an array, `false` otherwise. (12) Returns `true` if the json value is an object, `false` otherwise. ### Examples ```cpp json j = json::parse(R"( { "k1" : 2147483647, "k2" : 2147483648, "k3" : -10, "k4" : 10.5, "k5" : true, "k6" : "10.5" } )"); std::cout << std::boolalpha << "(1) " << j["k1"].is() << '\n'; std::cout << std::boolalpha << "(2) " << j["k2"].is() << '\n'; std::cout << std::boolalpha << "(3) " << j["k2"].is() << '\n'; std::cout << std::boolalpha << "(4) " << j["k3"].is() << '\n'; std::cout << std::boolalpha << "(5) " << j["k3"].is() << '\n'; std::cout << std::boolalpha << "(6) " << j["k4"].is() << '\n'; std::cout << std::boolalpha << "(7) " << j["k4"].is() << '\n'; std::cout << std::boolalpha << "(8) " << j["k5"].is() << '\n'; std::cout << std::boolalpha << "(9) " << j["k5"].is() << '\n'; std::cout << std::boolalpha << "(10) " << j["k6"].is() << '\n'; ``` Output: ``` (1) true (2) false (3) true (4) true (5) false (6) false (7) true (8) false (9) true (10) false jsoncons-1.3.2/doc/ref/corelib/json/key_value.md000066400000000000000000000031561477700171100216020ustar00rootroot00000000000000### jsoncons::key_value ```cpp template class key_value ``` `key_value` stores a key (name) and a json value #### Member types Member type |Definition ------------------------------------|------------------------------ `key_type` |KeyT `value_type` |ValueT `string_view_type`|ValueT::string_view_type #### Accessors const key_type& key() const const json& value() const json& value() #### Non member functions
bool operator==(const key_value& lhs, const key_value& rhs) Returns true if two key_value objects compare equal, false otherwise.
bool operator!=(const key_value& lhs, const key_value& rhs) Returns true if two key_value objects do not compare equal, false otherwise.
bool operator<(const key_value& lhs, const key_value& rhs) Compares the contents of lhs and rhs lexicographically.
bool operator<=(const key_value& lhs, const key_value& rhs) Compares the contents of lhs and rhs lexicographically.
bool operator>(const key_value& lhs, const key_value& rhs) Compares the contents of lhs and rhs lexicographically.
bool operator>=(const key_value& lhs, const key_value& rhs) Compares the contents of lhs and rhs lexicographically.
jsoncons-1.3.2/doc/ref/corelib/json/make_array.md000066400000000000000000000041661477700171100217330ustar00rootroot00000000000000### jsoncons::basic_json::make_array ```cpp template static basic_json make_array(size_ n, const T& val) template static basic_json make_array(size_ n, const T& val, const allocator_type& alloc = allocator_type()) template static basic_json make_array(std::size_t size1 ... size_t sizeN) template static basic_json make_array(std::size_t size1 ... size_t sizeN, const T& val) template static basic_json make_array(std::size_t size1 ... size_t sizeN, const T& val, const allocator_type& alloc) ``` Makes a multidimensional array with the number of dimensions specified as a template parameter. The size of each dimension is passed as a parameter, and optionally an inital value. If no initial value, the default is an empty json object. The elements may be accessed using familiar C++ native array syntax. ### Examples #### Make an array of size 10 initialized with zeros ```cpp json a = json::make_array(10,0); // angle brackets can be omitted when N = 1 a[1] = 1; a[2] = 2; std::cout << pretty_print(a) << '\n'; ``` Output: ```json [0,1,2,0,0,0,0,0,0,0] ``` #### Make a two dimensional array of size 3x4 initialized with zeros ```cpp json a = json::make_array<2>(3,4,0); a[0][0] = "Tenor"; a[0][1] = "ATM vol"; a[0][2] = "25-d-MS"; a[0][3] = "25-d-RR"; a[1][0] = "1Y"; a[1][1] = 0.20; a[1][2] = 0.009; a[1][3] = -0.006; a[2][0] = "2Y"; a[2][1] = 0.18; a[2][2] = 0.009; a[2][3] = -0.005; std::cout << pretty_print(a) << '\n'; ``` Output: ```json [ ["Tenor","ATM vol","25-d-MS","25-d-RR"], ["1Y",0.2,0.009,-0.006], ["2Y",0.18,0.009,-0.005] ] ``` #### Make a three dimensional array of size 4x3x2 initialized with zeros ```cpp json a = json::make_array<3>(4,3,2,0); a[0][2][0] = 2; a[0][2][1] = 3; std::cout << pretty_print(a) << '\n'; ``` Output: ```json [ [ [0,0], [0,0], [2,3] ], [ [0,0], [0,0], [0,0] ], [ [0,0], [0,0], [0,0] ], [ [0,0], [0,0], [0,0] ] ] ``` jsoncons-1.3.2/doc/ref/corelib/json/merge.md000066400000000000000000000020231477700171100207050ustar00rootroot00000000000000### jsoncons::basic_json::merge ```cpp void merge(const basic_json& source); (1) void merge(basic_json&& source); (2) void merge(object_iterator hint, const basic_json& source); (3) void merge(object_iterator hint, basic_json&& source); (4) ``` Copies the key-value pairs in source json object into json object. If there is a member in source json object with key equivalent to the key of a member in json object, then that member is not copied. The `merge` function performs only a one-level-deep shallow merge, not a deep merge of nested objects. #### Parameters
source `json` object value
#### Return value None #### Exceptions Throws `std::domain_error` if source or *this are not json objects. ### Examples #### Merge `json` ```cpp json j = json::parse(R"( { "a" : 1, "b" : 2 } )"); const json source = json::parse(R"( { "a" : 2, "c" : 3 } )"); j1.merge(source); std::cout << j << endl; ``` Output: ```json {"a":1,"b":2,"c":3} ``` jsoncons-1.3.2/doc/ref/corelib/json/merge_or_update.md000066400000000000000000000020011477700171100227430ustar00rootroot00000000000000### jsoncons::basic_json::merge_or_update ```cpp void merge_or_update(const basic_json& source); (1) void merge_or_update(basic_json&& source); (2) void merge_or_update(object_iterator hint, const basic_json& source); (3) void merge_or_update(object_iterator hint, basic_json&& source); (4) ``` Inserts another json object's key-value pairs into a json object, or assigns them if they already exist. The `merge_or_update` function performs only a one-level-deep shallow merge, not a deep merge of nested objects. #### Parameters
source `json` object value
#### Return value None #### Exceptions Throws `std::domain_error` if source or *this are not json objects. ### Examples #### Merge or update `json` ```cpp json j = json::parse(R"( { "a" : 1, "b" : 2 } )"); const json source = json::parse(R"( { "a" : 2, "c" : 3 } )"); j1.merge_or_update(source); std::cout << j << endl; ``` Output: ```json {"a":2,"b":2,"c":3} ``` jsoncons-1.3.2/doc/ref/corelib/json/object_range.md000066400000000000000000000023741477700171100222410ustar00rootroot00000000000000### jsoncons::basic_json::object_range ```c++ object_range_type object_range(); const_object_range_type object_range() const; ``` Returns a [range](range.md) that supports a range-based for loop over the key-value pairs of a `basic_json` object Throws `std::domain_error` if not an object. ### Examples #### Range-based for loop over key-value pairs of an object ```c++ #include int main() { json j = json::parse(R"( { "category" : "Fiction", "title" : "Pulp", "author" : "Charles Bukowski", "date" : "2004-07-08", "price" : 22.48, "isbn" : "1852272007" } )"); for (const auto& member : j.object_range()) { std::cout << member.key() << " => " << member.value().as() << '\n'; } } ``` Output: ```json author => Charles Bukowski category => Fiction date => 2004-07-08 isbn => 1852272007 price => 22.48 title => Pulp ``` #### Reverse object iterator ```c++ ojson j; j["city"] = "Toronto"; j["province"] = "Ontario"; j["country"] = "Canada"; for (auto it = j.object_range().crbegin(); it != j.object_range().crend(); ++it) { std::cout << it->key() << " => " << it->value().as() << '\n'; } ``` Output: ```c++ country => Canada province => Ontario city => Toronto ``` jsoncons-1.3.2/doc/ref/corelib/json/operator=.md000066400000000000000000000007051477700171100215430ustar00rootroot00000000000000### `jsoncons::basic_json::operator=` ```cpp basic_json& operator=(const basic_json& rhs); basic_json& operator=(basic_json&& rhs) noexcept; (1) template basic_json& operator=(const T& rhs); (2) basic_json& operator=(const char_type* rhs); (3) ``` (1) Assigns a new `json` value to a `json` variable, replacing it's current contents. (2) Assigns the templated value to a `json` variable using [json_type_traits](json_type_traits.md). jsoncons-1.3.2/doc/ref/corelib/json/operator_at.md000066400000000000000000000057171477700171100221420ustar00rootroot00000000000000### jsoncons::basic_json::operator[] ```cpp proxy_type operator[](const string_view_type& key); (1) (until 1.0.0) reference operator[](const string_view_type& key); (since 1.0.0) const_reference operator[](const string_view_type& key) const; (2) reference operator[](std::size_t i); (3) const_reference operator[](std::size_t i) const; (4) ``` (1) Unitl 1.0.0, returns a "reference-like" proxy object that can be used to access or assign to the underlying keyed value. Since 0.179, returns a reference to the value mapped to `key`, inserting a default constructed value mapped to `key` if no such key already exists (a default constructed value is an empty object.) (2) Until 1.0.0, if `key` exists, returns a const reference to the `basic_json` value mapped to `key`, otherwise throws. Since 1.0.0, returns a const reference to the `basic_json` value mapped to `key`, returning a const reference to a default constructed `basic_json` value with static storage duration if no such key already exists. (3) Returns a reference to the value at index i in a `basic_json` object or array. Throws `std::domain_error` if not an object or array. (4) Returns a `const_reference` to the value at index i in a `basic_json` object or array. Throws `std::domain_error` if not an object or array. Exceptions (1) Throws `std::domain_error` if not an object. Until 1.0.0, throws a `std::out_of_range` if assigning to a `basic_json` and the key does not exist. Since 1.0.0, inserts a default constructed key-value pair if the key does not exist. (2) Throws `std::domain_error` if not an object. Until 1.0.0, throws a `std::out_of_range` if the key does not exist. Since 1.0.0, does (3) Throws `std::domain_error` if not an array. (4) Throws `std::domain_error` if not an array. #### Notes Unlike `std::map::operator[]`, a new element is never inserted into the container when this operator is used for reading but the key does not exist. ### Examples #### Assigning to an object when the key does not exist ```cpp int main() { json image_formats(json_array_arg, {"JPEG","PSD","TIFF","DNG"}); json color_spaces(json_array_arg); color_spaces.push_back("sRGB"); color_spaces.push_back("AdobeRGB"); color_spaces.push_back("ProPhoto RGB"); json export_settings; export_settings["File Format Options"]["Color Spaces"] = std::move(color_spaces); export_settings["File Format Options"]["Image Formats"] = std::move(image_formats); std::cout << pretty_print(export_settings) << "\n\n"; } ``` Output: ``` { "File Format Options": { "Color Spaces": ["sRGB", "AdobeRGB", "ProPhoto RGB"], "Image Formats": ["JPEG", "PSD", "TIFF", "DNG"] } } ``` Note that if `file_export["File Format Options"]` doesnt exist, the statement ``` file_export["File Format Options"]["Color Spaces"] = std::move(color_spaces) ``` creates "File Format Options" as an object and puts "Color Spaces" in it. jsoncons-1.3.2/doc/ref/corelib/json/parse.md000066400000000000000000000154601477700171100207310ustar00rootroot00000000000000### jsoncons::basic_json::parse ```cpp template static basic_json parse(const Source& source, const basic_json_decode_options& options = basic_json_decode_options()); (1) static basic_json parse(const char_type* str, const basic_json_decode_options& options = basic_json_decode_options()); (2) static basic_json parse(const char_type* str, std::size_t length, const basic_json_decode_options& options = basic_json_decode_options()); (3) static basic_json parse(std::basic_istream& is, const basic_json_decode_options& options = basic_json_decode_options()); (4) template static basic_json parse(InputIt first, InputIt last, const basic_json_decode_options& options = basic_json_decode_options()); (5) template static basic_json parse(const allocator_set& alloc_set, const Source& source, const basic_json_decode_options& options = basic_json_decode_options()); (6) (since 0.171.0) template static basic_json parse(const allocator_set& alloc_set, const char_type* str, const basic_json_decode_options& options = basic_json_decode_options()); (7) (since 0.171.0) template static basic_json parse(const allocator_set& alloc_set, const char_type* str, std::size_t length, const basic_json_decode_options& options = basic_json_decode_options()); (8) (since 0.177.0) template static basic_json parse(const allocator_set& alloc_set, std::basic_istream& is, const basic_json_decode_options& options = basic_json_decode_options()); (9) (since 0.171.0) template static basic_json parse(const allocator_set& alloc_set, InputIt first, InputIt last, const basic_json_decode_options& options = basic_json_decode_options()); (10) (since 0.171.0) ``` (1) Parses JSON data from a contiguous character sequence provided by `source` and returns a `basic_json` value. Throws a [ser_error](../ser_error.md) if parsing fails. (2) Parses JSON data from a null-terminated character string and returns a `basic_json` value. Throws a [ser_error](../ser_error.md) if parsing fails. (3) Parses JSON data from a string and length and returns a `basic_json` value. Throws a [ser_error](../ser_error.md) if parsing fails. (4) Parses JSON data from an input stream and returns a `basic_json` value. Throws a [ser_error](../ser_error.md) if parsing fails. (5) Parses JSON data from the range [`first`,`last`) and returns a `basic_json` value. Throws a [ser_error](../ser_error.md) if parsing fails. (6)-(10) Same as (1)-(5), except they accept an [allocator_set](allocator_set.md) argument. #### Parameters `source` = a contigugous character source, such as a `std::string` or `std::string_view` `str` - a character string `length` - the length of a character string `is` - an input stream `first`, `last` - pair of [LegacyInputIterators](https://en.cppreference.com/w/cpp/named_req/InputIterator) that specify a character sequence `options` - a [basic_json_options](../basic_json_options.md) `err_handler` - an error handler. Since 0.171.0, an error handler may be provided as a member of a [basic_json_options](../basic_json_options.md). ### Examples #### Parse from string ```cpp try { json val = json::parse("[1,2,3,4,]"); } catch(const jsoncons::ser_error& e) { std::cout << e.what() << '\n'; } ``` Output: ``` Extra comma at line 1 and column 10 ``` #### Parse from string with options ```cpp std::string s = R"({"field1":"NaN","field2":"PositiveInfinity","field3":"NegativeInfinity"})"; auto options = json_options{} .nan_to_str("NaN") .inf_to_str("PositiveInfinity") .neginf_to_str("NegativeInfinity"); json j = json::parse(s,options); std::cout << "\n(1)\n" << pretty_print(j) << '\n'; std::cout << "\n(2)\n" << pretty_print(j,options) << '\n'; ``` Output: ``` (1) { "field1": null, "field2": null, "field3": null } (2) { "field1": "NaN", "field2": "PositiveInfinity", "field3": "NegativeInfinity" } ``` #### Parse from stream Input JSON file `example.json`: ```json {"File Format Options":{"Color Spaces":["sRGB","AdobeRGB","ProPhoto RGB"]}} ``` ```cpp std::ifstream is("example.json"); json j = json::parse(is); std::cout << pretty_print(j) << '\n'; ``` Output: ```json { "File Format Options": { "Color Spaces": ["sRGB","AdobeRGB","ProPhoto RGB"] } } ``` #### Parse from pair of input iterators ```cpp #include class MyIterator { const char* p_; public: using iterator_category = std::input_iterator_tag; using value_type = char; using difference_type = std::ptrdiff_t; using pointer = const char*; using reference = const char&; MyIterator(const char* p) : p_(p) { } reference operator*() const { return *p_; } pointer operator->() const { return p_; } MyIterator& operator++() { ++p_; return *this; } MyIterator operator++(int) { MyIterator temp(*this); ++*this; return temp; } bool operator!=(const MyIterator& rhs) const { return p_ != rhs.p_; } }; int main() { char source[] = {'[','\"', 'f','o','o','\"',',','\"', 'b','a','r','\"',']'}; MyIterator first(source); MyIterator last(source + sizeof(source)); json j = json::parse(first, last); std::cout << j << "\n\n"; } ``` Output: ```json ["foo","bar"] ``` #### Parse a JSON text using a `std::pmr::polymorphic_allocator` allocator (since 0.171.0) ```cpp #include using namespace jsoncons; // for convenience using pmr_json = jsoncons::pmr::json; int main() { char buffer[1024] = {}; // a small buffer on the stack std::pmr::monotonic_buffer_resource pool{std::data(buffer), std::size(buffer)}; std::pmr::polymorphic_allocator alloc(&pool); std::string json_text = R"( { "street_number" : "100", "street_name" : "Queen St W", "city" : "Toronto", "country" : "Canada" } )"; try { auto doc = pmr_json::parse(combine_allocators(alloc), json_text); std::cout << pretty_print(doc) << "\n\n"; } catch (const std::exception& ex) { std::cerr << ex.what() << '\n'; } } ``` Output: ```json { "city": "Toronto", "country": "Canada", "street_name": "Queen St W", "street_number": "100" } ``` jsoncons-1.3.2/doc/ref/corelib/json/push_back.md000066400000000000000000000023571477700171100215570ustar00rootroot00000000000000### jsoncons::basic_json::push_back ```cpp template void push_back(T&& val) ``` Adds a new json element at the end of a json array. The argument `val` is forwarded to the `json` constructor as `std::forward(val)`. Throws `std::domain_error` if not an array. ### Examples #### Creating an array of elements ```cpp json cities(json_array_arg); // an empty array std::cout << cities << '\n'; // output is "[]" cities.push_back("Toronto"); cities.push_back("Vancouver"); // Insert "Montreal" at beginning of array cities.insert(cities.array_range().begin(),"Montreal"); std::cout << cities << '\n'; ``` Output: ``` [] ["Montreal","Toronto","Vancouver"] ``` #### Creating an array of elements with reserved storage ```cpp json cities(json_array_arg); cities.reserve(10); // storage is reserved std::cout << "capacity=" << cities.capacity() << ", size=" << cities.size() << '\n'; cities.push_back("Toronto"); cities.push_back("Vancouver"); cities.insert(cities.array_range().begin(),"Montreal"); std::cout << "capacity=" << cities.capacity() << ", size=" << cities.size() << '\n'; std::cout << cities << '\n'; ``` Output: ``` capacity=10, size=0 capacity=10, size=3 ["Montreal","Toronto","Vancouver"] ``` jsoncons-1.3.2/doc/ref/corelib/json/range.md000066400000000000000000000032661477700171100207140ustar00rootroot00000000000000### jsoncons::range ```cpp #include template class range; ``` Member type |Definition ------------------------------------|------------------------------ `iterator`|`IteratorT` `const_iterator`|`ConstIteratorT` `reverse_iterator`|`std::reverse_iterator` `const_reverse_iterator`|`std::reverse_iterator` ### Range access iterator begin(); (until 0.173.3) iterator begin() const noexcept; (since 0.173.3) const_iterator cbegin(); (until 0.173.3) const_iterator cbegin() const noexcept; (since 0.173.3) Returns an iterator to the beginning iterator end(); (until 0.173.3) iterator end() const noexcept; (since 0.173.3) const_iterator cend(); (until 0.173.3) const_iterator cend() const noexcept; (since 0.173.3) Returns an iterator to the end reverse_iterator rbegin(); (until 0.173.3) reverse_iterator rbegin() const noexcept; (since 0.173.3) const_reverse_iterator crbegin(); (until 0.173.3) const_reverse_iterator crbegin() const noexcept; (since 0.173.3) Returns a reverse iterator to the beginning reverse_iterator rend(); (until 0.173.3) reverse_iterator rend() const noexcept; (since 0.173.3) const_reverse_iterator crend(); (until 0.173.3) const_reverse_iterator crend() const noexcept; (since 0.173.3) Returns a reverse iterator to the end jsoncons-1.3.2/doc/ref/corelib/json/try_emplace.md000066400000000000000000000023461477700171100221220ustar00rootroot00000000000000### jsoncons::basic_json::try_emplace ```cpp template pair try_emplace(const string_view_type& key, Args&&... args); (1) template object_iterator try_emplace(const_object_iterator hint, const string_view_type& key, Args&&... args); (2) ``` #### Parameters key The key used both to look up and to insert if not found hint Iterator to the position before which the new element will be inserted args Arguments to forward to the constructor of the element #### Return value (1) returns a pair consisting of first, an iterator to the inserted value or the already existing value, and second, a bool indicating whether the insertion took place (true for insertion, false for no insertion.) (2) returns an iterator to the inserted value or the already existing value. #### Exceptions Throws `std::domain_error` if not a json object. ### Example ```cpp json a; a.try_emplace("object1",json()); a.try_emplace("field1","value1"); a["object1"].try_emplace("field2","value2"); std::cout << a << '\n'; ``` Output: ```json {"field1":"value1","object1":{"field2":"value2"}} ``` jsoncons-1.3.2/doc/ref/corelib/json_array_arg.md000066400000000000000000000004031477700171100216350ustar00rootroot00000000000000### jsoncons::json_array_arg ```cpp #include constexpr json_array_arg_t json_array_arg{}; ``` A constant of type [json_array_arg_t](json_array_arg_t.md) used as first argument to disambiguate constructor overloads for json arrays. jsoncons-1.3.2/doc/ref/corelib/json_array_arg_t.md000066400000000000000000000004541477700171100221660ustar00rootroot00000000000000### jsoncons::json_array_arg_t #include template json_decoder ``` ![json_decoder](./diagrams/json_decoder.png) #### Member types Member type |Definition ------------------------------------|------------------------------ `result_allocator_type`|Json::allocator_type (until 0.171.0) `allocator_type`|Json::allocator_type (since 0.171.0) `temp_allocator_type`|TempAllocator #### Constructors json_decoder(result_allocator_arg_t, const result_allocator_type& alloc); (1) (until 0.171.0) json_decoder(result_allocator_arg_t, const result_allocator_type& alloc, const temp_allocator_type& temp_alloc); (1) (until 0.171.0) json_decoder(const allocator_type& alloc = allocator_type(), const temp_allocator_type& temp_alloc = temp_allocator_type()); (1) (since 0.171.0) json_decoder(const temp_allocator_type& temp_alloc = temp_allocator_type()); (2) (until 0.171.0) json_decoder(temp_allocator_arg_t, const temp_allocator_type& temp_alloc); (2) (since 0.171.0) #### Member functions allocator_type get_allocator() const Returns the allocator associated with the json value. bool is_valid() const Checks if the decoder contains a valid `basic_json` value. Initially `is_valid()` is false, becomes `true` when a `basic_json` value has been received, and becomes false when `get_result()` is called. Json get_result() Returns the json value `v` stored in the decoder as `std::move(v)`. If before calling this function `is_valid()` is false, an `assertion_error` is thrown. After `get_result()` is called, 'is_valid()' becomes false. Once the result has been retrieved, `get_result` cannot be called again until another `basic_json` value has been received. ### Examples #### Decode a JSON text using stateful result and work allocators Input JSON file `book_catalog.json`: ```json [ { "author" : "Haruki Murakami", "title" : "Hard-Boiled Wonderland and the End of the World", "isbn" : "0679743464", "publisher" : "Vintage", "date" : "1993-03-02", "price": 18.90 }, { "author" : "Graham Greene", "title" : "The Comedians", "isbn" : "0099478374", "publisher" : "Vintage Classics", "date" : "2005-09-21", "price": 15.74 } ] ``` ```cpp int main() { // Given allocator my_alloc with a single-argument constructor my_alloc(int), // use my_alloc(1) to allocate basic_json memory, my_alloc(2) to allocate // working memory used by json_decoder, and my_alloc(3) to allocate // working memory used by basic_json_reader. using my_json = basic_json; std::ifstream is("book_catalog.json"); json_decoder decoder(my_alloc(1),my_alloc(2)); basic_json_reader,my_alloc> reader(is, decoder, my_alloc(3)); reader.read(); my_json j = decoder.get_result(); std::cout << pretty_print(j) << "\n"; } ``` Output: ``` [ { "author": "Haruki Murakami", "date": "1993-03-02", "isbn": "0679743464", "price": 18.9, "publisher": "Vintage", "title": "Hard-Boiled Wonderland and the End of the World" }, { "author": "Graham Greene", "date": "2005-09-21", "isbn": "0099478374", "price": 15.74, "publisher": "Vintage Classics", "title": "The Comedians" } ] ``` #### Decode a CSV text using stateful result and work allocators Input CSV file `bond_yields.csv`: ``` Date,1Y,2Y,3Y,5Y 2017-01-09,0.0062,0.0075,0.0083,0.011 2017-01-08,0.0063,0.0076,0.0084,0.0112 2017-01-08,0.0063,0.0076,0.0084,0.0112 ``` ```cpp int main() { // Given allocator my_alloc with a single-argument constructor my_alloc(int), // use my_alloc(1) to allocate basic_json memory, my_alloc(2) to allocate // working memory used by json_decoder, and my_alloc(3) to allocate // working memory used by basic_csv_reader. using my_json = basic_json; auto options = csv::csv_options{} .assume_header(true); std::ifstream is("bond_yields.csv"); json_decoder decoder(my_alloc(1),my_alloc(2)); csv::basic_csv_reader,free_list_allocator> reader(is, decoder, options, my_alloc(3)); reader.read(); my_json j = decoder.get_result(); std::cout << pretty_print(j) << "\n"; } ``` Output: ``` [ { "1Y": 0.0062, "2Y": 0.0075, "3Y": 0.0083, "5Y": 0.011, "Date": "2017-01-09" }, { "1Y": 0.0063, "2Y": 0.0076, "3Y": 0.0084, "5Y": 0.0112, "Date": "2017-01-08" }, { "1Y": 0.0063, "2Y": 0.0076, "3Y": 0.0084, "5Y": 0.0112, "Date": "2017-01-08" } ] ``` ### See also [basic_json_visitor](basic_json_visitor.md) jsoncons-1.3.2/doc/ref/corelib/json_error.md000066400000000000000000000035641477700171100210320ustar00rootroot00000000000000### jsoncons::json_errc ```cpp #include ```
The constant integer values scoped by `jsoncons::json_errc` define the values for json text error codes. ### Member constants constant |Description ------------------------------------|------------------------------ `unexpected_eof` |Unexpected end of file `syntax_error` |JSON syntax_error `extra_character` |Unexpected non-whitespace character after JSON text `json_nesting_too_deep` |Maximum JSON depth exceeded `single_quote` |JSON strings cannot be quoted with single quotes `illegal_character_in_string` |Illegal character in string `extra_comma` |Extra comma `expected_key` |Expected object member key `expected_value` |Expected value `invalid_value` |Invalid value `expected_colon` |Expected name separator ':' `illegal_control_character` |Illegal control character in string `illegal_escaped_character` |Illegal escaped character in string `expected_codepoint_surrogate_pair` |Invalid codepoint, expected another \\u token to begin the second half of a codepoint surrogate pair. `invalid_hex_escape_sequence` |Invalid codepoint, expected hexadecimal digit. `invalid_unicode_escape_sequence` |Invalid codepoint, expected four hexadecimal digits. `leading_zero` |A number cannot have a leading zero `invalid_number` |Invalid number `expected_comma_or_rbrace` |Expected comma or right brace ']' `expected_comma_or_rbracket` |Expected comma or right bracket '}' `unexpected_rbrace` |Unexpected right brace '}' `unexpected_rbracket` |Unexpected right bracket ']' jsoncons-1.3.2/doc/ref/corelib/json_object_arg.md000066400000000000000000000004111477700171100217640ustar00rootroot00000000000000### jsoncons::json_object_arg ```cpp #include constexpr json_object_arg_t json_object_arg{}; ``` A constant of type [json_object_arg_t](json_object_arg_t.md) used as first argument to disambiguate constructor overloads for json objects. jsoncons-1.3.2/doc/ref/corelib/json_object_arg_t.md000066400000000000000000000004611477700171100223140ustar00rootroot00000000000000### jsoncons::json_object_arg_t ```cpp #include struct json_object_arg_t {explicit json_object_arg_t() = default;}; ``` `json_object_arg_t` is an empty class type used to disambiguate constructor overloads for json objects. ### See also [json_object_arg](json_object_arg.md) jsoncons-1.3.2/doc/ref/corelib/json_type.md000066400000000000000000000004351477700171100206540ustar00rootroot00000000000000### jsoncons::json_type ```cpp #include enum class json_type : uint8_t { null_value, bool_value, int64_value, uint64_value, half_value, double_value, string_value, byte_string_value, array_value, object_value }; ``` jsoncons-1.3.2/doc/ref/corelib/json_type_traits.md000066400000000000000000000032151477700171100222410ustar00rootroot00000000000000### jsoncons::json_type_traits ```cpp #include ```
`json_type_traits` defines a compile time template based interface for conversion between a `basic_json` value and a value of some other type. `json_type_traits` implementations must specialize this traits class: ```cpp template struct json_type_traits { using allocator_type = Json::allocator_type; static constexpr bool is(const Json&) noexcept; static T as(const Json&); static Json to_json(const T& val); static Json to_json(const T& val, const allocator_type& alloc); }; ``` The function `json_type_traits::is(const Json& j)` indictates whether `j` satisfies the requirements of type `T`. This function supports the type selection strategy when converting a `Json` value to the proper derived class in the polymorphic case, and when converting a `Json` value to the proper alternative type in the variant case. The function `json_type_traits::as(const Json& j)` tries to convert `j` to a value of type `T`. The functions `json_type_traits::to_json(const T& val)` and `json_type_traits::to_json(const T& val, const allocator_type& alloc)` try to convert `val` into a `Json` value. jsoncons includes specializiations for most types in the standard library. And it includes convenience macros that make specializing `json_type_traits` for your own types easier. [Built-in Specializations](json_type_traits/built-in-specializations.md) [Convenience Macros](json_type_traits/convenience-macros.md) [Custom Specializations](json_type_traits/custom-specializations.md) jsoncons-1.3.2/doc/ref/corelib/json_type_traits/000077500000000000000000000000001477700171100217165ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/corelib/json_type_traits/built-in-specializations.md000066400000000000000000000452231477700171100271700ustar00rootroot00000000000000### Built-in Specializations jsoncons supports many types in the standard library. * [integer](#integer) Integer types, including `__int128` and `__uint128` if supported on the platform. * float and double * bool * [nullptr_t](https://en.cppreference.com/w/cpp/types/nullptr_t) (since 0.155.0) * [basic_string](#basic_string) - jsoncons supports [std::basic_string](https://en.cppreference.com/w/cpp/string/basic_string) with character types `char` and `wchar_t` * [basic_string_view](#basic_string_view) - jsoncons supports [std::basic_string_view](https://en.cppreference.com/w/cpp/string/basic_string_view) with character types `char` and `wchar_t` * [duration](#duration) (since 0.155.0) - covers [std::chrono::duration](https://en.cppreference.com/w/cpp/chrono/duration) for tick periods `std::ratio<1>` (one second), `std::milli` and `std::nano`. * [pair](#pair) * [tuple](#tuple) * [optional](#optional) * [shared_ptr and unique_ptr](#smart_ptr) - if `T` is a class that is not a polymorphic class, jsoncons provides specializations for `std::shared_ptr` and `std::unique_ptr` * [variant](#variant) (since 0.154.0) * [sequence containers](#sequence) - includes [std::array](https://en.cppreference.com/w/cpp/container/array), [std::vector](https://en.cppreference.com/w/cpp/container/vector), [std::deque](https://en.cppreference.com/w/cpp/container/deque), [std::forward_list](https://en.cppreference.com/w/cpp/container/forward_list) and [std::list](https://en.cppreference.com/w/cpp/container/list). * [associative containers](#associative) - includes [std::set](https://en.cppreference.com/w/cpp/container/set), [std::map](https://en.cppreference.com/w/cpp/container/map), [std::multiset](https://en.cppreference.com/w/cpp/container/multiset), and [std::multimap](https://en.cppreference.com/w/cpp/container/multimap). * [unordered associative containers](#unordered) - includes unordered associative containers [std::unordered_set](https://en.cppreference.com/w/cpp/container/unordered_set), [std::unordered_map](https://en.cppreference.com/w/cpp/container/unordered_map), [std::unordered_multiset](https://en.cppreference.com/w/cpp/container/unordered_multiset), and [std::unordered_multimap](https://en.cppreference.com/w/cpp/container/unordered_multimap). * [bitset](#bitset) (since 0.156.0) ### integer Supported integer types include integral types such as `char`, `int8_t`, `int`, `unsigned long long`, `int64_t`, and `uint64_t`. Also supported are 128 bit integer types `__int128` and `unsigned __int128`, if supported on the platform. jsoncons encodes integer types with size greater than 64 bit to strings if JSON, `bignum` if CBOR, and strings for all other formats. #### JSON example assuming gcc or clang ```cpp #include #include #include using jsoncons::json; int main() { json j1("-18446744073709551617", semantic_tag::bigint); std::cout << j1 << "\n\n"; __int128 val1 = j1.as<__int128>(); json j2(val1); assert(j2 == j1); __int128 val2 = j2.as<__int128>(); assert(val2 == val1); } ``` Output: ``` "-18446744073709551617" ``` #### CBOR example assuming gcc or clang ```cpp #include #include #include #include using jsoncons::json; namespace cbor = jsoncons::cbor; int main() { json j1("-18446744073709551617", semantic_tag::bigint); std::cout << "(1) " << j1 << "\n\n"; __int128 val1 = j1.as<__int128>(); std::vector data; cbor::encode_cbor(val1, data); std::cout << "(2) " << jsoncons::byte_string_view(data) << "\n\n"; /* c3, // Negative bignum 49,01,00,00,00,00,00,00,00,00 */ auto val2 = cbor::decode_cbor(data); CHECK((val2 == val1)); } ``` Output: ``` (1) "-18446744073709551617" (2) c3,49,01,00,00,00,00,00,00,00,00 ``` #### MessagePack example assuming gcc or clang ```cpp #include #include #include #include using jsoncons::json; namespace msgpack = jsoncons::msgpack; int main() { json j1("-18446744073709551617", semantic_tag::bigint); std::cout << "(1) " << j1 << "\n\n"; __int128 val1 = j1.as<__int128>(); std::vector data; msgpack::encode_msgpack(val1, data); std::cout << "(2) " << byte_string_view(data) << "\n\n"; /* b5, // fixstr, length 21 2d,31,38,34,34,36,37,34,34,30,37,33,37,30,39,35,35,31,36,31,37 */ auto val2 = msgpack::decode_msgpack(data); CHECK((val2 == val1)); } ``` Output: ``` (1) "-18446744073709551617" (2) b5,2d,31,38,34,34,36,37,34,34,30,37,33,37,30,39,35,35,31,36,31,37 ``` ### duration jsoncons supports [std::chrono::duration](https://en.cppreference.com/w/cpp/chrono/duration) for tick periods `std::ratio<1>` (one second), `std::milli` and `std::nano`. #### CBOR example (integer) ```cpp #include #include #include using jsoncons::json; namespace cbor = jsoncons::cbor; int main() { auto duration = std::chrono::system_clock::now().time_since_epoch(); auto time = std::chrono::duration_cast(duration); std::vector data; cbor::encode_cbor(time, data); /* c1, // Tag 1 (epoch time) 1a, // 32 bit unsigned integer 5f,23,29,18 // 1596139800 */ std::cout << "CBOR bytes:\n" << jsoncons::byte_string_view(data) << "\n\n"; auto seconds = cbor::decode_cbor(data); std::cout << "Time since epoch (seconds): " << seconds.count() << "\n"; } ``` Output: ``` CBOR bytes: c1,1a,5f,23,29,18 Time since epoch (seconds): 1596139800 ``` #### CBOR example (double) ```cpp #include #include #include using jsoncons::json; namespace cbor = jsoncons::cbor; int main() { auto duration = std::chrono::system_clock::now().time_since_epoch(); auto time = std::chrono::duration_cast>(duration); std::vector data; cbor::encode_cbor(time, data); /* c1, // Tag 1 (epoch time) fb, // Double 41,d7,c8,ca,46,1c,0f,87 // 1596139800.43845 */ std::cout << "CBOR bytes:\n" << jsoncons::byte_string_view(data) << "\n\n"; auto seconds = cbor::decode_cbor>(data); std::cout << "Time since epoch (seconds): " << seconds.count() << "\n"; auto milliseconds = cbor::decode_cbor(data); std::cout << "Time since epoch (milliseconds): " << milliseconds.count() << "\n"; } ``` Output: ``` CBOR bytes: c1,fb,41,d7,c8,ca,46,1c,0f,87 Time since epoch (seconds): 1596139800.43845 Time since epoch (milliseconds): 1596139800438 ``` #### MessagePack example (timestamp 32) ```cpp #include #include #include using jsoncons::json; namespace msgpack = jsoncons::msgpack; int main() { std::vector data = { 0xd6, 0xff, // timestamp 32 0x5a,0x4a,0xf6,0xa5 // 1514862245 }; auto seconds = msgpack::decode_msgpack(data); std::cout << "Seconds elapsed since 1970-01-01 00:00:00 UTC: " << seconds.count() << "\n"; } ``` Output: ``` Seconds elapsed since 1970-01-01 00:00:00 UTC: 1514862245 ``` #### MessagePack example (timestamp 64) ```cpp #include #include #include using jsoncons::json; namespace msgpack = jsoncons::msgpack; int main() { auto duration = std::chrono::system_clock::now().time_since_epoch(); auto dur_nano = std::chrono::duration_cast(duration); std::vector data; msgpack::encode_msgpack(dur_nano, data); /* d7, ff, // timestamp 64 e3,94,56,e0, // nanoseconds in 30-bit unsigned int 5f,22,b6,8b // seconds in 34-bit unsigned int */ std::cout << "MessagePack bytes:\n" << jsoncons::byte_string_view(data) << "\n\n"; auto nanoseconds = msgpack::decode_msgpack(data); std::cout << "nanoseconds elapsed since 1970-01-01 00:00:00 UTC: " << nanoseconds.count() << "\n"; auto milliseconds = msgpack::decode_msgpack(data); std::cout << "milliseconds elapsed since 1970-01-01 00:00:00 UTC: " << milliseconds.count() << "\n"; auto seconds = msgpack::decode_msgpack(data); std::cout << "seconds elapsed since 1970-01-01 00:00:00 UTC: " << seconds.count() << "\n"; } ``` Output: ``` nanoseconds elapsed since 1970-01-01 00:00:00 UTC: 1596128821304212600 milliseconds elapsed since 1970-01-01 00:00:00 UTC: 1596128821304 seconds elapsed since 1970-01-01 00:00:00 UTC: 1596128821 ``` #### MessagePack example (timestamp 96) ```cpp #include #include #include using jsoncons::json; namespace msgpack = jsoncons::msgpack; int main() { std::vector input = { 0xc7,0x0c,0xff, // timestamp 96 0x3b,0x9a,0xc9,0xff, // 999999999 nanoseconds in 32-bit unsigned int 0xff,0xff,0xff,0xff,0x7c,0x55,0x81,0x7f // -2208988801 seconds in 64-bit signed int }; auto milliseconds = msgpack::decode_msgpack(input); std::cout << "milliseconds elapsed since 1970-01-01 00:00:00 UTC: " << milliseconds.count() << "\n"; auto seconds = msgpack::decode_msgpack(input); std::cout << "seconds elapsed since 1970-01-01 00:00:00 UTC: " << seconds.count() << "\n"; } ``` Output: ``` milliseconds elapsed since 1970-01-01 00:00:00 UTC: -2208988801999 seconds elapsed since 1970-01-01 00:00:00 UTC: -2208988801 ``` #### BSON example ```cpp #include #include #include using jsoncons::json; namespace bson = jsoncons::bson; int main() { auto duration = std::chrono::system_clock::now().time_since_epoch(); auto time = std::chrono::duration_cast(duration); json j; j.try_emplace("time", time); auto milliseconds = j["time"].as(); std::cout << "Time since epoch (milliseconds): " << milliseconds.count() << "\n\n"; auto seconds = j["time"].as(); std::cout << "Time since epoch (seconds): " << seconds.count() << "\n\n"; std::vector data; bson::encode_bson(j, data); std::cout << "BSON bytes:\n" << jsoncons::byte_string_view(data) << "\n\n"; /* 13,00,00,00, // document has 19 bytes 09, // UTC datetime 74,69,6d,65,00, // "time" ea,14,7f,96,73,01,00,00, // 1595957777642 00 // terminating null */ } ``` Output: ``` Time since epoch (milliseconds): 1595957777642 Time since epoch (seconds): 1595957777 BSON bytes: 13,00,00,00,09,74,69,6d,65,00,ea,14,7f,96,73,01,00,00,00 ``` ### pair The pair specialization encodes an `std::pair` as a JSON array of size 2. ### tuple The tuple specialization encodes an `std::tuple` as a fixed size JSON array. #### Example ```cpp #include #include #include #include #include #include #include #include using qualifying_results_type = std::tuple; int main() { std::vector results = { {1,"Lewis Hamilton","Mercedes","1'24.303",std::chrono::milliseconds(0)}, {2,"Valtteri Bottas","Mercedes","1'24.616",std::chrono::milliseconds(313)}, {3,"Max Verstappen","Red Bull","1'25.325",std::chrono::milliseconds(1022)} }; std::string json_data; encode_json(results, json_data, indenting::indent); std::cout << json_data << "\n\n"; auto results1 = decode_json>(json_data); assert(results1 == results); auto csv_options = csv::csv_options{} .column_names("Pos,Driver,Entrant,Time,Gap") .mapping_kind(csv::csv_mapping_kind::n_rows) .header_lines(1); std::string csv_data; csv::encode_csv(results, csv_data, csv_options); std::cout << csv_data << "\n\n"; auto results2 = csv::decode_csv>(csv_data, csv_options); assert(results2 == results); std::vector bson_data; bson::encode_bson(results, bson_data); auto results3 = bson::decode_bson>(bson_data); assert(results3 == results); std::vector cbor_data; cbor::encode_cbor(results, cbor_data); auto results4 = cbor::decode_cbor>(cbor_data); assert(results4 == results); std::vector msgpack_data; msgpack::encode_msgpack(results, msgpack_data); auto results5 = msgpack::decode_msgpack>(msgpack_data); assert(results5 == results); std::vector ubjson_data; ubjson::encode_ubjson(results, ubjson_data); auto results6 = ubjson::decode_ubjson>(ubjson_data); assert(results6 == results); } ``` Output: ``` [ [1, "Lewis Hamilton", "Mercedes", "1'24.303", 0], [2, "Valtteri Bottas", "Mercedes", "1'24.616", 313], [3, "Max Verstappen", "Red Bull", "1'25.325", 1022] ] Pos,Driver,Entrant,Time,Gap 1,Lewis Hamilton,Mercedes,1'24.303,0 2,Valtteri Bottas,Mercedes,1'24.616,313 3,Max Verstappen,Red Bull,1'25.325,1022 ```
### shared_ptr and unique_ptr If `T` is a class that is not a polymorphic class (does not have any virtual functions), jsoncons provides specializations for `std::shared_ptr` and `std::unique_ptr`. #### Example ```cpp #include #include #include #include namespace ns { struct Model { Model() : x(0), y(0), z(0) {} std::string path; int x; int y; int z; }; struct Models { std::vector> models; }; } JSONCONS_ALL_MEMBER_TRAITS(ns::Model, path, x, y, z) JSONCONS_ALL_MEMBER_TRAITS(ns::Models, models) int main() { std::string input = R"( { "models" : [ {"path" : "foo", "x" : 1, "y" : 2, "z" : 3}, {"path" : "bar", "x" : 4, "y" : 5, "z" : 6}, {"path" : "baz", "x" : 7, "y" : 8, "z" : 9} ] } )"; auto models = jsoncons::decode_json>(input); for (auto& it : models->models) { std::cout << "path: " << it->path << ", x: " << it->x << ", y: " << it->y << ", z: " << it->z << "\n"; } std::cout << "\n"; jsoncons::encode_json(models, std::cout, indenting::indent); std::cout << "\n\n"; } ``` Output: ``` path: foo, x: 1, y: 2, z: 3 path: bar, x: 4, y: 5, z: 6 path: baz, x: 7, y: 8, z: 9 { "models": [ { "path": "foo", "x": 1, "y": 2, "z": 3 }, { "path": "bar", "x": 4, "y": 5, "z": 6 }, { "path": "baz", "x": 7, "y": 8, "z": 9 } ] } ``` ### variant #### Example ```cpp int main() { using variant_type = std::variant; std::vector v = {nullptr, 10, 5.1, true, std::string("Hello World")}; std::string buffer; jsoncons::encode_json(v, buffer, indenting::indent); std::cout << "(1)\n" << buffer << "\n\n"; auto v2 = jsoncons::decode_json>(buffer); auto visitor = [](auto&& arg) { using T = std::decay_t; if constexpr (std::is_same_v) std::cout << "nullptr " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "int " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "double " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "bool " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "std::string " << arg << '\n'; }; std::cout << "(2)\n"; for (const auto& item : v2) { std::visit(visitor, item); } } ``` Output: ``` (1) [ null, 10, 5.1, true, "Hello World" ] (2) nullptr nullptr int 10 double 5.1 bool true std::string Hello World ``` ### sequence containers #### Example ```cpp std::vector v{1, 2, 3, 4}; json j(v); std::cout << "(1) "<< j << '\n'; std::deque d = j.as>(); ``` Output: ``` (1) [1,2,3,4] ``` ### associative containers #### From std::map, to std::unordered_map ```cpp std::map m{{"one",1},{"two",2},{"three",3}}; json j(m); std::cout << j << '\n'; std::unordered_map um = j.as>(); ``` Output: ``` {"one":1,"three":3,"two":2} ``` #### std::map with integer key ```cpp std::map m{ {1,"foo",},{2,"baz"} }; json j{m}; std::cout << "(1)\n"; std::cout << pretty_print(j) << "\n\n"; auto other = j.as>(); std::cout << "(2)\n"; for (const auto& item : other) { std::cout << item.first << " | " << item.second << "\n"; } std::cout << "\n\n"; ``` Output: ```cpp (1) { "1": "foo", "2": "baz" } (2) 1 | foo 2 | baz ``` ### bitset jsoncons encodes a `std::bitset` into `base16` encoded strings (JSON) and byte strings (binary formats.) jsoncons can decode a `std::bitset` from integers, `base16` encoded strings and byte strings. #### JSON example ```cpp #include #include #include #include #include int main() { std::bitset<70> bs1(ULLONG_MAX); std::string s; encode_json(bs1, s); std::cout << s << "\n\n"; auto bs2 = decode_json>(s); assert(bs2 == bs1); } ``` Output: ``` "FFFFFFFFFFFFFFFF00" ``` #### CBOR example ```cpp #include #include #include #include #include #include int main() { std::bitset<8> bs1(42); std::vector data; cbor::encode_cbor(bs1, data); std::cout << byte_string_view(data) << "\n\n"; /* 0xd7, // Expected conversion to base16 0x41, // Byte string value of length 1 0x54 */ auto bs2 = cbor::decode_cbor>(data); assert(bs2 == bs1); } ``` Output: ``` d7,41,54 ``` jsoncons-1.3.2/doc/ref/corelib/json_type_traits/convenience-macros.md000066400000000000000000001466021477700171100260270ustar00rootroot00000000000000### Convenience Macros The `jsoncons` library provides a number of macros that can be used to generate the code to specialize `json_type_traits` for a user-defined class. Macro names follow naming conventions. Component | Description ----------|-------------------- TPL | Template class with a specified number of template parameters ALL | All data members are mandatory N | A specified number of data members are mandatory MEMBER | Accesses and modifies class data members CTOR | Requires constructor that takes all data members in the order they appear in the list GETTER | Accesses data members through getter functions SETTER | Modifies data members through setter functions NAME | Serialize with provided names (instead of C++ member names) The `_NAME_` macros are the most general. They allow optional parameters that affect data member mappings. Optionality is indicated by square brackets. The maximum number of parameters allowed in macros is 70 (since 0.168.4). Previously it was 50. ```cpp #include JSONCONS_N_MEMBER_TRAITS(class_name,num_mandatory, member0,member1,...) (1) JSONCONS_ALL_MEMBER_TRAITS(class_name, member0,member1,...) (2) JSONCONS_TPL_N_MEMBER_TRAITS(num_template_params, class_name,num_mandatory, member0,member1,...) (3) JSONCONS_TPL_ALL_MEMBER_TRAITS(num_template_params, class_name, member0,member1,...) (4) JSONCONS_N_MEMBER_NAME_TRAITS(class_name,num_mandatory, (member0,serialized_name0[,mode0,match0,into0,from0]), (member1,serialized_name1[,mode1,match1,into1,from1])...) (5) JSONCONS_ALL_MEMBER_NAME_TRAITS(class_name, (member0,serialized_name0[,mode0,match0,into0,from0]), (member1,serialized_name1[,mode1,match1,into1,from1])...) (6) JSONCONS_TPL_N_MEMBER_NAME_TRAITS(num_template_params, class_name,num_mandatory, (member0,serialized_name0[,mode0,match0,into0,from0]), (member1,serialized_name1[,mode1,match1,into1,from1])...) (7) JSONCONS_TPL_ALL_MEMBER_NAME_TRAITS(num_template_params, class_name, (member0,serialized_name0[,mode0,match0,into0,from0]), (member1,serialized_name1[,mode1,match1,into1,from1])...) (8) JSONCONS_ENUM_TRAITS(enum_name,enumerator0,enumerator1,...) (9) JSONCONS_ENUM_NAME_TRAITS(enum_name, (enumerator0,serialized_name0), (enumerator1,serialized_name1)...) (10) JSONCONS_N_CTOR_GETTER_TRAITS(class_name,num_mandatory, getter0, getter1,...) (11) JSONCONS_ALL_CTOR_GETTER_TRAITS(class_name, getter0,getter1,...) (12) JSONCONS_TPL_N_CTOR_GETTER_TRAITS(num_template_params, class_name,num_mandatory, getter0,getter1,...) (13) JSONCONS_TPL_ALL_CTOR_GETTER_TRAITS(num_template_params, class_name, getter0,getter1,...) (14) JSONCONS_N_CTOR_GETTER_NAME_TRAITS(class_name,num_mandatory, (getter0,serialized_name0[,mode0,match0,into0,from0]), (getter1,serialized_name1[,mode1,match1,into1,from1])...) (15) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(class_name, (getter0,serialized_name0[,mode0,match0,into0,from0]), (getter1,serialized_name1[,mode1,match1,into1,from1])...) (16) JSONCONS_TPL_N_CTOR_GETTER_NAME_TRAITS(num_template_params, class_name,num_mandatory, (getter0,serialized_name0[,mode0,match0,into0,from0]), (getter1,serialized_name1[,mode1,match1,into1,from1])...) (17) JSONCONS_TPL_ALL_CTOR_GETTER_NAME_TRAITS(num_template_params, class_name, (getter0,serialized_name0[,mode0,match0,into0,from0]), (getter1,serialized_name1[,mode1,match1,into1,from1])...) (18) JSONCONS_N_GETTER_SETTER_TRAITS(class_name,get_prefix,set_prefix,num_mandatory, property0,property1,...) (19) JSONCONS_ALL_GETTER_SETTER_TRAITS(class_name,get_prefix,set_prefix, property0,property1,...) (20) JSONCONS_TPL_N_GETTER_SETTER_TRAITS(num_template_params, class_name,get_prefix,set_prefix,num_mandatory, property0,property1,...) (21) JSONCONS_TPL_ALL_GETTER_SETTER_TRAITS(num_template_params, class_name,get_prefix,set_prefix, property0,property1,...) (22) JSONCONS_N_GETTER_SETTER_NAME_TRAITS(class_name,num_mandatory, (getter0,setter0,serialized_name0[,mode0,match0,into0,from0]), (getter1,setter1,serialized_name1[,mode1,match1,into1,from1])...) (23) JSONCONS_ALL_GETTER_SETTER_NAME_TRAITS(class_name, (getter0,setter0,serialized_name0[,mode0,match0,into0,from0]), (getter1,setter1,serialized_name1[,mode1,match1,into1,from1])...) (24) JSONCONS_TPL_N_GETTER_SETTER_NAME_TRAITS(num_template_params, class_name,num_mandatory, (getter0,setter0,serialized_name0[,mode0,match0,into0,from0]), (getter1,setter1,serialized_name1[,mode1,match1,into1,from1])...) (25) JSONCONS_TPL_ALL_GETTER_SETTER_NAME_TRAITS(num_template_params, class_name, (getter0,setter0,serialized_name0[,mode0,match0,into0,from0]), (getter1,setter1,serialized_name1[,mode1,match1,into1,from1])...) (26) JSONCONS_POLYMORPHIC_TRAITS(base_class_name,derived_class_name0,derived_class_name1,...) (27) ``` (1)-(4) generate the code to specialize `json_type_traits` for a class from member data. The serialized names are the stringified member names. When decoding to a C++ data structure, (1) and (3) require that the first `num_mandatory` member names be present in the JSON, the rest can have default values. (2) and (4) require that all member names be present in the JSON. The class must have a default constructor. If the member data or default constructor are private, the macro `JSONCONS_TYPE_TRAITS_FRIEND` will make them accessible to `json_type_traits`, used so ```cpp class MyClass { JSONCONS_TYPE_TRAITS_FRIEND ... }; ``` (3)-(4) generate the code to specialize `json_type_traits` for a class template from member data. (5)-(8) generate the code to specialize `json_type_traits` for a class from member data. The serialized names are the provided names. The sequence of `(memberN,serialized_nameN)` pairs declares the member name and provided name for each of the class members that are part of the sequence. When decoding to a C++ data structure, (5) and (7) require that the first `num_mandatory` member names be present in the JSON, the rest can have default values. (6) and (8) require that all member names be present in the JSON. The class must have a default constructor. If the member data or default constructor are private, the macro `JSONCONS_TYPE_TRAITS_FRIEND` will make them accessible to `json_type_traits`. (7)-(8) generate the code to specialize `json_type_traits` for a class template from member data. (9) generates the code to specialize `json_type_traits` for an enumerated type from its enumerators. The serialized name is the stringified enumerator name. (10) generates the code to specialize `json_type_traits` for an enumerated type from its enumerators. The serialized name is the provided name. The sequence of `(enumeratorN,serialized_nameN)` pairs declares the named constant and provided name for each of the enumerators that are part of the sequence. (11)-(14) generate the code to specialize `json_type_traits` for a class from a constructor and get functions. The serialized names are the stringified field names. When decoding to a C++ data structure, (11) and (13) require that the first `num_mandatory` member names be present in the JSON, the rest can have default values. (12) and (14) require that all member names be present in the JSON. The class must have a constructor such that the return types of the get functions are convertible to its parameters, taken in order. (13)-(14) generate the code to specialize `json_type_traits` for a class template from a constructor and get functions. (15)-(18) generate the code to specialize `json_type_traits` for a class from a constructor and get functions. The serialized names are the provided names. The sequence of `(getterN,serialized_nameN)` pairs declares the get function and provided name for each of the class members that are part of the sequence. When decoding to a C++ data structure, (15) and (17) require that the first `num_mandatory` member names be present in the JSON, the rest can have default values. (16) and (18) require that all member names be present in the JSON. The class must have a constructor such that the return types of the get functions are convertible to its parameters, taken in order. (17)-(18) generate the code to specialize `json_type_traits` for a class template from a constructor and get functions. (19)-(22) generate the code to specialize `json_type_traits` for a class from get and set functions. The serialized names are the stringified field names. The get and set function names are formed from the concatenation of `get_prefix` and `set_prefix` with field name. (19) and (21) require that the first `num_mandatory` member names be present in the JSON, the rest can have default values. (20) and (22) require that all member names be present in the JSON. (21)-(22) generate the code to specialize `json_type_traits` for a class template from get and set functions. (23)-(26) generate the code to specialize `json_type_traits` for a class from get and set functions. The serialized names are the provided names. The sequence of `(getterN,setterN,serialized_nameN)` triples declares the get and set functions and provided name for each of the class members that are part of the sequence. When decoding to a C++ data structure, (23) and (25) require that the first `num_mandatory` member names be present in the JSON, the rest can have default values. (24) and (26) require that all member names be present in the JSON. The class must have a default constructor. (25)-(26) generate the code to specialize `json_type_traits` for a class template from get and set functions. (27) generates the code to specialize `json_type_traits` for `std::shared_ptr` and `std::unique_ptr`. Each derived class must have a `json_type_traits` specialization. The type selection strategy is based on `json_type_traits::is(const Json& j)`. In the case that `json_type_traits` has been generated by one of the conveniences macros (1)-(26), the type selection strategy is based on the presence of members in the derived classes. #### Parameters
class_name The name of a class or struct.
enum_name The name of an enum type or enum class type.
num_mandatory The number of mandatory class data members or accessors.
num_template_params For a class template, the number of template parameters.
memberN The name of a class data member. Class data members are normally modifiable, but may be const or static const. Data members that are const or static const are one-way serialized.
propertyN The base name of a class getter or setter, with any get or set prefix stripped out.
getterN The getter for a class data member.
setterN The setter for a class data member.
enumeratorN An enumerator.
serialized_nameN Serialized name.
modeN Indicates whether a data member is read-write (JSONCONS_RDWR) or read-only (JSONCONS_RDONLY). Read-only data members are serialized but not de-serialized. (since 0.157.0)
matchN A function object that checks if a type that has json_type_traits specialization can be converted into a user value. It must have function call signature equivalent to

bool fun(const Type& a);

where Type matches the return type of function object intoN, if provided, and if not, the type of memberN (_MEMBER_ traits) or the return type of an accessor (_GETTER_ traits). It returns true if the argument provided matches an allowed value, false otherwise. (since 0.157.0)
intoN A function object that converts a user value into a type that has json_type_traits specialization. It must have function call signature equivalent to

Ret fun(const Type& a);

where Type matches the type of memberN (_MEMBER_ traits) or the return type of an accessor (_GETTER_ traits), and Ret is the parameter type of function object fromN (if provided) or Type (if not). It can be a free function, a struct object with operator() defined, or a variable containing a lambda expression, but because it is used in an unevaluated context, it cannot be a lambda expression (at least until C++20). (since 0.157.0)
fromN A function object that gets a user value from a type that has json_type_traits specialization. It must have function call signature equivalent to

Ret fun(const Type& a);

where Type is the return type of the function object intoN, and Ret is the is the type of memberN (_MEMBER_ traits) or the return type of an accessor (_GETTER_ traits). Only used if modeN is JSONCONS_RDWR. (since 0.157.0)
base_class_name The name of a base class.
derived_class_nameN A class that is derived from the base class, and that has a json_type_traits specialization.
These macro declarations must be placed at global scope, outside any namespace blocks, and `class_name`, `base_class_name` and `derived_class_nameN` must be a fully namespace qualified names. All of the `json_type_traits` specializations for type `T` generated by the convenience macros include a specialization of `is_json_type_traits_declared` with member constant `value` equal `true`. ### Examples [Specialize json_type_traits to support a book class](#A1) [Using JSONCONS_ALL_CTOR_GETTER_TRAITS to generate the json_type_traits](#A2) [Example with std::shared_ptr, std::unique_ptr and std::optional](#A3) [Serialize a polymorphic type based on the presence of members](#A4) [Ensuring type selection is possible](#A5) [Decode to a polymorphic type based on a type marker (since 0.157.0)](#A6) [An example with std::variant](#A7) [Type selection and std::variant](#A8) [Decode to a std::variant based on a type marker (since 0.158.0)](#A9) [Transform data member (since 0.157.0)](#A10) [Tidy data member (since 0.158.0)](#A11)
#### Specialize json_type_traits to support a book class. ```cpp #include #include #include #include namespace ns { struct book { std::string author; std::string title; double price; }; } // namespace ns JSONCONS_ALL_MEMBER_TRAITS(ns::book, author, title, price) using namespace jsoncons; // for convenience int main() { const std::string s = R"( [ { "author" : "Haruki Murakami", "title" : "Kafka on the Shore", "price" : 25.17 }, { "author" : "Charles Bukowski", "title" : "Pulp", "price" : 22.48 } ] )"; std::vector book_list = decode_json>(s); std::cout << "(1)\n"; for (const auto& item : book_list) { std::cout << item.author << ", " << item.title << ", " << item.price << "\n"; } std::cout << "\n(2)\n"; encode_json(book_list, std::cout, indenting::indent); std::cout << "\n\n"; } ``` Output: ``` (1) Haruki Murakami, Kafka on the Shore, 25.17 Charles Bukowski, Pulp, 22.48 (2) [ { "author": "Haruki Murakami", "price": 25.17, "title": "Kafka on the Shore" }, { "author": "Charles Bukowski", "price": 22.48, "title": "Pulp" } ] ```
#### Using JSONCONS_ALL_CTOR_GETTER_TRAITS to generate the json_type_traits The macro `JSONCONS_ALL_CTOR_GETTER_TRAITS` will generate the `json_type_traits` boilerplate for your own types from a constructor and getter functions. ```cpp #include #include #include namespace ns { enum class hiking_experience {beginner,intermediate,advanced}; class hiking_reputon { std::string rater_; hiking_experience assertion_; std::string rated_; double rating_; std::optional generated_; // use std::optional if C++17 std::optional expires_; public: hiking_reputon(const std::string& rater, hiking_experience assertion, const std::string& rated, double rating, const std::optional& generated = std::optional(), const std::optional& expires = std::optional()) : rater_(rater), assertion_(assertion), rated_(rated), rating_(rating), generated_(generated), expires_(expires) { } const std::string& rater() const {return rater_;} hiking_experience assertion() const {return assertion_;} const std::string& rated() const {return rated_;} double rating() const {return rating_;} std::optional generated() const {return generated_;} std::optional expires() const {return expires_;} friend bool operator==(const hiking_reputon& lhs, const hiking_reputon& rhs) { return lhs.rater_ == rhs.rater_ && lhs.assertion_ == rhs.assertion_ && lhs.rated_ == rhs.rated_ && lhs.rating_ == rhs.rating_ && lhs.confidence_ == rhs.confidence_ && lhs.expires_ == rhs.expires_; } friend bool operator!=(const hiking_reputon& lhs, const hiking_reputon& rhs) { return !(lhs == rhs); }; }; class hiking_reputation { std::string application_; std::vector reputons_; public: hiking_reputation(const std::string& application, const std::vector& reputons) : application_(application), reputons_(reputons) {} const std::string& application() const { return application_;} const std::vector& reputons() const { return reputons_;} }; } // namespace ns // Declare the traits. Specify which data members need to be serialized. JSONCONS_ENUM_TRAITS(ns::hiking_experience, beginner, intermediate, advanced) // First four members listed are mandatory, generated and expires are optional JSONCONS_N_CTOR_GETTER_TRAITS(ns::hiking_reputon, 4, rater, assertion, rated, rating, generated, expires) // All members are mandatory JSONCONS_ALL_CTOR_GETTER_TRAITS(ns::hiking_reputation, application, reputons) int main() { // Decode the string of data into a c++ structure ns::hiking_reputation v = decode_json(data); // Iterate over reputons array value std::cout << "(1)\n"; for (const auto& item : v.reputons()) { std::cout << item.rated() << ", " << item.rating(); if (item.generated()) { std::cout << ", " << (*item.generated()).count(); } std::cout << "\n"; } // Encode the c++ structure into a string std::string s; encode_json(v, s, indenting::indent); std::cout << "(2)\n"; std::cout << s << "\n"; } ``` Output: ``` (1) Marilyn C, 0.9, 1514862245 (2) { "application": "hiking", "reputons": [ { "assertion": "advanced", "generated": 1514862245, "rated": "Marilyn C", "rater": "HikingAsylum", "rating": 0.9 } ] } ```
#### Example with std::shared_ptr, std::unique_ptr and std::optional This example assumes C++17 language support for `std::optional`. Lacking that, you can use `jsoncons::optional`. ```cpp #include #include #include namespace ns { struct smart_pointer_and_optional_test { std::shared_ptr field1; std::unique_ptr field2; std::optional field3; std::shared_ptr field4; std::unique_ptr field5; std::optional field6; std::shared_ptr field7; std::unique_ptr field8; std::optional field9; std::shared_ptr field10; std::unique_ptr field11; std::optional field12; }; } // namespace ns // Declare the traits, first 6 members mandatory, last 6 non-mandatory JSONCONS_N_MEMBER_TRAITS(ns::smart_pointer_and_optional_test,6, field1,field2,field3,field4,field5,field6, field7,field8,field9,field10,field11,field12) using namespace jsoncons; // for convenience int main() { ns::smart_pointer_and_optional_test val; val.field1 = std::make_shared("Field 1"); val.field2 = jsoncons::make_unique("Field 2"); val.field3 = "Field 3"; val.field4 = std::shared_ptr(nullptr); val.field5 = std::unique_ptr(nullptr); val.field6 = std::optional(); val.field7 = std::make_shared("Field 7"); val.field8 = jsoncons::make_unique("Field 8"); val.field9 = "Field 9"; val.field10 = std::shared_ptr(nullptr); val.field11 = std::unique_ptr(nullptr); val.field12 = std::optional(); std::string buf; encode_json(val, buf, indenting::indent); std::cout << buf << "\n"; auto other = decode_json(buf); assert(*other.field1 == *val.field1); assert(*other.field2 == *val.field2); assert(*other.field3 == *val.field3); assert(!other.field4); assert(!other.field5); assert(!other.field6); assert(*other.field7 == *val.field7); assert(*other.field8 == *val.field8); assert(*other.field9 == *val.field9); assert(!other.field10); assert(!other.field11); assert(!other.field12); } ``` Output: ``` { "field1": "Field 1", "field2": "Field 2", "field3": "Field 3", "field4": null, "field5": null, "field6": null, "field7": "Field 7", "field8": "Field 8", "field9": "Field 9" } ```
#### Serialize a polymorphic type based on the presence of members This example uses the convenience macro `JSONCONS_N_CTOR_GETTER_TRAITS` to generate the `json_type_traits` boilerplate for the `HourlyEmployee` and `CommissionedEmployee` derived classes, and `JSONCONS_POLYMORPHIC_TRAITS` to generate the `json_type_traits` boilerplate for `std::shared_ptr` and `std::unique_ptr`. The type selection strategy is based on the presence of mandatory members, in particular, to the `firstName`, `lastName`, and `wage` members of an `HourlyEmployee`, and to the `firstName`, `lastName`, `baseSalary`, and `commission` members of a `CommissionedEmployee`. Non-mandatory members are not considered for the purpose of type selection. ```cpp #include #include #include #include using namespace jsoncons; namespace ns { class Employee { std::string firstName_; std::string lastName_; public: Employee(const std::string& firstName, const std::string& lastName) : firstName_(firstName), lastName_(lastName) { } virtual ~Employee() noexcept = default; virtual double calculatePay() const = 0; const std::string& firstName() const {return firstName_;} const std::string& lastName() const {return lastName_;} }; class HourlyEmployee : public Employee { double wage_; unsigned hours_; public: HourlyEmployee(const std::string& firstName, const std::string& lastName, double wage, unsigned hours) : Employee(firstName, lastName), wage_(wage), hours_(hours) { } double wage() const {return wage_;} unsigned hours() const {return hours_;} double calculatePay() const override { return wage_*hours_; } }; class CommissionedEmployee : public Employee { double baseSalary_; double commission_; unsigned sales_; public: CommissionedEmployee(const std::string& firstName, const std::string& lastName, double baseSalary, double commission, unsigned sales) : Employee(firstName, lastName), baseSalary_(baseSalary), commission_(commission), sales_(sales) { } double baseSalary() const { return baseSalary_; } double commission() const { return commission_; } unsigned sales() const { return sales_; } double calculatePay() const override { return baseSalary_ + commission_*sales_; } }; } // ns JSONCONS_N_CTOR_GETTER_TRAITS(ns::HourlyEmployee, 3, firstName, lastName, wage, hours) JSONCONS_N_CTOR_GETTER_TRAITS(ns::CommissionedEmployee, 4, firstName, lastName, baseSalary, commission, sales) JSONCONS_POLYMORPHIC_TRAITS(ns::Employee, ns::HourlyEmployee, ns::CommissionedEmployee) int main() { std::string input = R"( [ { "firstName": "John", "hours": 1000, "lastName": "Smith", "wage": 40.0 }, { "baseSalary": 30000.0, "commission": 0.25, "firstName": "Jane", "lastName": "Doe", "sales": 1000 } ] )"; auto v = decode_json>>(input); std::cout << "(1)\n"; for (const auto& p : v) { std::cout << p->firstName() << " " << p->lastName() << ", " << p->calculatePay() << "\n"; } std::cout << "\n(2)\n"; encode_json(v, std::cout, indenting::indent); std::cout << "\n\n(3)\n"; json j(v); std::cout << pretty_print(j) << "\n\n"; } ``` Output: ``` (1) John Smith, 40000 Jane Doe, 30250 (2) [ { "firstName": "John", "hours": 1000, "lastName": "Smith", "wage": 40.0 }, { "baseSalary": 30000.0, "commission": 0.25, "firstName": "Jane", "lastName": "Doe", "sales": 1000 } ] (3) [ { "firstName": "John", "hours": 1000, "lastName": "Smith", "wage": 40.0 }, { "baseSalary": 30000.0, "commission": 0.25, "firstName": "Jane", "lastName": "Doe", "sales": 1000 } ] ```
#### Ensuring type selection is possible When deserializing a polymorphic type, jsoncons needs to know how to convert a json value to the proper derived class. In the Employee example above, the type selection strategy is based on the presence of members in the derived classes. If derived classes cannot be distinguished in this way, you can introduce extra members. The convenience macros `JSONCONS_N_MEMBER_TRAITS`, `JSONCONS_ALL_MEMBER_TRAITS`, `JSONCONS_TPL_N_MEMBER_TRAITS`, `JSONCONS_TPL_ALL_MEMBER_TRAITS`, `JSONCONS_N_MEMBER_NAME_TRAITS`, `JSONCONS_ALL_MEMBER_NAME_TRAITS`, `JSONCONS_TPL_N_MEMBER_NAME_TRAITS`, and `JSONCONS_TPL_ALL_MEMBER_NAME_TRAITS` allow you to have `const` or `static const` data members that are serialized and that particpate in the type selection strategy during deserialization. ```cpp namespace ns { class Foo { public: virtual ~Foo() noexcept = default; }; class Bar : public Foo { static const bool bar = true; JSONCONS_TYPE_TRAITS_FRIEND }; class Baz : public Foo { static const bool baz = true; JSONCONS_TYPE_TRAITS_FRIEND }; } // ns JSONCONS_N_MEMBER_TRAITS(ns::Bar,1,bar) JSONCONS_N_MEMBER_TRAITS(ns::Baz,1,baz) JSONCONS_POLYMORPHIC_TRAITS(ns::Foo, ns::Bar, ns::Baz) int main() { std::vector> u; u.emplace_back(new ns::Bar()); u.emplace_back(new ns::Baz()); std::string buffer; encode_json(u, buffer); std::cout << "(1)\n" << buffer << "\n\n"; auto v = decode_json>>(buffer); std::cout << "(2)\n"; for (const auto& ptr : v) { if (dynamic_cast(ptr.get())) { std::cout << "A bar\n"; } else if (dynamic_cast(ptr.get())) { std::cout << "A baz\n"; } } } ``` Output: ``` (1) [{"bar":true},{"baz":true}] (2) A bar A baz ```
#### Decode to a polymorphic type based on a type marker (since 0.157.0) ```cpp namespace ns { class Shape { public: virtual ~Shape() = default; virtual double area() const = 0; }; class Rectangle : public Shape { double height_; double width_; public: Rectangle(double height, double width) : height_(height), width_(width) { } const std::string& type() const { static const std::string type_ = "rectangle"; return type_; } double height() const { return height_; } double width() const { return width_; } double area() const override { return height_ * width_; } }; class Triangle : public Shape { double height_; double width_; public: Triangle(double height, double width) : height_(height), width_(width) { } const std::string& type() const { static const std::string type_ = "triangle"; return type_; } double height() const { return height_; } double width() const { return width_; } double area() const override { return (height_ * width_)/2.0; } }; class Circle : public Shape { double radius_; public: Circle(double radius) : radius_(radius) { } const std::string& type() const { static const std::string type_ = "circle"; return type_; } double radius() const { return radius_; } double area() const override { constexpr double pi = 3.14159265358979323846; return pi*radius_*radius_; } }; } // ns JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Rectangle, (type,"type",JSONCONS_RDONLY,[](const std::string& type) noexcept{return type == "rectangle";}), (height, "height"), (width, "width") ) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Triangle, (type,"type", JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "triangle";}), (height, "height"), (width, "width") ) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Circle, (type,"type", JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "circle";}), (radius, "radius") ) JSONCONS_POLYMORPHIC_TRAITS(ns::Shape,ns::Rectangle,ns::Triangle,ns::Circle) int main() { std::string input = R"( [ {"type" : "rectangle", "width" : 2.0, "height" : 1.5 }, {"type" : "triangle", "width" : 4.0, "height" : 2.0 }, {"type" : "circle", "radius" : 1.0 } ] )"; auto shapes = jsoncons::decode_json>>(input); std::cout << "(1)\n"; for (const auto& shape : shapes) { std::cout << typeid(*shape.get()).name() << " area: " << shape->area() << "\n"; } std::string output; jsoncons::encode_json(shapes, output, indenting::indent); std::cout << "\n(2)\n" << output << "\n"; } ``` Output: ``` (1) class `ns::Rectangle area: 3.0000000 class `ns::Triangle area: 4.0000000 class `ns::Circle area: 3.1415927 (2) [ { "height": 1.5, "type": "rectangle", "width": 2.0 }, { "height": 2.0, "type": "triangle", "width": 4.0 }, { "radius": 1.0, "type": "circle" } ] ``` This example maps a `type()` getter to a "type" data member in the JSON. However, we can also achieve this without using a `type()` getter at all. Compare with the very similar example [decode to a std::variant based on a type marker](#A9)
#### An example with std::variant This example assumes C++17 language support and jsoncons v0.154.0 or later. ```cpp #include namespace ns { enum class Color {yellow, red, green, blue}; inline std::ostream& operator<<(std::ostream& os, Color val) { switch (val) { case Color::yellow: os << "yellow"; break; case Color::red: os << "red"; break; case Color::green: os << "green"; break; case Color::blue: os << "blue"; break; } return os; } class Fruit { private: JSONCONS_TYPE_TRAITS_FRIEND std::string name_; Color color_; public: friend std::ostream& operator<<(std::ostream& os, const Fruit& val) { os << "name: " << val.name_ << ", color: " << val.color_ << "\n"; return os; } }; class Fabric { private: JSONCONS_TYPE_TRAITS_FRIEND int size_; std::string material_; public: friend std::ostream& operator<<(std::ostream& os, const Fabric& val) { os << "size: " << val.size_ << ", material: " << val.material_ << "\n"; return os; } }; class Basket { private: JSONCONS_TYPE_TRAITS_FRIEND std::string owner_; std::vector> items_; public: std::string owner() const { return owner_; } std::vector> items() const { return items_; } }; } // ns } // namespace JSONCONS_ENUM_NAME_TRAITS(ns::Color, (yellow, "YELLOW"), (red, "RED"), (green, "GREEN"), (blue, "BLUE")) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::Fruit, (name_, "name"), (color_, "color")) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::Fabric, (size_, "size"), (material_, "material")) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::Basket, (owner_, "owner"), (items_, "items")) int main() { std::string input = R"( { "owner": "Rodrigo", "items": [ { "name": "banana", "color": "YELLOW" }, { "size": 40, "material": "wool" }, { "name": "apple", "color": "RED" }, { "size": 40, "material": "cotton" } ] } )"; ns::Basket basket = jsoncons::decode_json(input); std::cout << basket.owner() << "\n\n"; std::cout << "(1)\n"; for (const auto& var : basket.items()) { std::visit([](auto&& arg) { using T = std::decay_t; if constexpr (std::is_same_v) std::cout << "Fruit " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "Fabric " << arg << '\n'; }, var); } std::string output; jsoncons::encode_json(basket, output, indenting::indent); std::cout << "(2)\n" << output << "\n\n"; } ``` Output: ``` Rodrigo (1) Fruit name: banana, color: yellow Fabric size: 28, material: wool Fruit name: apple, color: red Fabric size: 28, material: cotton (2) { "items": [ { "color": "YELLOW", "name": "banana" }, { "material": "wool", "size": 40 }, { "color": "RED", "name": "apple" }, { "material": "cotton", "size": 40 } ], "owner": "Rodrigo" } ```
#### Type selection and std::variant For classes supported through the convenience macros, e.g. `Fruit` and `Fabric` from the previous example, the type selection strategy is the same as for polymorphic types, and is based on the presence of mandatory members in the classes. More generally, the type selection strategy is based on the `json_type_traits::is(const Json& j)` function, checking each type in the variant from left to right, and stopping when `json_type_traits::is(j)` returns `true`. Now consider ```cpp #include namespace ns { enum class Color {yellow, red, green, blue}; } // ns JSONCONS_ENUM_NAME_TRAITS(ns::Color, (yellow, "YELLOW"), (red, "RED"), (green, "GREEN"), (blue, "BLUE")) int main() { using variant_type = std::variant; std::vector vars = {100, 10.1, false, std::string("Hello World"), ns::Color::yellow}; std::string buffer; jsoncons::encode_json(vars, buffer, indenting::indent); std::cout << "(1)\n" << buffer << "\n\n"; auto vars2 = jsoncons::decode_json>(buffer); auto visitor = [](auto&& arg) { using T = std::decay_t; if constexpr (std::is_same_v) std::cout << "int " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "double " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "bool " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "std::string " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "ns::Color " << arg << '\n'; }; std::cout << "(2)\n"; for (const auto& item : vars2) { std::visit(visitor, item); } std::cout << "\n"; } ``` Output: ``` (1) [ 100, 10.1, false, "Hello World", "YELLOW" ] (2) int 100 double 10.1 bool false std::string Hello World std::string YELLOW ``` Encode is fine. But when decoding, jsoncons checks if the JSON string "YELLOW" is a `std::string` before it checks whether it is an `ns::Color`, and since the answer is yes, it is stored in the variant as a `std::string`. But if we switch the order of `ns::Color` and `std::string` in the variant definition, viz. ```cpp using variant_type = std::variant; ``` strings containing the text "YELLOW", "RED", "GREEN", or "BLUE" are detected to be `ns::Color`, and the others `std::string`. And the output becomes ``` (1) [ 100, 10.1, false, "Hello World", "YELLOW" ] (2) int 100 double 10.1 bool false std::string Hello World ns::Color yellow ``` So: types that are more constrained should appear to the left of types that are less constrained.
#### Decode to a std::variant based on a type marker (since 0.158.0) This example is very similar to [decode to a polymorphic type based on a type marker](#A6), and in fact the json traits defined for that example would do for `std::variant` as well. But here we add a wrinkle by omitting the `type()` function in the `Rectangle`, `Triangle` and `Circle` classes. More generally, we show how to augment the JSON output with name/value pairs that are not present in the class definitions, and to perform type selection with them. ```cpp #include namespace ns { class Rectangle { double height_; double width_; public: Rectangle(double height, double width) : height_(height), width_(width) { } double height() const { return height_; } double width() const { return width_; } double area() const { return height_ * width_; } }; class Triangle { double height_; double width_; public: Triangle(double height, double width) : height_(height), width_(width) { } double height() const { return height_; } double width() const { return width_; } double area() const { return (height_ * width_)/2.0; } }; class Circle { double radius_; public: Circle(double radius) : radius_(radius) { } double radius() const { return radius_; } double area() const { constexpr double pi = 3.14159265358979323846; return pi*radius_*radius_; } }; inline constexpr auto rectangle_marker = [](double) noexcept {return "rectangle"; }; inline constexpr auto triangle_marker = [](double) noexcept {return "triangle";}; inline constexpr auto circle_marker = [](double) noexcept {return "circle";}; } // namespace ns JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Rectangle, (height,"type",JSONCONS_RDONLY, [](const std::string& type) noexcept{return type == "rectangle";}, ns::rectangle_marker), (height, "height"), (width, "width") ) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Triangle, (height,"type", JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "triangle";}, ns::triangle_marker), (height, "height"), (width, "width") ) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Circle, (radius,"type", JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "circle";}, ns::circle_marker), (radius, "radius") ) int main() { using shapes_t = std::variant; std::string input = R"( [ {"type" : "rectangle", "width" : 2.0, "height" : 1.5 }, {"type" : "triangle", "width" : 4.0, "height" : 2.0 }, {"type" : "circle", "radius" : 1.0 } ] )"; auto shapes = jsoncons::decode_json>(input); auto visitor = [](auto&& shape) { using T = std::decay_t; if constexpr (std::is_same_v) std::cout << "rectangle area: " << shape.area() << '\n'; else if constexpr (std::is_same_v) std::cout << "triangle area: " << shape.area() << '\n'; else if constexpr (std::is_same_v) std::cout << "circle area: " << shape.area() << '\n'; }; std::cout << "(1)\n"; for (const auto& shape : shapes) { std::visit(visitor, shape); } std::string output; jsoncons::encode_json(shapes, output, indenting::indent); std::cout << "\n(2)\n" << output << "\n"; } ``` Output: ``` (1) rectangle area: 3.0000000 triangle area: 4.0000000 circle area: 3.1415927 (2) [ { "height": 1.5, "type": "rectangle", "width": 2.0 }, { "height": 2.0, "type": "triangle", "width": 4.0 }, { "radius": 1.0, "type": "circle" } ] ``` Note the mapping to the "type" member, in particular, for the rectangle, ```cpp (height,"type",JSONCONS_RDONLY, [](const std::string& type) noexcept{return type == "rectangle";}, ns::rectangle_marker), ``` There are two things to observe. First, the class member being mapped, here `height`, can be any member, we don't actually use it. Instead, we use the function object `ns::rectangle_marker` to ouput the value "rectangle" with the key "type". Second, the function argument in this position cannot be a lambda expression (at least until C++20), because jsoncons uses it in an unevaluated context, so it is provided as a variable containing a lambda expression instead.
#### Transform data member (since 0.158.0) ```cpp #include #include namespace ns { class Employee { std::string name_; std::string surname_; public: Employee() = default; Employee(const std::string& name, const std::string& surname) : name_(name), surname_(surname) { } std::string getName() const { return name_; } void setName(const std::string& name) { name_ = name; } std::string getSurname()const { return surname_; } void setSurname(const std::string& surname) { surname_ = surname; } friend bool operator<(const Employee& lhs, const Employee& rhs) { if (lhs.surname_ < rhs.surname_) return true; return lhs.name_ < rhs.name_; } }; class Company { std::string name_; std::vector employeeIds_; public: std::string getName() const { return name_; } void setName(const std::string& name) { name_ = name; } const std::vector getIds() const { return employeeIds_; } void setIds(const std::vector& employeeIds) { employeeIds_ = employeeIds; } }; std::vector fromEmployeesToIds(const std::vector& employees) { static std::map employee_id_map = {{Employee("John", "Smith"), 1},{Employee("Jane", "Doe"), 2}}; std::vector ids; for (auto employee : employees) { ids.push_back(employee_id_map.at(employee)); } return ids; } std::vector toEmployeesFromIds(const std::vector& ids) { static std::map id_employee_map = {{1, Employee("John", "Smith")},{2, Employee("Jane", "Doe")}}; std::vector employees; for (auto id : ids) { employees.push_back(id_employee_map.at(id)); } return employees; } } // namespace ns JSONCONS_ALL_GETTER_SETTER_NAME_TRAITS(ns::Employee, (getName, setName, "employee_name"), (getSurname, setSurname, "employee_surname") ) JSONCONS_ALL_GETTER_SETTER_NAME_TRAITS(ns::Company, (getName, setName, "company"), (getIds, setIds, "resources", JSONCONS_RDWR, jsoncons::always_true(), ns::toEmployeesFromIds, ns::fromEmployeesToIds) ) int main() { std::string input = R"( { "company": "ExampleInc", "resources": [ { "employee_name": "John", "employee_surname": "Smith" }, { "employee_name": "Jane", "employee_surname": "Doe" } ] } )"; auto company = decode_json(input); std::cout << "(1)\n" << company.getName() << "\n"; for (auto id : company.getIds()) { std::cout << id << "\n"; } std::cout << "\n"; std::string output; encode_json(company, output, indenting::indent); std::cout << "(2)\n" << output << "\n\n"; } ``` Output: ``` (1) ExampleInc 1 2 (2) { "company": "ExampleInc", "resources": [ { "employee_name": "John", "employee_surname": "Smith" }, { "employee_name": "Jane", "employee_surname": "Doe" } ] } ```
#### Tidy data member (since 0.158.0) ```cpp #include namespace ns { class Person { std::string name_; std::optional socialSecurityNumber_; public: Person(const std::string& name, const std::optional& socialSecurityNumber) : name_(name), socialSecurityNumber_(socialSecurityNumber) { } std::string getName() const { return name_; } std::optional getSsn() const { return socialSecurityNumber_; } }; } // namespace ns JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Person, (getName, "name"), (getSsn, "social_security_number", jsoncons::always_true(), jsoncons::identity(), // or std::identity() if C++20 [] (const std::optional& unvalidated) { if (!unvalidated) { return unvalidated; } std::regex myRegex(("^(\\d{9})$")); if (!std::regex_match(*unvalidated, myRegex) ) { return std::optional(); } return unvalidated; } ) ) int main() { std::string input = R"( [ { "name": "John Smith", "social_security_number": "123456789" }, { "name": "Jane Doe", "social_security_number": "12345678" } ] )"; auto persons = jsoncons::decode_json>(input); std::cout << "(1)\n"; for (const auto& person : persons) { std::cout << person.getName() << ", " << (person.getSsn() ? *person.getSsn() : "n/a") << "\n"; } std::cout << "\n"; std::string output; jsoncons::encode_json(persons, output, indenting::indent); std::cout << "(2)\n" << output << "\n"; } ``` Output: ``` (1) John Smith, 123456789 Jane Doe, n/a (2) [ { "name": "John Smith", "social_security_number": "123456789" }, { "name": "Jane Doe", "social_security_number": null } ] ``` jsoncons-1.3.2/doc/ref/corelib/json_type_traits/custom-specializations.md000066400000000000000000000240021477700171100267470ustar00rootroot00000000000000### Custom Specializations If you try to specialize `json_type_traits` for a type that is already specialized in the jsoncons library, for example, a custom container type that satisfies the conditions for a sequence container, you may see a compile error "more than one partial specialization matches the template argument list". For these situations `jsoncons` provides the traits class ```cpp template struct is_json_type_traits_declared : public std::false_type {}; ``` which inherits from [std::false_type](http://www.cplusplus.com/reference/type_traits/false_type/). This traits class may be specialized for a user-defined type with member constant `value` equal `true` to inform the `jsoncons` library that the type is already specialized. ### Examples [Extend json_type_traits to support `boost::gregorian` dates.](#A1) [Specialize json_type_traits to support a book class.](#A2) [Specialize json_type_traits for a container type that the jsoncons library also supports](#A3) [Convert JSON to/from boost matrix](#A4)
#### Extend json_type_traits to support `boost::gregorian` dates. ```cpp #include #include "boost/datetime/gregorian/gregorian.hpp" namespace jsoncons { template struct json_type_traits { static bool is(const Json& val) noexcept { if (!val.is_string()) { return false; } std::string s = val.template as(); try { boost::gregorian::from_simple_string(s); return true; } catch (...) { return false; } } static boost::gregorian::date as(const Json& val) { std::string s = val.template as(); return boost::gregorian::from_simple_string(s); } static Json to_json(boost::gregorian::date val) { return Json(to_iso_extended_string(val)); } }; } ``` ```cpp namespace ns { using jsoncons::json; using boost::gregorian::date; json deal = json::parse(R"( { "Maturity":"2014-10-14", "ObservationDates": ["2014-02-14","2014-02-21"] } )"); deal["ObservationDates"].push_back(date(2014,2,28)); date maturity = deal["Maturity"].as(); std::cout << "Maturity: " << maturity << '\n' << '\n'; std::cout << "Observation dates: " << '\n' << '\n'; for (auto observation_date: deal["ObservationDates"].array_range()) { std::cout << observation_date << '\n'; } std::cout << '\n'; } ``` Output: ``` Maturity: 2014-Oct-14 Observation dates: 2014-Feb-14 2014-Feb-21 2014-Feb-28 ```
#### Specialize json_type_traits to support a book class. ```cpp #include #include #include #include namespace ns { struct book { std::string author; std::string title; double price; }; } // namespace ns namespace jsoncons { template struct json_type_traits { using allocator_type = Json::allocator_type; static bool is(const Json& j) noexcept { return j.is_object() && j.contains("author") && j.contains("title") && j.contains("price"); } static ns::book as(const Json& j) { ns::book val; val.author = j.at("author").template as(); val.title = j.at("title").template as(); val.price = j.at("price").template as(); return val; } static Json to_json(const ns::book& val, allocator_type alloc=allocator_type()) { Json j(alloc); j.try_emplace("author", val.author); j.try_emplace("title", val.title); j.try_emplace("price", val.price); return j; } }; } // namespace jsoncons ``` To save typing and enhance readability, the jsoncons library defines macros, so you could also write ```cpp JSONCONS_ALL_MEMBER_TRAITS(ns::book, author, title, price) ``` which expands to the code above. ```cpp using namespace jsoncons; // for convenience int main() { const std::string s = R"( [ { "author" : "Haruki Murakami", "title" : "Kafka on the Shore", "price" : 25.17 }, { "author" : "Charles Bukowski", "title" : "Pulp", "price" : 22.48 } ] )"; std::vector book_list = decode_json>(s); std::cout << "(1)\n"; for (const auto& item : book_list) { std::cout << item.author << ", " << item.title << ", " << item.price << "\n"; } std::cout << "\n(2)\n"; encode_json(book_list, std::cout, indenting::indent); std::cout << "\n\n"; } ``` Output: ``` (1) Haruki Murakami, Kafka on the Shore, 25.17 Charles Bukowski, Pulp, 22.48 (2) [ { "author": "Haruki Murakami", "price": 25.17, "title": "Kafka on the Shore" }, { "author": "Charles Bukowski", "price": 22.48, "title": "Pulp" } ] ```
#### Specialize json_type_traits for a container type that the jsoncons library also supports ```cpp #include #include #include #include //own vector will always be of an even length struct own_vector : std::vector { using std::vector::vector; }; namespace jsoncons { template struct json_type_traits { static bool is(const Json& j) noexcept { return j.is_object() && j.size() % 2 == 0; } static own_vector as(const Json& j) { own_vector v; for (auto& item : j.object_range()) { std::string s(item.key()); v.push_back(std::strtol(s.c_str(),nullptr,10)); v.push_back(item.value().template as()); } return v; } static Json to_json(const own_vector& val){ Json j; for(std::size_t i=0;i struct is_json_type_traits_declared : public std::true_type {}; } // namespace jsoncons using jsoncons::json; int main() { json j(json_object_arg, {{"1",2},{"3",4}}); assert(j.is()); auto v = j.as(); json j2 = v; std::cout << j2 << "\n"; } ``` Output: ``` {"1":2,"3":4} ```
#### Convert JSON to/from boost matrix ```cpp #include #include namespace jsoncons { template struct json_type_traits> { static bool is(const Json& val) noexcept { if (!val.is_array()) { return false; } if (val.size() > 0) { std::size_t n = val[0].size(); for (const auto& a: val.array_range()) { if (!(a.is_array() && a.size() == n)) { return false; } for (auto x: a.array_range()) { if (!x.template is()) { return false; } } } } return true; } static boost::numeric::ublas::matrix as(const Json& val) { if (val.is_array() && val.size() > 0) { std::size_t m = val.size(); std::size_t n = 0; for (const auto& a : val.array_range()) { if (a.size() > n) { n = a.size(); } } boost::numeric::ublas::matrix A(m,n,T()); for (std::size_t i = 0; i < m; ++i) { const auto& a = val[i]; for (std::size_t j = 0; j < a.size(); ++j) { A(i,j) = a[j].template as(); } } return A; } else { boost::numeric::ublas::matrix A; return A; } } static Json to_json(const boost::numeric::ublas::matrix& val) { Json a = Json::template make_array<2>(val.size1(), val.size2(), T()); for (std::size_t i = 0; i < val.size1(); ++i) { for (std::size_t j = 0; j < val.size1(); ++j) { a[i][j] = val(i,j); } } return a; } }; } // namespace jsoncons using namespace jsoncons; using boost::numeric::ublas::matrix; int main() { matrix A(2, 2); A(0, 0) = 1.1; A(0, 1) = 2.1; A(1, 0) = 3.1; A(1, 1) = 4.1; json a = A; std::cout << "(1) " << std::boolalpha << a.is>() << "\n\n"; std::cout << "(2) " << std::boolalpha << a.is>() << "\n\n"; std::cout << "(3) \n\n" << pretty_print(a) << "\n\n"; matrix B = a.as>(); std::cout << "(4) \n\n"; for (std::size_t i = 0; i < B.size1(); ++i) { for (std::size_t j = 0; j < B.size2(); ++j) { if (j > 0) { std::cout << ","; } std::cout << B(i, j); } std::cout << "\n"; } std::cout << "\n\n"; } ``` Output: ``` (1) true (2) false (3) [ [1.1,2.1], [3.1,4.1] ] (4) 1.1,2.1 3.1,4.1 ``` jsoncons-1.3.2/doc/ref/corelib/line_split_kind.md000066400000000000000000000002141477700171100220040ustar00rootroot00000000000000### jsoncons::line_split_kind ```cpp #include enum class line_split_kind{same_line,new_line,multi_line}; ``` jsoncons-1.3.2/doc/ref/corelib/ojson.md000066400000000000000000000042231477700171100177710ustar00rootroot00000000000000### jsoncons::ojson ```cpp #include typedef basic_json> ojson ``` The `ojson` class is an instantiation of the [basic_json](basic_json.md) class template that uses `char` as the character type. The original insertion order of an object's name/value pairs is preserved. `ojson` behaves similarly to [json](json.md), with these particularities: - `ojson`, like `json`, supports object member `insert_or_assign` methods that take an `object_iterator` as the first parameter. But while with `json` that parameter is just a hint that allows optimization, with `ojson` it is the actual location where to insert the member. - In `ojson`, the `insert_or_assign` members that just take a name and a value always insert the member at the end. ### Examples ```cpp ojson o = ojson::parse(R"( { "street_number" : "100", "street_name" : "Queen St W", "city" : "Toronto", "country" : "Canada" } )"); std::cout << pretty_print(o) << '\n'; ``` Output: ```json { "street_number": "100", "street_name": "Queen St W", "city": "Toronto", "country": "Canada" } ``` Insert "postal_code" at end ```cpp o.insert_or_assign("postal_code", "M5H 2N2"); std::cout << pretty_print(o) << '\n'; ``` Output: ```json { "street_number": "100", "street_name": "Queen St W", "city": "Toronto", "country": "Canada", "postal_code": "M5H 2N2" } ``` Insert "province" before "country" ```cpp auto it = o.find("country"); o.insert_or_assign(it,"province","Ontario"); std::cout << pretty_print(o) << '\n'; ``` Output: ```json { "street_number": "100", "street_name": "Queen St W", "city": "Toronto", "province": "Ontario", "country": "Canada", "postal_code": "M5H 2N2" } ``` ### See also [json](json.md) constructs a json value that sorts name-value members alphabetically [wjson](wjson.md) constructs a wide character json value that sorts name-value members alphabetically [wojson](wojson.md) constructs a wide character json value that preserves the original insertion order of an object's name/value pairs jsoncons-1.3.2/doc/ref/corelib/rename_object_key_filter.md000066400000000000000000000023251477700171100236540ustar00rootroot00000000000000### jsoncons::rename_object_key_filter ```cpp #include using rename_object_key_filter = basic_rename_object_key_filter; ``` The `rename_object_key_filter` class is an instantiation of the `basic_rename_object_key_filter` class template that uses `char` as the character type. Renames object member names. ![rename_object_key_filter](./diagrams/rename_object_key_filter.png) #### Constructors rename_object_key_filter(const std::string& name, const std::string& new_name, json_visitor& visitor) rename_object_key_filter(const std::string& name, const std::string& new_name, json_visitor& visitor) ### Examples #### Rename object member names ```cpp #include #include using namespace jsoncons; int main() { ojson j = ojson::parse(R"({"first":1,"second":2,"fourth":3})"); json_stream_encoder encoder(std::cout); rename_object_key_filter filter("fourth","third",encoder); j.dump(filter); } ``` Output: ```json {"first":1,"second":2,"third":3} ``` ### See also [basic_json_filter](basic_json_filter.md) jsoncons-1.3.2/doc/ref/corelib/semantic_tag.md000066400000000000000000000010601477700171100212730ustar00rootroot00000000000000### jsoncons::semantic_tag ```cpp #include enum class semantic_tag : uint8_t { none = 0, undefined, datetime, epoch_seconds, epoch_milli, epoch_nano, bigint, bigdec, float128, // since 0.165.0 bigfloat, base16, base64, base64url, uri, clamped, multi_dim_row_major, multi_dim_column_major, ext, id, // since 0.165.0 regex, // since 0.165.0 code // since 0.165.0 }; ``` jsoncons-1.3.2/doc/ref/corelib/ser_context.md000066400000000000000000000025761477700171100212070ustar00rootroot00000000000000### jsoncons::ser_context ```cpp #include class ser_context; ``` Provides contextual information for serializing and deserializing JSON and JSON-like data formats. This information may be used for error reporting. virtual size_t line() const; Returns the line number for the text being parsed. Line numbers (if available) start at 1. The default implementation returns 0. virtual size_t column() const; Returns the column number to the end of the text being parsed. Column numbers (if available) start at 1. The default implementation returns 0. virtual size_t begin_position() const; (since 1.3.1) `position()` is defined for all JSON elements reported to the visitor, and indicates the position of the character at the beginning of the element, e.g. '"' for a string or the first digit for a positive number. Currently only supported for the JSON parser. virtual size_t position() const; Currently returns the same value as `begin_position()`. Since 1.3.1, prefer `begin_position()`. virtual size_t end_position() const; `end_position()` is defined for all JSON elements reported to the visitor, and indicates the position after the character at the end of the element, e.g. one past the closing '"' for a string or the one past the last digit for a number. Currently only supported for the JSON parser. jsoncons-1.3.2/doc/ref/corelib/ser_error.md000066400000000000000000000031751477700171100206500ustar00rootroot00000000000000### jsoncons::ser_error ```cpp #include ```
`jsoncons::ser_error` defines an exception type for reporting serialization and deserialization failures. ![ser_error](./diagrams/ser_error.png) std::exception #### Constructors ser_error(std::error_code ec); ser_error(std::error_code ec, std::size_t position); ser_error(std::error_code ec, std::size_t line, std::size_t column); ser_error(const ser_error& other); #### Member functions std::size_t line() const noexcept Returns the line number to the end of the text where the exception occurred. Line numbers start at 1. std::size_t column() const noexcept Returns the column number to the end of the text where the exception occurred. Column numbers start at 1. const char* what() const noexcept Constructs an error message, including line and column position #### Inherited from std::system_error const std::error_code code() const noexcept Returns an error code for this exception ### Example ```cpp #include using jsoncons::json; int main() { string s = "[1,2,3,4,]"; try { jsoncons::json j = jsoncons::json::parse(s); } catch(const jsoncons::ser_error& e) { std::cout << "Caught ser_error with category " << e.code().category().name() << ", code " << e.code().value() << " and message " << e.what() << '\n'; } } ``` Output: ``` Caught ser_error with category json_input, code 1 and message Unexpected value separator ',' at line 1 and column 10 ``` jsoncons-1.3.2/doc/ref/corelib/spaces_option.md000066400000000000000000000002411477700171100215030ustar00rootroot00000000000000### jsoncons::spaces_option ```cpp enum class spaces_option : uint8_t { no_spaces=0, space_after, space_before, space_before_and_after }; ``` jsoncons-1.3.2/doc/ref/corelib/staj_array_iterator.md000066400000000000000000000074451477700171100227220ustar00rootroot00000000000000### jsoncons::staj_array_iterator ```cpp #include template< typename T, typename Json > class staj_array_iterator ``` A `staj_array_iterator` is an [InputIterator](https://en.cppreference.com/w/cpp/named_req/InputIterator) that accesses the individual stream events from a [staj_cursor](staj_cursor.md) and, provided that when it is constructed the current stream event has type `staj_event_type::begin_array`, it retrieves the elements of the JSON array as items of type `T`. If when it is constructed the current stream event does not have type `staj_event_type::begin_array`, it becomes equal to the default-constructed iterator. #### Member types Member type |Definition ------------------------------------|------------------------------ `char_type`|Json::char_type `value_type`|`T` `difference_type`|`std::ptrdiff_t` `pointer`|`value_type*` `reference`|`value_type&` `iterator_category`|[std::input_iterator_tag](https://en.cppreference.com/w/cpp/iterator/iterator_tags) #### Constructors staj_array_iterator() noexcept; (1) staj_array_iterator(staj_array_view& view); (2) staj_array_iterator(staj_array_view& view, std::error_code& ec); (3) (1) Constructs the end iterator (2) Constructs a `staj_array_iterator` that refers to the first element of the array following the current stream event `begin_array`. If there is no such element, returns the end iterator. If a parsing error is encountered, throws a [ser_error](ser_error.md). (3) Constructs a `staj_array_iterator` that refers to the first member of the array following the current stream event `begin_array`. If there is no such element, returns the end iterator. If a parsing error is encountered, returns the end iterator and sets `ec`. #### Member functions const T& operator*() const const T* operator->() const staj_array_iterator& operator++() staj_array_iterator& increment(std::error_code& ec) staj_array_iterator operator++(int) Advances the iterator to the next array element. #### Non-member functions template bool operator==(const staj_array_iterator& a, const staj_array_iterator& b); template bool operator!=(const staj_array_iterator& a, const staj_array_iterator& b); ### Examples #### Iterate over a JSON array, returning json values ```cpp const std::string example = R"( [ { "employeeNo" : "101", "name" : "Tommy Cochrane", "title" : "Supervisor" }, { "employeeNo" : "102", "name" : "Bill Skeleton", "title" : "Line manager" } ] )"; int main() { std::istringstream is(example); json_stream_cursor cursor(is); auto view = staj_array(cursor); for (const auto& j : view) { std::cout << pretty_print(j) << "\n"; } std::cout << "\n\n"; } ``` Output: ``` { "employeeNo": "101", "name": "Tommy Cochrane", "title": "Supervisor" } { "employeeNo": "102", "name": "Bill Skeleton", "title": "Line manager" } ``` #### Iterate over the JSON array, returning employee values ```cpp namespace ns { struct employee { std::string employeeNo; std::string name; std::string title; }; } // namespace ns JSONCONS_ALL_MEMBER_TRAITS(ns::employee, employeeNo, name, title) int main() { std::istringstream is(example); json_stream_cursor cursor(is); auto view = staj_array(cursor); for (const auto& val : view) { std::cout << val.employeeNo << ", " << val.name << ", " << val.title << "\n"; } std::cout << "\n\n"; } ``` Output: ``` 101, Tommy Cochrane, Supervisor 102, Bill Skeleton, Line manager ``` jsoncons-1.3.2/doc/ref/corelib/staj_cursor.md000066400000000000000000000052541477700171100212040ustar00rootroot00000000000000### jsoncons::staj_cursor ```cpp #include typedef basic_staj_cursor staj_cursor ``` The `staj_cursor` interface supports forward, read-only, access to JSON and JSON-like data formats. The `staj_cursor` is designed to iterate over stream events until `done()` returns `true`. The `next()` function causes the reader to advance to the next stream event. The `current()` function returns the current stream event. The data can be accessed using the [staj_event](basic_staj_event.md) interface. When `next()` is called, copies of data previously accessed may be invalidated. #### Destructor virtual ~basic_staj_cursor() noexcept = default; #### Member functions virtual bool done() const = 0; Check if there are no more events. virtual const staj_event& current() const = 0; Returns the current [staj_event](basic_staj_event.md). virtual void read_to(json_visitor& visitor) = 0; Sends the parse events from the current event to the matching completion event to the supplied [visitor](basic_json_visitor.md) E.g., if the current event is `begin_object`, sends the `begin_object` event and all inbetween events until the matching `end_object` event. If a parsing error is encountered, throws a [ser_error](ser_error.md). virtual void read_to(json_visitor& visitor, std::error_code& ec) = 0; Sends the parse events from the current event to the matching completion event to the supplied [visitor](basic_json_visitor.md) E.g., if the current event is `begin_object`, sends the `begin_object` event and all inbetween events until the matching `end_object` event. If a parsing error is encountered, sets `ec`. virtual void next() = 0; Get the next event. If a parsing error is encountered, throws a [ser_error](ser_error.md). virtual void next(std::error_code& ec) = 0; Get the next event. If a parsing error is encountered, sets `ec`. virtual const ser_context& context() const = 0; Returns the current [context](ser_context.md) #### Non-member functions template ::value,T,basic_json>::type> staj_array_view staj_array(basic_staj_cursor& cursor); Create a view of the parse events as an array of items of type `T`. The current event type must be `staj_event_type::begin_array`. template ::value,T,basic_json>::type> staj_object_view staj_object(basic_staj_cursor& cursor); Create a view of the parse events as an object of key-value pairs. The current event type must be `staj_event_type::begin_object`. jsoncons-1.3.2/doc/ref/corelib/staj_event_type.md000066400000000000000000000005641477700171100220500ustar00rootroot00000000000000### jsoncons::staj_event_type ```cpp #include enum class staj_event_type { begin_array, end_array, begin_object, end_object, name, // until 0.150.0 key, // since 0.150.0 string_value, byte_string_value, null_value, bool_value, int64_value, uint64_value, half_value, double_value }; ``` jsoncons-1.3.2/doc/ref/corelib/staj_object_iterator.md000066400000000000000000000064371477700171100230520ustar00rootroot00000000000000### jsoncons::staj_object_iterator ```cpp #include template< typename Key, typename T, typename Json > class staj_object_iterator ``` A `staj_object_iterator` is an [InputIterator](https://en.cppreference.com/w/cpp/named_req/InputIterator) that accesses the individual stream events from a [staj_cursor](staj_cursor.md) and, provided that when it is constructed the current stream event has type `begin_object`, it returns the elements of the JSON object as items of type `std::pair`. If when it is constructed the current stream event does not have type `begin_object`, it becomes equal to the default-constructed iterator. #### Member types Member type |Definition ------------------------------------|------------------------------ `char_type`|`Json::char_type` `key_type`|`Key` `value_type`|`std::pair` `difference_type`|`std::ptrdiff_t` `pointer`|`value_type*` `reference`|`value_type&` `iterator_category`|[std::input_iterator_tag](https://en.cppreference.com/w/cpp/iterator/iterator_tags) #### Constructors staj_object_iterator() noexcept; (1) staj_object_iterator(staj_object_view& view); (2) staj_object_iterator(staj_object_view& view, std::error_code& ec); (3) (1) Constructs the end iterator (2) Constructs a `staj_object_iterator` that refers to the first member of the object following the current stream event `begin_object`. If there is no such member, returns the end iterator. If a parsing error is encountered, throws a [ser_error](ser_error.md). (3) Constructs a `staj_object_iterator` that refers to the first member of the object following the current stream event `begin_object`. If there is no such member, returns the end iterator. If a parsing error is encountered, returns the end iterator and sets `ec`. #### Member functions const key_value_type& operator*() const const key_value_type* operator->() const staj_object_iterator& operator++(); staj_object_iterator operator++(int); staj_object_iterator& increment(std::error_code& ec); Advances the iterator to the next object member. #### Non-member functions template bool operator==(const staj_object_iterator& a, const staj_object_iterator& b) template bool operator!=(const staj_object_iterator& a, const staj_object_iterator& b) ### Examples #### Iterate over a JSON object, returning key-json value pairs ```cpp const std::string example = R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum.array_example.com", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 } ] } )"; int main() { json_string_cursor cursor(example); auto view = staj_object(cursor); for (const auto& kv : view) { std::cout << kv.first << ":\n" << pretty_print(kv.second) << "\n"; } std::cout << "\n\n"; } ``` Output: ``` application: "hiking" reputons: [ { "assertion": "advanced", "rated": "Marilyn C", "rater": "HikingAsylum.array_example.com", "rating": 0.90 } ] ``` jsoncons-1.3.2/doc/ref/corelib/utility/000077500000000000000000000000001477700171100200215ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/corelib/utility/bigint.md000066400000000000000000000140041477700171100216160ustar00rootroot00000000000000### jsoncons::bigint ```cpp #include typedef basic_bigint> bigint; ``` The `bigint` class is an instantiation of the `basic_bigint` class template that uses `std::allocator` as the allocator type. An arbitrary-precision integer. #### Constructor bigint(); explicit bigint(const Allocator& alloc); explicit bigint(const char* str); Constructs a bigint from the decimal string representation of a bigint. explicit bigint(const char* data, std::size_t length); Constructs a bigint from the decimal string representation of a bigint. explicit bigint(const char* str, const Allocator& alloc); bigint(int signum, std::initializer_list magnitude); Constructs a bigint from the sign-magnitude representation. The magnitude is an unsigned integer `n` encoded as a byte string data item in big-endian byte-order. If the value of signum is 1, the value of the bigint is `n`. If the value of signum is -1, the value of the bigint is `-1 - n`. An empty list means a zero value. bigint(int signum, std::initializer_list magnitude, const Allocator& alloc); bigint(const bigint& s); bigint(bigint&& s); #### Assignment bigint& operator=(const bigint& s); bigint& operator=(bigint&& s); #### Accessors template void dump(std::basic_string& data) const template void dump(int& signum, std::vector& data) const #### Arithmetic operators explicit operator bool() const explicit operator int64_t() const explicit operator uint64_t() const explicit operator double() const explicit operator long double() const bigint operator-() const bigint& operator+=( const bigint& y ) bigint& operator-=( const bigint& y ) bigint& operator*=( int64_t y ) bigint& operator*=( uint64_t y ) bigint& operator*=( bigint y ) bigint& operator/=( const bigint& divisor ) bigint& operator%=( const bigint& divisor ) bigint& operator<<=( uint64_t k ) bigint& operator>>=(uint64_t k) bigint& operator++() bigint operator++(int) bigint& operator--() bigint operator--(int) bigint& operator|=( const bigint& a ) bigint& operator^=( const bigint& a ) bigint& operator&=( const bigint& a ) #### Non-member functions bool operator==(const bigint& lhs, const bigint& rhs); bool operator!=(const bigint& lhs, const bigint& rhs); template friend std::basic_ostream& operator<<(std::basic_ostream& os, const bigint& o); #### Global arithmetic operators bool operator==( const bigint& x, const bigint& y ) bool operator==( const bigint& x, int y ) bool operator!=( const bigint& x, const bigint& y ) bool operator!=( const bigint& x, int y ) bool operator<( const bigint& x, const bigint& y ) bool operator<( const bigint& x, int64_t y ) bool operator>( const bigint& x, const bigint& y ) bool operator>( const bigint& x, int y ) bool operator<=( const bigint& x, const bigint& y ) bool operator<=( const bigint& x, int y ) bool operator>=( const bigint& x, const bigint& y ) bool operator>=( const bigint& x, int y ) bigint operator+( bigint x, const bigint& y ) bigint operator+( bigint x, int64_t y ) bigint operator-( bigint x, const bigint& y ) bigint operator-( bigint x, int64_t y ) bigint operator*( int64_t x, const bigint& y ) bigint operator*( bigint x, const bigint& y ) bigint operator*( bigint x, int64_t y ) bigint operator/( bigint x, const bigint& y ) bigint operator/( bigint x, int y ) bigint operator%( bigint x, const bigint& y ) bigint operator<<( bigint u, unsigned k ) bigint operator<<( bigint u, int k ) bigint operator>>( bigint u, unsigned k ) bigint operator>>( bigint u, int k ) bigint operator|( bigint x, const bigint& y ) bigint operator|( bigint x, int y ) bigint operator|( bigint x, unsigned y ) bigint operator^( bigint x, const bigint& y ) bigint operator^( bigint x, int y ) bigint operator^( bigint x, unsigned y ) bigint operator&( bigint x, const bigint& y ) bigint operator&( bigint x, int y ) bigint operator&( bigint x, unsigned y ) bigint abs( const bigint& a ) bigint power( bigint x, unsigned n ) bigint sqrt( const bigint& a ) ### Examples ### Examples #### Initializing with bigint ```cpp #include using namespace jsoncons; int main() { std::string s = "-18446744073709551617"; json j(bigint(s.c_str())); std::cout << "(1) " << j.as() << "\n\n"; std::cout << "(2) " << j.as() << "\n\n"; std::cout << "(3) "; j.dump(std::cout); std::cout << "\n\n"; std::cout << "(4) "; auto options1 = json_options{} .bigint_format(bignum_format_kind::raw); j.dump(std::cout, options1); std::cout << "\n\n"; std::cout << "(5) "; auto options2 = json_options{} .bigint_format(bignum_format_kind::base64url); j.dump(std::cout, options2); std::cout << "\n\n"; } ``` Output: ``` (1) -18446744073709551617 (2) -18446744073709551617 (3) "-18446744073709551617" (4) -18446744073709551617 (5) "~AQAAAAAAAAAB" ``` #### Integer overflow during parsing ```cpp #include using namespace jsoncons; int main() { std::string s = "-18446744073709551617"; json j = json::parse(s); std::cout << "(1) "; j.dump(std::cout); std::cout << "\n\n"; std::cout << "(2) "; auto options1 = json_options{} .bigint_format(bignum_format_kind::raw); j.dump(std::cout, options1); std::cout << "\n\n"; std::cout << "(3) "; auto options2 = json_options{} .bigint_format(bignum_format_kind::base64url); j.dump(std::cout, options2); std::cout << "\n\n"; } ``` Output: ``` (1) -18446744073709551617 (2) -18446744073709551617 (3) "~AQAAAAAAAAAB" ``` jsoncons-1.3.2/doc/ref/corelib/utility/uri.md000066400000000000000000000136561477700171100211550ustar00rootroot00000000000000### jsoncons::uri ```cpp #include ``` The class `uri` represents a Uniform Resource Identifier (URI) reference. #### Constructor uri(); explicit uri(jsoncons::string_view str); Constructs a `uri` by parsing the given string. uri(jsoncons::string_view scheme, jsoncons::string_view userinfo, jsoncons::string_view host, jsoncons::string_view port, jsoncons::string_view path, jsoncons::string_view query = "", jsoncons::string_view fragment = "") Constructs a `uri` from the given parts. It is assumed that the parts are not already %-encoded, encoding is performed during construction. uri(const uri& other, uri_fragment_part_t, jsoncons::string_view fragment); Constructs a `uri` from `other`, replacing it's fragment part with `fragment`. It is assumed that `fragment` is not already %-encoded, encoding is performed during construction. uri(const uri& other); Copy constructor. uri(uri&& other) noexcept; Move constructor. #### Assignment uri& operator=(const uri& other); Copy assignment. uri& operator=(uri&& other) noexcept; Move assignment. #### Member functions jsoncons::string_view scheme() const noexcept; Returns the scheme part of this URI. The scheme is the first part of the URI, before the `:` character. std::string userinfo() const; Returns the decoded userinfo part of this URI. jsoncons::string_view encoded_userinfo() const noexcept; Returns the encoded userinfo part of this URI. jsoncons::string_view host() const noexcept; Returns the host part of this URI. jsoncons::string_view port() const noexcept; Returns the port number of this URI. std::string authority() const; Returns the decoded authority part of this URI. jsoncons::string_view encoded_authority() const noexcept; Returns the encoded authority part of this URI. std::string path() const; Returns the decoded path part of this URI. jsoncons::string_view encoded_path() const noexcept; Returns the encoded path part of this URI. std::string query() const; Returns the decoded query part of this URI. jsoncons::string_view encoded_query() const noexcept; Returns the encoded query part of this URI. std::string fragment() const; Returns the decoded fragment part of this URI. jsoncons::string_view encoded_fragment() const noexcept; Returns the encoded fragment part of this URI. bool is_absolute() const noexcept; Returns true if this URI is absolute, false if it is relative. An absolute URI has a scheme part. bool is_opaque() const noexcept; Returns true if this URI is opaque, otherwise false. An opaque URI is an absolute URI whose scheme-specific part does not begin with a slash character ('/'). uri base() const noexcept; Returns the base uri. The base uri includes the scheme, userinfo, host, port, and path parts, but not the query or fragment. bool has_scheme() const noexcept; Returns true if this URI has a scheme part, otherwise false. bool has_userinfo() const noexcept; Returns true if this URI has a userinfo part, otherwise false. bool has_authority() const noexcept; Returns true if this URI has an authority part, otherwise false. bool has_host() const noexcept; Returns true if this URI has a host part, otherwise false. bool has_port() const noexcept; Returns true if this URI has a port number, otherwise false. bool has_path() const noexcept; Returns true if this URI has a path part, otherwise false. bool has_query() const noexcept; Returns true if this URI has a query part, otherwise false. bool has_fragment() const noexcept; Returns true if this URI has a fragment part, otherwise false. uri resolve(jsoncons::string_view reference) const; Resolve `reference` as a URI relative to this URI. uri resolve(const uri& reference) const; Resolve `reference` as a URI relative to this URI. const std::string& string() const noexcept; Returns a URI string. static uri parse(jsoncons::string_view str, std::error_code& ec); Creates a `uri` by parsing the given string. If a parse error is encountered, returns a default constructed `uri` and sets `ec`. friend std::ostream& operator<<(std::ostream& os, const uri& uri_); ### Examples #### Parts ```cpp #include int main() { jsoncons::uri uri{ "https://github.com/danielaparker/jsoncons/tree/master/doc/ref/corelib/utility/uri.md#Examples" }; std::cout << "uri: " << uri << "\n"; std::cout << "base: " << uri.base() << "\n"; std::cout << "scheme: " << uri.scheme() << "\n"; std::cout << "authority: " << uri.authority() << "\n"; std::cout << "userinfo: " << uri.userinfo() << "\n"; std::cout << "path: " << uri.path() << "\n"; std::cout << "query: " << uri.query() << "\n"; std::cout << "fragment: " << uri.fragment() << "\n"; } ``` Output: ``` uri: https://github.com/danielaparker/jsoncons/tree/master/doc/ref/corelib/utility/uri.md#Examples base: https://github.com/danielaparker/jsoncons/tree/master/doc/ref/corelib/utility/uri.md scheme: https authority: github.com userinfo: path: /danielaparker/jsoncons/tree/master/doc/ref/corelib/utility/uri.md query: fragment: Examples ``` #### Resolve reference relative to a base URI ```cpp #include int main() { jsoncons::uri uri{ "https://github.com/danielaparker/jsoncons/" }; auto uri1 = uri.resolve("tree/master/doc/ref/corelib/utility/uri.md#Examples"); std::cout << "(1) " << uri1 << "\n"; auto uri2 = uri1.resolve("../../../../../../blob/master/include/jsoncons/utility/uri.hpp"); std::cout << "(2) " << uri2 << "\n"; auto uri3 = uri2.resolve("file:///~calendar"); std::cout << "(3) " << uri3 << "\n"; } ``` Output: ``` (1) https://github.com/danielaparker/jsoncons/tree/master/doc/ref/corelib/utility/uri.md#Examples (2) https://github.com/danielaparker/jsoncons/blob/master/include/jsoncons/utility/uri.hpp (3) file:///~calendar ``` jsoncons-1.3.2/doc/ref/corelib/wjson.md000066400000000000000000000016121477700171100200000ustar00rootroot00000000000000### jsoncons::wjson ```cpp #include typedef basic_json> wjson ``` The `wjson` class is an instantiation of the [basic_json](basic_json.md) class template that uses `wchar_t` as the character type. The order of an object's name/value pairs is not preserved, they are sorted alphabetically by name. If you want to preserve the original insertion order, use [wojson](wojson.md) instead. ### See also [wojson](wojson.md) constructs a wide character json value that preserves the original insertion order of an object's name/value pairs [json](json.md) constructs a utf8 character json value that sorts name-value members alphabetically [ojson](ojson.md) constructs a utf8 character json value that preserves the original insertion order of an object's name/value pairs jsoncons-1.3.2/doc/ref/corelib/wojson.md000066400000000000000000000023411477700171100201570ustar00rootroot00000000000000### jsoncons::wojson ```cpp #include typedef basic_json> wojson ``` The `wojson` class is an instantiation of the [basic_json](basic_json.md) class template that uses `wchar_t` as the character type. The original insertion order of an object's name/value pairs is preserved. `wojson` behaves similarly to [wjson](wjson.md), with these particularities: - `wojson`, like `wjson`, supports object member `insert_or_assign` methods that take an `object_iterator` as the first parameter. But while with `wjson` that parameter is just a hint that allows optimization, with `wojson` it is the actual location where to insert the member. - In `wojson`, the `insert_or_assign` members that just take a name and a value always insert the member at the end. ### See also [wjson](wjson.md) constructs a wide character json value that sorts name-value members alphabetically [json](json.md) constructs a utf8 character json value that sorts name-value members alphabetically [ojson](ojson.md) constructs a utf8 character json value that preserves the original insertion order of an object's name/value pairs jsoncons-1.3.2/doc/ref/csv/000077500000000000000000000000001477700171100154725ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/csv/basic_csv_cursor.md000066400000000000000000000126341477700171100213530ustar00rootroot00000000000000### jsoncons::csv::basic_csv_cursor ```cpp #include template< typename CharT, typename Source=jsoncons::stream_source, typename Allocator=std::allocator> basic_csv_cursor; ``` A pull parser for reporting CSV parse events. A typical application will repeatedly process the `current()` event and call the `next()` function to advance to the next event, until `done()` returns `true`. In addition, when positioned on a `begin_object` event, the `read_to` function can pull a complete object representing the events from `begin_object` to `end_object`, and when positioned on a `begin_array` event, a complete array representing the events from `begin_array` ro `end_array`. `basic_csv_cursor` is noncopyable and nonmoveable. Aliases for common character types are provided: Type |Definition --------------------|------------------------------ `csv_stream_cursor` (since 0.167.0) |`basic_csv_cursor>` `csv_string_cursor` (since 0.167.0) |`basic_csv_cursor>` `wcsv_stream_cursor` (since 0.167.0) |`basic_csv_cursor>` `wcsv_string_cursor` (since 0.167.0) |`basic_csv_cursor>` `csv_cursor` (until 0.167.0) |`basic_csv_cursor` `wcsv_cursor` (until 0.167.0) |`basic_csv_cursor` ### Implemented interfaces [basic_staj_cursor](../staj_cursor.md) #### Constructors template basic_csv_cursor(Sourceable&& source, const basic_csv_decode_options& options = basic_csv_decode_options(), (1) std::function err_handler = default_csv_parsing(), const Allocator& alloc = Allocator()); template basic_csv_cursor(Sourceable&& source, std::error_code& ec); (2) template basic_csv_cursor(Sourceable&& source, const basic_csv_decode_options& options, (3) std::error_code& ec); template basic_csv_cursor(Sourceable&& source, const basic_csv_decode_options& options, (4) std::function err_handler, std::error_code& ec); template basic_csv_cursor(std::allocator_arg_t, const Allocator& alloc, Sourceable&& source, const basic_csv_decode_options& options, (5) std::function err_handler, std::error_code& ec); Constructors (1) reads from a character sequence or stream and throws a [ser_error](../ser_error.md) if a parsing error is encountered while processing the initial event. Constructors (2)-(5) read from a character sequence or stream and set `ec` if a parsing error is encountered while processing the initial event. Note: It is the programmer's responsibility to ensure that `basic_csv_cursor` does not outlive the source passed in the constuctor, as `basic_csv_cursor` holds pointers to but does not own this resource. #### Parameters `source` - a value from which a `jsoncons::basic_string_view` is constructible, or a value from which a `source_type` is constructible. In the case that a `jsoncons::basic_string_view` is constructible from `source`, `source` is dispatched immediately to the parser. Otherwise, the `csv_cursor` reads from a `source_type` in chunks. #### Member functions bool done() const override; Checks if there are no more events. const basic_staj_event& current() const override; Returns the current [basic_staj_event](../staj_event.md). void read_to(json_visitor& visitor) override Feeds the current and succeeding [staj events](basic_staj_event.md) through the provided [visitor](basic_json_visitor.md), until the visitor indicates to stop. If a parsing error is encountered, throws a [ser_error](../ser_error.md). void read_to(basic_json_visitor& visitor, std::error_code& ec) override Feeds the current and succeeding [staj events](basic_staj_event.md) through the provided [visitor](basic_json_visitor.md), until the visitor indicates to stop. If a parsing error is encountered, sets `ec`. void next() override; Advances to the next event. If a parsing error is encountered, throws a [ser_error](../ser_error.md). void next(std::error_code& ec) override; Advances to the next event. If a parsing error is encountered, sets `ec`. const ser_context& context() const override; Returns the current [context](../ser_context.md) void reset(); Reset cursor to read another value from the same source template reset(Sourceable&& source) Reset cursor to read new value from a new sources #### Non-member functions template basic_staj_filter_view operator|(basic_csv_cursor& cursor, std::function&, const ser_context&)> pred); ### Examples ### See also [basic_staj_event](../basic_staj_event.md) [staj_array_iterator](../staj_array_iterator.md) [staj_object_iterator](../staj_object_iterator.md) jsoncons-1.3.2/doc/ref/csv/basic_csv_encoder.md000066400000000000000000000370721477700171100214600ustar00rootroot00000000000000### jsoncons::csv::basic_csv_encoder ```cpp #include template< typename CharT, typename Sink, typename Allocator=std::allocator=std::allocator> > class basic_csv_encoder : public jsoncons::basic_json_visitor ``` `basic_csv_encoder` and `basic_compact_json_encoder` are noncopyable and nonmoveable. ![basic_csv_encoder](./diagrams/basic_csv_encoder.png) Four specializations for common character types and result types are defined: Type |Definition ---------------------------|------------------------------ csv_stream_encoder |basic_csv_encoder> csv_string_encoder |basic_csv_encoder> wcsv_stream_encoder |basic_csv_encoder> wcsv_string_encoder |basic_csv_encoder> #### Member types Type |Definition ---------------------------|------------------------------ char_type |CharT sink_type |Sink string_view_type | #### Constructors explicit basic_csv_encoder(Sink&& sink) Constructs a new csv encoder that is associated with the destination `sink`. basic_csv_encoder(Sink&& sink, const basic_csv_options& options) Constructs a new csv encoder that is associated with the destination `sink` and uses the specified [csv options](basic_csv_options.md). #### Destructor virtual ~basic_csv_encoder() noexcept #### Member functions void reset(); Reset encoder to write another value to the same sink void reset(Sink&& sink) Reset encoder to write a new value to a new sink #### Inherited from [basic_json_visitor](../basic_json_visitor.md) void flush(); (1) bool begin_object(semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (2) bool begin_object(std::size_t length, semantic_tag tag=semantic_tag::none, const ser_context& context = ser_context()); (3) bool end_object(const ser_context& context = ser_context()); (4) bool begin_array(semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (5) bool begin_array(std::size_t length, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (6) bool end_array(const ser_context& context=ser_context()); (7) bool key(const string_view_type& name, const ser_context& context=ser_context()); (8) bool null_value(semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (9) bool bool_value(bool value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (10) bool string_value(const string_view_type& value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (11) bool byte_string_value(const byte_string_view& source, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (12) (until 0.152.0) template bool byte_string_value(const ByteStringLike& souce, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (12) (since 0.152.0) template bool byte_string_value(const ByteStringLike& souce, uint64_t ext_tag, const ser_context& context=ser_context()); (13) (since 0.152.0) bool uint64_value(uint64_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (14) bool int64_value(int64_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (15) bool half_value(uint16_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (16) bool double_value(double value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (17) bool begin_object(semantic_tag tag, const ser_context& context, std::error_code& ec); (18) bool begin_object(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec); (19) bool end_object(const ser_context& context, std::error_code& ec); (20) bool begin_array(semantic_tag tag, const ser_context& context, std::error_code& ec); (21) bool begin_array(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec); (22) bool end_array(const ser_context& context, std::error_code& ec); (23) bool key(const string_view_type& name, const ser_context& context, std::error_code& ec); (24) bool null_value(semantic_tag tag, const ser_context& context, std::error_code& ec); (25) bool bool_value(bool value, semantic_tag tag, const ser_context& context, std::error_code& ec); (26) bool string_value(const string_view_type& value, semantic_tag tag, const ser_context& context, std::error_code& ec); (27) bool byte_string_value(const byte_string_view& source, semantic_tag tag, const ser_context& context, std::error_code& ec); (28) (until 0.152.0) template bool byte_string_value(const ByteStringLike& source, semantic_tag tag, const ser_context& context, std::error_code& ec); (28) (since 0.152.0) template bool byte_string_value(const ByteStringLike& source, uint64_t ext_tag, const ser_context& context, std::error_code& ec); (29) (since 0.152.0) bool uint64_value(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (30) bool int64_value(int64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (31) bool half_value(uint16_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (32) bool double_value(double value, semantic_tag tag, const ser_context& context, std::error_code& ec); (33) template bool typed_array(const span& data, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (34) bool typed_array(half_arg_t, const span& s, semantic_tag tag = semantic_tag::none, const ser_context& context = ser_context()); (35) bool begin_multi_dim(const span& shape, semantic_tag tag, const ser_context& context); (36) bool end_multi_dim(const ser_context& context=ser_context()); (37) template bool typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (38) bool typed_array(half_arg_t, const span& s, semantic_tag tag, const ser_context& context, std::error_code& ec); (39) bool begin_multi_dim(const span& shape, semantic_tag tag, const ser_context& context, std::error_code& ec); (40) bool end_multi_dim(const ser_context& context, std::error_code& ec); (41) (1) Flushes whatever is buffered to the destination. (2) Indicates the begining of an object of indefinite length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (3) Indicates the begining of an object of known length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (4) Indicates the end of an object. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (5) Indicates the beginning of an indefinite length array. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (6) Indicates the beginning of an array of known length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (7) Indicates the end of an array. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (8) Writes the name part of an object name-value pair. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (9) Writes a null value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (10) Writes a boolean value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (11) Writes a text string value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (12) Writes a byte string value `source` with a generic tag. Type `ByteStringLike` must be a container that has member functions `data()` and `size()`, and member type `value_type` with size exactly 8 bits (since 0.152.0.) Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (13) Writes a byte string value `source` with a format specific tag, `ext_tag`. Type `ByteStringLike` must be a container that has member functions `data()` and `size()`, and member type `value_type` with size exactly 8 bits (since 0.152.0.) Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (14) Writes a non-negative integer value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (15) Writes a signed integer value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (16) Writes a half precision floating point value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (17) Writes a double precision floating point value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (18)-(33) Same as (2)-(17), except sets `ec` and returns `false` on parse errors. ### Examples ### Serializing an array of json values to a comma delimted file #### JSON input file ```json [ ["country_code","name"], ["ABW","ARUBA"], ["ATF","FRENCH SOUTHERN TERRITORIES, D.R. OF"], ["VUT","VANUATU"], ["WLF","WALLIS & FUTUNA ISLANDS"] ] ``` Note - The third array element has a value that contains a comma, in the CSV file this value will be quoted. #### Serializing the comma delimited file with csv_stream_encoder ```cpp std::string in_file = "input/countries.json"; std::ifstream is(in_file); json_decoder decoder; json_stream_reader reader(is,decoder); reader.read(); json countries = decoder.get_result(); csv_stream_encoder encoder(std::cout); countries.dump(encoder); ``` #### Output ``` country_code,name ABW,ARUBA ATF,"FRENCH SOUTHERN TERRITORIES, D.R. OF" VUT,VANUATU WLF,WALLIS & FUTUNA ISLANDS ``` ### Serializing an array of json objects to a tab delimted file #### JSON input file ```json [ { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" } ] ``` Note - The names in the first object in the array will be used for the header row of the CSV file - The fourth object has a `note` member whose value contains escaped quotes and an escaped new line character, in the CSV file, this value will be quoted, and it will contain a new line character and escaped quotes. #### Dump json value to a tab delimited file ```cpp std::string in_file = "input/employees.json"; std::ifstream is(in_file); json_decoder decoder; auto options = csv_options{} .field_delimiter = '\t'; json_stream_reader reader(is,decoder); reader.read(); json employees = decoder.get_result(); csv_stream_encoder encoder(std::cout,options); employees.dump(encoder); ``` #### Tab delimited output file ``` dept employee-name employee-no note salary sales Smith, Matthew 00000001 150,000.00 sales Brown, Sarah 00000002 89,000.00 finance Oberc, Scott 00000003 110,000.00 sales Scott, Colette 00000004 ""Exemplary"" employee Dependable, trustworthy 75,000.00 ``` #### Dump json value to csv file ```cpp #include #include using namespace jsoncons; int main() { const json books = json::parse(R"( [ { "title" : "Kafka on the Shore", "author" : "Haruki Murakami", "price" : 25.17 }, { "title" : "Women: A Novel", "author" : "Charles Bukowski", "price" : 12.00 }, { "title" : "Cutter's Way", "author" : "Ivan Passer" } ] )"); auto options = csv_options{} .column_names("author,title,price"); csv_stream_encoder encoder(std::cout, options); books.dump(encoder); } ``` Output: ```csv author,title,price Haruki Murakami,Kafka on the Shore,25.17 Charles Bukowski,Women: A Novel,12.0 Ivan Passer,Cutter's Way, ``` ### See also [byte_string_view](../byte_string_view.md) jsoncons-1.3.2/doc/ref/csv/basic_csv_options.md000066400000000000000000000253701477700171100215320ustar00rootroot00000000000000### jsoncons::csv::basic_csv_options ```cpp #include template< typename CharT > class basic_csv_options; ```
![basic_csv_options](./diagrams/basic_csv_options.png) Specifies options for reading and writing CSV data. Option|Reading|Writing|Default ------|-------|-------|------- flat (since 1.2.0)| |Indicates whether the encoder should process JSON as "flat" (without navigating through nested structures)|**true** max_nesting_depth (since 1.2.0)| |Maximum nesting depth allowed in the input when encoding nested JSON to CSV|**1024** column_mapping (since 1.2.0)| |Maps column paths identified by JSONPointers to plain names|No column mappings nan_to_str|Substitute string with `NaN`, if enabled|Sets a string replacement for `NaN` when writing JSON inf_to_str|Substitute string with `infinity`, if enabled|Sets a string replacement for infinity when writing JSON neginf_to_str|Substitute string with `negative infinity`, if enabled|Sets a string replacement for negative infinity when writing JSON nan_to_num| |Sets a number replacement for `NaN` when writing JSON inf_to_num| |Sets a number replacement for `Infinity` when writing JSON neginf_to_num| |Sets a number replacement for `Negative Infinity` when writing JSON line_delimiter|Not used. When reading, the parser accepts `\n`, `\r` and `\r\n`.|An end-of-line string that marks the end of a row.|**'\n'** field_delimiter|A character that indicates the end of a field.|Character to separate values.|**','** subfield_delimiter|A character that indicates the end of a single value in a multi-valued field.|Character to write between items in an array value.|No multivalued fields quote_char|A character to quote fields.|A character to quote fields.|**'"'** quote_escape_char|A character to escape quote characters occuring inside quoted fields. |Character to escape quote characters occurring inside quoted fields.|double quote character (quote character is doubled) quote_style| |Indicates what [quote_style](quote_style_kind.md) to use when quoting fields. |**minimal** column_names|Use these column names when reading the file.|Write these column names to the header line. header_lines|Number of header lines in the CSV text.|**1** if assume_header is true, otherwise **0** assume_header|Assume first row in file is header, use field names to construct objects.| |**false** skip_header|Skip the first (header) line of input.| |**false** ignore_empty_values|Do not read CSV fields that have empty values.| |**false** ignore_empty_lines|If set to true, all lines in the file that are empty (apart from record delimiter characters) are ignored. To ignore lines with only spaces or tabs, set trim to true.| |**true** trim_leading|Trim leading whitespace.| |**false** trim_trailing|Trim trailing whitespace.| |**false** trim|Trim both leading and trailing whitespace.| |**false** trim_leading_inside_quotes|Trim leading whitespace inside quote characters.| |**false** trim_trailing_inside_quotes|Trim trailing whitespace inside quote characters.| |**false** trim_inside_quotes|Trim both leading and trailing whitespace inside quote characters.|| **false** unquoted_empty_value_is_null|Replace empty field with json null value.| |**false** infer_types|Infer null, true, false, integers and floating point values in the CSV source.| |**true** lossless_number|If set to `true`, parse numbers with exponents and fractional parts as strings with semantic tagging `semantic_tag::bigdec`.| |**false** comment_starter|Character to comment out a line, must be at column 1| |None mapping_kind|Indicates what [mapping kind](csv_mapping_kind.md) to use when parsing a CSV file into a `basic_json`.| |`csv_mapping_kind::n_objects` if assume_header is true or column_names is not empty, otherwise `csv_mapping_kind::n_rows`.| max_lines|Maximum number of lines to read.| |Unlimited column_types|A comma separated list of data types corresponding to the columns in the file. The following data types are supported: string, integer, float and boolean. Example: "bool,float,string"}| column_defaults|A comma separated list of strings containing default json values corresponding to the columns in the file. Example: "false,0.0,"\"\""| float_format| |Overrides [floating point format](../float_chars_format.md) when serializing to CSV.| |[float_chars_format::general](float_chars_format.md). precision| |Overrides floating point precision when serializing csv from json.|Shortest representation. Aliases for common character types are provided: Type |Definition --------------------|------------------------------ `csv_options` |`basic_csv_options` `wcsv_options` |`basic_csv_options` Member type |Definition ------------------------------------|------------------------------ `char_type`|`CharT` `string_type`|`std::basic_string` #### Constructors basic_csv_options() Constructs a `basic_csv_options` with default values. basic_csv_options(const basic_csv_options& other) Copy constructor. basic_csv_options(basic_csv_options&& other) Move constructor. #### Modifiers basic_csv_options& flat(bool value); // (since 1.2.0) basic_csv_options& column_mapping( // (since 1.2.0) const std::vector>& value); basic_csv_options& max_nesting_depth(std::size_t value); // (since 1.2.0) basic_json_options& nan_to_str(const string_type& value, bool enable_inverse = true); Sets a string replacement for `NaN` when writing JSON, and indicate whether it is also to be used when reading JSON. basic_json_options& inf_to_str(const string_type& value, bool enable_inverse = true); Sets a string replacement for infinity when writing JSON, and indicate whether it is also to be used when reading JSON. basic_json_options& neginf_to_str(const string_type& value, bool enable_inverse = true); (4) Sets a string replacement for negative infinity when writing JSON, and indicate whether it is also to be used when reading JSON. basic_json_options& nan_to_num(const string_type& value); Sets a number replacement for `NaN` when writing JSON basic_json_options& inf_to_num(const string_type& value); Sets a number replacement for `Infinity` when writing JSON basic_json_options& neginf_to_num(const string_type& value); Sets a number replacement for `Negative Infinity` when writing JSON basic_csv_options& float_format(float_chars_format value); Overrides [floating point format](../float_chars_format.md) when serializing to CSV. The default is [float_chars_format::general](float_chars_format.md). basic_csv_options& precision(int8_t value); Overrides floating point precision when serializing csv from json. The default is shortest representation. basic_csv_options& header_lines(std::size_t value); Number of header lines in the CSV text. Defaults to 1 if assume_header is true, otherwise 0 basic_csv_options& assume_header(bool value); Assume first row in file is header, use field names to construct objects. Default is `false`. basic_csv_options& ignore_empty_values(bool value); Do not read CSV fields that have empty values. Default is `false`. basic_csv_options& ignore_empty_lines(bool value); If set to true, all lines in the file that are empty (apart from record delimiter characters) are ignored. To ignore lines with only spaces or tabs, set trim to true. Default is `true`. basic_csv_options& trim_leading(bool value); Trim leading whitespace. Default is `false`. basic_csv_options& trim_trailing(bool value); Trim trailing whitespace. Default is `false`. basic_csv_options& trim(bool value); Trim both leading and trailing whitespace. Default is `false`. basic_csv_options& trim_leading_inside_quotes(bool value); Trim leading whitespace inside quote characters. Default is `false`. basic_csv_options& trim_trailing_inside_quotes(bool value); Trim trailing whitespace inside quote characters. Default is `false`. basic_csv_options& trim_inside_quotes(bool value); Trim both leading and trailing whitespace inside quote characters. Default is `false`. basic_csv_options& unquoted_empty_value_is_null(bool value); Replace empty field with json null value. Default is `false`. basic_csv_options& column_names(const string_type& value); A comma separated list of names corresponding to the fields in the file. Example: "bool-field,float-field,string-field" basic_csv_options& column_types(const string_type& value); A comma separated list of data types corresponding to the columns in the file. The following data types are supported: string, integer, float and boolean. Example: "bool,float,string"} basic_csv_options& column_defaults(const string_type& value); A comma separated list of strings containing default json values corresponding to the columns in the file. Example: "false,0.0,"\"\"" basic_csv_options& field_delimiter(char_type value); A delimiter character that indicates the end of a field. Default is `,` basic_csv_options& subfield_delimiter(char_type value); A delimiter character that indicates the end of a single value in a multi-valued field. Default is no multi-valued fields. basic_csv_options& line_delimiter(string_type value); String to write between records. Default is `\n`. basic_csv_options& quote_char(char_type value); Quote character. Default is quote character `"` basic_csv_options& infer_types(bool value); Infer null, true, false, integers and floating point values in the CSV source. Default is `true`. basic_csv_options& lossless_number(bool value); If set to `true`, parse numbers with exponents and fractional parts as strings with semantic tagging `semantic_tag::bigdec`. Default is `false`. basic_csv_options& quote_escape_char(char_type value); Character to escape quote character (by default the quote character is doubled). Default is quote character `"`. basic_csv_options& comment_starter(char_type value); Character to comment out a line, must be at column 1. Default is no comments. basic_csv_options& quote_style(quote_style_kind value); Indicates what [quote_style](quote_style_kind.md) to use when quoting fields. Default is minimal. basic_csv_options& mapping_kind(csv_mapping_kind value); Indicates what [mapping kind](csv_mapping_kind.md) to use when parsing a CSV file into a `basic_json`. If assume_header is true or column_names is not empty, defaults to `csv_mapping_kind::n_rows`, otherwise `csv_mapping_kind::n_columns`. basic_csv_options& max_lines(std::size_t value); Maximum number of lines to read. Default is unlimited. jsoncons-1.3.2/doc/ref/csv/basic_csv_reader.md000066400000000000000000000305671477700171100213050ustar00rootroot00000000000000### jsoncons::csv::basic_csv_reader ```cpp #include template< typename CharT, typename Source=jsoncons::stream_source, typename TempAllocator=std::allocator> class basic_csv_reader ``` The `basic_csv_reader` class reads a [CSV file](http://tools.ietf.org/html/rfc4180) and produces JSON parse events. `basic_csv_reader` is noncopyable and nonmoveable. A number of specializations for common character types are defined: Type |Definition ----------------------|------------------------------ `csv_string_reader` |`basic_csv_string_reader>` (since 0.164.0) `wcsv_stringreader` |`basic_csv_string_reader>` (since 0.164.0) `csv_stream_reader` |`basic_csv_stream_reader>` (since 0.164.0) `wcsv_stream_reader` |`basic_csv_stream_reader>` (since 0.164.0) `csv_reader` |Constructible from either a string or stream (deprecated since 0.164.0) `wcsv_reader` |Constructible from either a wide character string or stream (deprecated since 0.164.0) #### Member types Type |Definition ---------------------------|------------------------------ char_type |CharT source_type |Source #### Constructors template basic_csv_reader(Sourceable&& source, basic_json_visitor& visitor, const TempAllocator& alloc = TempAllocator()); (1) template basic_csv_reader(Sourceable&& source, basic_json_visitor& visitor, const basic_csv_options& options, const TempAllocator& alloc = TempAllocator()); (2) template basic_csv_reader(Sourceable&& source, basic_json_visitor& visitor, std::function err_handler, const TempAllocator& alloc = TempAllocator()); (3) template basic_csv_reader(Sourceable&& source, basic_json_visitor& visitor, const basic_csv_options& options, std::function err_handler, const TempAllocator& alloc = TempAllocator()); (4) (1) Constructs a `basic_csv_reader` that reads from a character sequence or stream `source` and a [basic_json_visitor](../basic_json_visitor.md) that receives JSON events. Uses default [basic_csv_options](basic_csv_options.md). (2) Constructs a `basic_csv_reader` that that reads from a character sequence or stream `source`, a [basic_json_visitor](../basic_json_visitor.md) that receives JSON events, and [basic_csv_options](basic_csv_options.md). (3) Constructs a `basic_csv_reader` that reads from a character sequence or stream `source`, a [basic_json_visitor](../basic_json_visitor.md) that receives JSON events and the specified [JSON parsing error handling](../err_handler.md). Uses default [basic_csv_options](basic_csv_options.md). (4) Constructs a `basic_csv_reader` that reads from a character sequence or stream `source`, a [basic_json_visitor](../basic_json_visitor.md) that receives JSON events, [basic_csv_options](basic_csv_options.md), and the specified [JSON parsing error handling](../err_handler.md). Note: It is the programmer's responsibility to ensure that `basic_csv_reader` does not outlive any source or visitor passed in the constuctor, as `basic_csv_reader` holds pointers to but does not own these resources. #### Parameters `source` - a value from which a `jsoncons::basic_string_view` is constructible, or a value from which a `source_type` is constructible. In the case that a `jsoncons::basic_string_view` is constructible from `source`, `source` is dispatched immediately to the parser. Otherwise, the `basic_csv_reader` reads from a `source_type` in chunks. #### Member functions bool eof() const Returns `true` when there is no more data to be read from the stream, `false` otherwise void read() Reports JSON related events for JSON objects, arrays, object members and array elements to a [basic_json_visitor](../basic_json_visitor.md), such as a [json_decoder](json_decoder.md). Throws a [ser_error](../ser_error.md) if parsing fails. ### Examples #### Reading a comma delimted file into an array of json values #### Comma delimited input file ``` country_code,name ABW,ARUBA ATF,"FRENCH SOUTHERN TERRITORIES, D.R. OF" VUT,VANUATU WLF,WALLIS & FUTUNA ISLANDS ``` Note - The first record contains a header line, but we're going to ignore that and read the entire file as an array of arrays. - The third record has a field value that contains an embedded comma, so it must be quoted. #### Code ```cpp std::string in_file = "countries.csv"; std::ifstream is(in_file); json_decoder decoder; csv_stream_reader reader(is,decoder); reader.read(); json countries = decoder.get_result(); std::cout << pretty_print(countries) << '\n'; ``` #### Output ```json [ ["country_code","name"], ["ABW","ARUBA"], ["ATF","FRENCH SOUTHERN TERRITORIES, D.R. OF"], ["VUT","VANUATU"], ["WLF","WALLIS & FUTUNA ISLANDS"] ] ``` #### Reading a tab delimted file into an array of json objects #### Tab delimited input file ``` employee-no employee-name dept salary note 00000001 Smith, Matthew sales 150,000.00 00000002 Brown, Sarah sales 89,000.00 00000003 Oberc, Scott finance 110,000.00 00000004 Scott, Colette sales 75,000.00 """Exemplary"" employee Dependable, trustworthy" ``` Note - The first record is a header line, which will be used to associate data values with names - The fifth record has a field value that contains embedded quotes and a new line character, so it must be quoted and the embedded quotes escaped. #### Code ```cpp std::string in_file = "employees.txt"; std::ifstream is(in_file); json_decoder decoder; auto options = csv_options{} .field_delimiter = '\t' .assume_header = true; csv_stream_reader reader(is,decoder,options); reader.read(); json employees = decoder.get_result(); std::cout << pretty_print(employees) << '\n'; ``` #### Output ```json [ { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "note":"", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "salary":"75,000.00" } ] ``` #### Reading the comma delimited file as an array of objects with user supplied columns names Note - The first record contains a header line, but we're going to ignore that and use our own names for the fields. #### Code ```cpp std::string in_file = "countries.csv"; std::ifstream is(in_file); json_decoder decoder; auto options = csv_options{} .column_names("Country Code,Name") .header_lines(1); csv_stream_reader reader(is,decoder,options); reader.read(); json countries = decoder.get_result(); std::cout << pretty_print(countries) << '\n'; ``` #### Output ```json [ { "Country Code":"ABW", "Name":"ARUBA" }, { "Country Code":"ATF", "Name":"FRENCH SOUTHERN TERRITORIES, D.R. OF" }, { "Country Code":"VUT", "Name":"VANUATU" }, { "Country Code":"WLF", "Name":"WALLIS & FUTUNA ISLANDS" } ] ``` #### Reading a comma delimited file with different mapping strategies #### Input ```csv Date,1Y,2Y,3Y,5Y 2017-01-09,0.0062,0.0075,0.0083,0.011 2017-01-08,0.0063,0.0076,0.0084,0.0112 2017-01-08,0.0063,0.0076,0.0084,0.0112 ``` #### Code ```cpp json_decoder decoder; auto options = csv_options{} .assume_header(true) .column_types("string,float,float,float,float") .mapping_kind(csv_mapping_kind::n_rows); std::istringstream is1("bond_yields.csv"); csv_stream_reader reader1(is1,decoder,options); reader1.read(); ojson val1 = decoder.get_result(); std::cout << "\n(1)\n"<< pretty_print(val1) << "\n"; options.mapping_kind(csv_mapping_kind::n_objects); std::istringstream is2("bond_yields.csv"); csv_stream_reader reader2(is2,decoder,options); reader2.read(); ojson val2 = decoder.get_result(); std::cout << "\n(2)\n"<< pretty_print(val2) << "\n"; options.mapping_kind(csv_mapping_kind::m_columns); std::istringstream is3("bond_yields.csv"); csv_stream_reader reader3(is3, decoder, options); reader3.read(); ojson val3 = decoder.get_result(); std::cout << "\n(3)\n" << pretty_print(val3) << "\n"; ``` #### Output ```json (1) [ ["Date","1Y","2Y","3Y","5Y"], ["2017-01-09",0.0062,0.0075,0.0083,0.011], ["2017-01-08",0.0063,0.0076,0.0084,0.0112], ["2017-01-08",0.0063,0.0076,0.0084,0.0112] ] (2) [ { "Date": "2017-01-09", "1Y": 0.0062, "2Y": 0.0075, "3Y": 0.0083, "5Y": 0.011 }, { "Date": "2017-01-08", "1Y": 0.0063, "2Y": 0.0076, "3Y": 0.0084, "5Y": 0.0112 }, { "Date": "2017-01-08", "1Y": 0.0063, "2Y": 0.0076, "3Y": 0.0084, "5Y": 0.0112 } ] (3) { "Date": ["2017-01-09","2017-01-08","2017-01-08"], "1Y": [0.0062,0.0063,0.0063], "2Y": [0.0075,0.0076,0.0076], "3Y": [0.0083,0.0084,0.0084], "5Y": [0.011,0.0112,0.0112] } ``` #### Convert CSV to json when last column repeats ```cpp int main() { const std::string bond_yields = R"(Date,Yield 2017-01-09,0.0062,0.0075,0.0083,0.011,0.012 2017-01-08,0.0063,0.0076,0.0084,0.0112,0.013 2017-01-08,0.0063,0.0076,0.0084,0.0112,0.014 )"; // array of arrays json_decoder decoder1; auto options1 = csv_options{} .header_lines(1) .assume_header(false) .column_types("string,float*"); std::istringstream is1(bond_yields); csv_stream_reader reader1(is1, decoder1, options1); reader1.read(); ojson val1 = decoder1.get_result(); std::cout << "\n(1)\n" << pretty_print(val1) << "\n"; // array of objects json_decoder decoder2; auto options2 = csv_options{} .assume_header(true) .column_types("string,[float*]"); std::istringstream is2(bond_yields); csv_stream_reader reader2(is2, decoder2, options2); reader2.read(); ojson val2 = decoder2.get_result(); std::cout << "\n(2)\n" << pretty_print(val2) << "\n"; } ``` Output: ``` (1) [ ["2017-01-09",0.0062,0.0075,0.0083,0.011,0.012], ["2017-01-08",0.0063,0.0076,0.0084,0.0112,0.013], ["2017-01-08",0.0063,0.0076,0.0084,0.0112,0.014] ] (2) [ { "Date": "2017-01-09", "Yield": [0.0062,0.0075,0.0083,0.011,0.012] }, { "Date": "2017-01-08", "Yield": [0.0063,0.0076,0.0084,0.0112,0.013] }, { "Date": "2017-01-08", "Yield": [0.0063,0.0076,0.0084,0.0112,0.014] } ] ``` #### Convert CSV to json when last two columns repeat ```cpp const std::string holidays = R"(1,CAD,2,UK,3,EUR,4,US + UK,5,US 38719,2-Jan-2006,40179,1-Jan-2010,38719,2-Jan-2006,38719,2-Jan-2006,39448,1-Jan-2008 38733,16-Jan-2006,40270,2-Apr-2010,38733,16-Jan-2006,38733,16-Jan-2006,39468,21-Jan-2008 )"; json_decoder decoder; auto options = csv_options{} .column_types("[integer,string]*"); // Default std::istringstream is1(holidays); csv_stream_reader reader1(is1, decoder, options); reader1.read(); ojson val1 = decoder.get_result(); std::cout << pretty_print(val1) << "\n"; ``` Output: ``` [ [ [1,"CAD"], [2,"UK"], [3,"EUR"], [4,"US + UK"], [5,"US"] ], [ [38719,"2-Jan-2006"], [40179,"1-Jan-2010"], [38719,"2-Jan-2006"], [38719,"2-Jan-2006"], [39448,"1-Jan-2008"] ], [ [38733,"16-Jan-2006"], [40270,"2-Apr-2010"], [38733,"16-Jan-2006"], [38733,"16-Jan-2006"], [39468,"21-Jan-2008"] ] ] ``` jsoncons-1.3.2/doc/ref/csv/csv.md000066400000000000000000000225261477700171100166160ustar00rootroot00000000000000### csv extension The csv extension implements decode from and encode to the [CSV format](https://www.rfc-editor.org/rfc/rfc4180.txt) [decode_csv](decode_csv.md) [basic_csv_cursor](basic_csv_cursor.md) [encode_csv](encode_csv.md) [basic_csv_options](basic_csv_options.md) [basic_csv_reader](basic_csv_reader.md) [basic_csv_encoder](basic_csv_encoder.md) ### Working with CSV data For the examples below you need to include some header files and initialize a string of CSV data: ```cpp #include #include #include #include const std::string data = R"(index_id,observation_date,rate EUR_LIBOR_06M,2015-10-23,0.0000214 EUR_LIBOR_06M,2015-10-26,0.0000143 EUR_LIBOR_06M,2015-10-27,0.0000001 )"; ``` jsoncons allows you to work with the CSV data similarly to JSON data: - As a variant-like data structure, [basic_json](../basic_json.md) - As a strongly typed C++ data structure that implements [json_type_traits](../json_type_traits.md) - With [cursor-level access](doc/ref/csv/basic_csv_cursor.md) to a stream of parse events #### As a variant-like data structure ```cpp int main() { auto options = csv::csv_options{} .assume_header(true); // Parse the CSV data into an ojson value ojson j = csv::decode_csv(data, options); // Pretty print auto print_options = json_options{} .float_format(float_chars_format::fixed); std::cout << "(1)\n" << pretty_print(j, print_options) << "\n\n"; // Iterate over the rows std::cout << "(2)\n"; for (const auto& row : j.array_range()) { // Access rated as string and rating as double std::cout << row["index_id"].as() << ", " << row["observation_date"].as() << ", " << row["rate"].as() << "\n"; } } ``` Output: ``` (1) [ { "index_id": "EUR_LIBOR_06M", "observation_date": "2015-10-23", "rate": 0.0000214 }, { "index_id": "EUR_LIBOR_06M", "observation_date": "2015-10-26", "rate": 0.0000143 }, { "index_id": "EUR_LIBOR_06M", "observation_date": "2015-10-27", "rate": 0.0000001 } ] (2) EUR_LIBOR_06M, 2015-10-23, 0.0000214 EUR_LIBOR_06M, 2015-10-26, 0.0000143 EUR_LIBOR_06M, 2015-10-27, 0.0000001 ``` #### As a strongly typed C++ data structure jsoncons supports transforming CSV data into C++ data structures. The functions decode_csv and encode_csv convert strings or streams of CSV data to C++ data structures and back. Decode and encode work for all C++ classes that have [json_type_traits](../json_type_traits.md) defined. jsoncons already supports many types in the standard library, and your own types will be supported too if you specialize [json_type_traits](../json_type_traits.md) in the jsoncons namespace. ```cpp #include namespace ns { class fixing { std::string index_id_; boost::gregorian::date observation_date_; double rate_; public: fixing(const std::string& index_id, boost::gregorian::date observation_date, double rate) : index_id_(index_id), observation_date_(observation_date), rate_(rate) { } const std::string& index_id() const {return index_id_;} boost::gregorian::date observation_date() const {return observation_date_;} double rate() const {return rate_;} }; } // namespace ns template struct json_type_traits { static bool is(const Json& val) noexcept { if (!val.is_string()) return false; try { std::string s = val.template as(); boost::gregorian::from_simple_string(s); return true; } catch (...) { return false; } } static boost::gregorian::date as(const Json& val) { std::string s = val.template as(); return boost::gregorian::from_simple_string(s); } static Json to_json(boost::gregorian::date val, Json::allocator_type alloc = Json::allocator_type()) { return Json(to_iso_extended_string(val), alloc); } }; JSONCONS_ALL_CTOR_GETTER_TRAITS(ns::fixing, index_id, observation_date, rate) int main() { auto options = csv::csv_options{} .assume_header(true) .float_format(float_chars_format::fixed); // Decode the CSV data into a c++ structure std::vector v = csv::decode_csv>(data, options); // Iterate over values std::cout << std::fixed << std::setprecision(7); std::cout << "(1)\n"; for (const auto& item : v) { std::cout << item.index_id() << ", " << item.observation_date() << ", " << item.rate() << "\n"; } // Encode the c++ structure into CSV data std::string s; csv::encode_csv(v, s, options); std::cout << "(2)\n"; std::cout << s << "\n"; } ``` Output: ``` (1) EUR_LIBOR_06M, 2015-10-23, 0.0000214 EUR_LIBOR_06M, 2015-10-26, 0.0000143 EUR_LIBOR_06M, 2015-10-27, 0.0000001 (2) index_id,observation_date,rate EUR_LIBOR_06M,2015-10-23,0.0000214 EUR_LIBOR_06M,2015-10-26,0.0000143 EUR_LIBOR_06M,2015-10-27,0.0000001 ``` #### With cursor-level access ```cpp int main() { auto options = csv::csv_options{} .assume_header(true); csv::csv_string_cursor cursor(data, options); for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::end_array: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::begin_object: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::end_object: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::key: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::string_value: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::null_value: std::cout << event.event_type() << "\n"; break; case staj_event_type::bool_value: std::cout << event.event_type() << ": " << std::boolalpha << event.get() << "\n"; break; case staj_event_type::int64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::double_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; default: std::cout << "Unhandled event type: " << event.event_type() << " " << "\n"; break; } } } ``` Output: ``` begin_array begin_object key: index_id string_value: EUR_LIBOR_06M key: observation_date string_value: 2015-10-23 key: rate double_value: 0.0000214 end_object begin_object key: index_id string_value: EUR_LIBOR_06M key: observation_date string_value: 2015-10-26 key: rate double_value: 0.0000143 end_object begin_object key: index_id string_value: EUR_LIBOR_06M key: observation_date string_value: 2015-10-27 key: rate double_value: 0.0000001 end_object end_array ``` You can use a [staj_array_iterator](../staj_array_iterator.md) to group the CSV parse events into [basic_json](../basic_json.md) records: ```cpp int main() { auto options = csv::csv_options{} .assume_header(true); csv::csv_string_cursor cursor(data, options); auto view = staj_array(cursor); auto print_options = json_options{} .float_format(float_chars_format::fixed); for (const auto& item : view) { std::cout << pretty_print(item, print_options) << "\n"; } } ``` Output: ``` { "index_id": "EUR_LIBOR_06M", "observation_date": "2015-10-23", "rate": 0.0000214 } { "index_id": "EUR_LIBOR_06M", "observation_date": "2015-10-26", "rate": 0.0000143 } { "index_id": "EUR_LIBOR_06M", "observation_date": "2015-10-27", "rate": 0.0000001 } ``` Or into strongly typed records: ```cpp int main() { using record_type = std::tuple; auto options = csv::csv_options{} .assume_header(true); csv::csv_string_cursor cursor(data, options); auto view = staj_array(cursor); std::cout << std::fixed << std::setprecision(7); for (const auto& record : view) { std::cout << std::get<0>(record) << ", " << std::get<1>(record) << ", " << std::get<2>(record) << "\n"; } } ``` Output ``` EUR_LIBOR_06M, 2015-10-23, 0.0000214 EUR_LIBOR_06M, 2015-10-26, 0.0000143 EUR_LIBOR_06M, 2015-10-27, 0.0000001 ``` jsoncons-1.3.2/doc/ref/csv/csv_mapping_kind.md000066400000000000000000000006561477700171100213360ustar00rootroot00000000000000### jsoncons::csv::csv_mapping_kind ```cpp #include enum class csv_mapping_kind { n_rows = 1, n_objects, m_columns }; ``` Value |Definition -----------|----------- n_rows | Map a CSV file to an array of arrays in a `basic_json`. n_objects | Map a CSV file to an array of objects in a `basic_json`. m_columns | Map a CSV file to an object with name/array-value pairs. jsoncons-1.3.2/doc/ref/csv/decode_csv.md000066400000000000000000000265711477700171100201250ustar00rootroot00000000000000### jsoncons::csv::decode_csv Decodes a [comma-separated variables (CSV)](https://en.wikipedia.org/wiki/Comma-separated_values) data format into a C++ data structure. ```cpp #include template T decode_csv(const Source& s, const basic_csv_decode_options& options = basic_csv_decode_options())); (1) template T decode_csv(std::basic_istream& is, const basic_csv_decode_options& options = basic_csv_decode_options())); (2) template T decode_csv(InputIt first, InputIt last, const basic_csv_decode_options& options = basic_csv_decode_options())); (3) (since 0.153.0) template T decode_csv(allocator_set alloc_set, const Source& s, const basic_csv_decode_options& options = basic_csv_decode_options()); (4) template T decode_csv(allocator_set alloc_set, std::basic_istream& is, const basic_csv_decode_options& options = basic_csv_decode_options()); (5) ``` (1) Reads CSV data from a contiguous character sequence into a type T, using the specified (or defaulted) [options](basic_csv_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). (2) Reads CSV data from an input stream into a type T, using the specified (or defaulted) [options](basic_csv_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). (3) Reads CSV data from the range [`first`,`last`) into a type T, using the specified (or defaulted) [options](basic_csv_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). Functions (4)-(5) are identical to (1)-(2) except an [allocator_set](../allocator_set.md) is passed as an additional argument and provides allocators for result data and temporary allocations. #### Return value Returns a value of type `T`. #### Exceptions Throws a [ser_error](../ser_error.md) if parsing fails, and a [conv_error](conv_error.md) if type conversion fails. ### Examples #### Decode a CSV file with type inference (default) Example file (sales.csv) ```csv customer_name,has_coupon,phone_number,zip_code,sales_tax_rate,total_amount "John Roe",true,0272561313,01001,0.05,431.65 "Jane Doe",false,416-272-2561,55416,0.15,480.70 "Joe Bloggs",false,"4162722561","55416",0.15,300.70 "John Smith",FALSE,NULL,22313-1450,0.15,300.70 ``` ```cpp #include #include #include using namespace jsoncons; int main() { auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_objects); std::ifstream is1("input/sales.csv"); ojson j1 = csv::decode_csv(is1,options); std::cout << "\n(1)\n"<< pretty_print(j1) << "\n"; options.mapping_kind(csv::csv_mapping_kind::n_rows); std::ifstream is2("input/sales.csv"); ojson j2 = csv::decode_csv(is2,options); std::cout << "\n(2)\n"<< pretty_print(j2) << "\n"; options.mapping_kind(csv::csv_mapping_kind::m_columns); std::ifstream is3("input/sales.csv"); ojson j3 = csv::decode_csv(is3,options); std::cout << "\n(3)\n"<< pretty_print(j3) << "\n"; } ``` Output: ```json (1) [ { "customer_name": "John Roe", "has_coupon": true, "phone_number": "0272561313", "zip_code": "01001", "sales_tax_rate": 0.05, "total_amount": 431.65 }, { "customer_name": "Jane Doe", "has_coupon": false, "phone_number": "416-272-2561", "zip_code": 55416, "sales_tax_rate": 0.15, "total_amount": 480.7 }, { "customer_name": "Joe Bloggs", "has_coupon": false, "phone_number": "4162722561", "zip_code": "55416", "sales_tax_rate": 0.15, "total_amount": 300.7 }, { "customer_name": "John Smith", "has_coupon": false, "phone_number": null, "zip_code": "22313-1450", "sales_tax_rate": 0.15, "total_amount": 300.7 } ] (2) [ ["customer_name","has_coupon","phone_number","zip_code","sales_tax_rate","total_amount"], ["John Roe",true,"0272561313","01001",0.05,431.65], ["Jane Doe",false,"416-272-2561",55416,0.15,480.7], ["Joe Bloggs",false,"4162722561","55416",0.15,300.7], ["John Smith",false,null,"22313-1450",0.15,300.7] ] (3) { "customer_name": ["John Roe","Jane Doe","Joe Bloggs","John Smith"], "has_coupon": [true,false,false,false], "phone_number": ["0272561313","416-272-2561",4162722561,null], "zip_code": ["01001",55416,55416,"22313-1450"], "sales_tax_rate": [0.05,0.15,0.15,0.15], "total_amount": [431.65,480.7,300.7,300.7] } ``` #### Decode a CSV string without type inference ```cpp #include #include using namespace jsoncons; int main() { std::string s = R"(employee-no,employee-name,dept,salary 00000001,"Smith,Matthew",sales,150000.00 00000002,"Brown,Sarah",sales,89000.00 )"; auto options = csv::csv_options{} .assume_header(true) .infer_types(false); ojson j = csv::decode_csv(s,options); std::cout << pretty_print(j) << '\n'; } ``` Output: ```json [ { "employee-no": "00000001", "employee-name": "Smith,Matthew", "dept": "sales", "salary": "150000.00" }, { "employee-no": "00000002", "employee-name": "Brown,Sarah", "dept": "sales", "salary": "89000.00" } ] ``` #### Decode a CSV string with specified types ```cpp #include #include using namespace jsoncons; int main() { const std::string s = R"(Date,1Y,2Y,3Y,5Y 2017-01-09,0.0062,0.0075,0.0083,0.011 2017-01-08,0.0063,0.0076,0.0084,0.0112 2017-01-08,0.0063,0.0076,0.0084,0.0112 )"; auto options = csv::csv_options{} .assume_header(true) .column_types("string,float,float,float,float"); // csv_mapping_kind::n_objects options.mapping_kind(csv::csv_mapping_kind::n_objects); ojson j1 = csv::decode_csv(s,options); std::cout << "\n(1)\n"<< pretty_print(j1) << "\n"; // csv_mapping_kind::n_rows options.mapping_kind(csv::csv_mapping_kind::n_rows); ojson j2 = csv::decode_csv(s,options); std::cout << "\n(2)\n"<< pretty_print(j2) << "\n"; // csv_mapping_kind::m_columns options.mapping_kind(csv::csv_mapping_kind::m_columns); ojson j3 = csv::decode_csv(s,options); std::cout << "\n(3)\n" << pretty_print(j3) << "\n"; } ``` Output: ```json (1) [ { "Date": "2017-01-09", "1Y": 0.0062, "2Y": 0.0075, "3Y": 0.0083, "5Y": 0.011 }, { "Date": "2017-01-08", "1Y": 0.0063, "2Y": 0.0076, "3Y": 0.0084, "5Y": 0.0112 }, { "Date": "2017-01-08", "1Y": 0.0063, "2Y": 0.0076, "3Y": 0.0084, "5Y": 0.0112 } ] (2) [ ["Date","1Y","2Y","3Y","5Y"], ["2017-01-09",0.0062,0.0075,0.0083,0.011], ["2017-01-08",0.0063,0.0076,0.0084,0.0112], ["2017-01-08",0.0063,0.0076,0.0084,0.0112] ] (3) { "Date": ["2017-01-09","2017-01-08","2017-01-08"], "1Y": [0.0062,0.0063,0.0063], "2Y": [0.0075,0.0076,0.0076], "3Y": [0.0083,0.0084,0.0084], "5Y": [0.011,0.0112,0.0112] } ``` #### Decode a CSV string with multi-valued fields separated by subfield delimiters ```cpp #include #include using namespace jsoncons; int main() { const std::string s = R"(calculationPeriodCenters,paymentCenters,resetCenters NY;LON,TOR,LON NY,LON,TOR;LON "NY";"LON","TOR","LON" "NY","LON","TOR";"LON" )"; auto print_options = json_options{} .array_array_line_splits(line_split_kind::same_line); auto options1 = csv::csv_options{} .assume_header(true) .subfield_delimiter(';'); json j1 = csv::decode_csv(s,options1); std::cout << "(1)\n" << pretty_print(j1,print_options) << "\n\n"; auto options2 = csv::csv_options{} .mapping_kind(csv::csv_mapping_kind::n_rows) .subfield_delimiter(';'); json j2 = csv::decode_csv(s,options2); std::cout << "(2)\n" << pretty_print(j2,print_options) << "\n\n"; auto options3 = csv::csv_options{} assume_header(true) .mapping_kind(csv::csv_mapping_kind::m_columns) .subfield_delimiter(';'); json j3 = csv::decode_csv(s,options3); std::cout << "(3)\n" << pretty_print(j3,print_options) << "\n\n"; } ``` Output: ```json (1) [ { "calculationPeriodCenters": ["NY","LON"], "paymentCenters": "TOR", "resetCenters": "LON" }, { "calculationPeriodCenters": "NY", "paymentCenters": "LON", "resetCenters": ["TOR","LON"] }, { "calculationPeriodCenters": ["NY","LON"], "paymentCenters": "TOR", "resetCenters": "LON" }, { "calculationPeriodCenters": "NY", "paymentCenters": "LON", "resetCenters": ["TOR","LON"] } ] (2) [ ["calculationPeriodCenters","paymentCenters","resetCenters"], [["NY","LON"],"TOR","LON"], ["NY","LON",["TOR","LON"]], [["NY","LON"],"TOR","LON"], ["NY","LON",["TOR","LON"]] ] (3) { "calculationPeriodCenters": [["NY","LON"],"NY",["NY","LON"],"NY"], "paymentCenters": ["TOR","LON","TOR","LON"], "resetCenters": ["LON",["TOR","LON"],"LON",["TOR","LON"]] } ``` #### Convert a CSV source to a C++ data structure that satisfies [json_type_traits](../json_type_traits.md) requirements, and back ```cpp #include #include #include using namespace jsoncons; int main() { const std::string input = R"(Date,1Y,2Y,3Y,5Y 2017-01-09,0.0062,0.0075,0.0083,0.011 2017-01-08,0.0063,0.0076,0.0084,0.0112 2017-01-08,0.0063,0.0076,0.0084,0.0112 )"; auto ioptions = csv::csv_options{} .header_lines(1) .mapping_kind(csv::csv_mapping_kind::n_rows); using table_type = std::vector>; table_type table = csv::decode_csv(input,ioptions); std::cout << "(1)\n"; for (const auto& row : table) { std::cout << std::get<0>(row) << "," << std::get<1>(row) << "," << std::get<2>(row) << "," << std::get<3>(row) << "," << std::get<4>(row) << "\n"; } std::cout << "\n"; std::string output; auto ooptions = csv::csv_options{} .column_names("Date,1Y,2Y,3Y,5Y"); csv::encode_csv(table, output, ooptions); std::cout << "(2)\n"; std::cout << output << "\n"; } ``` Output: ``` (1) 2017-01-09,0.0062,0.0075,0.0083,0.011 2017-01-08,0.0063,0.0076,0.0084,0.011 2017-01-08,0.0063,0.0076,0.0084,0.011 (2) Date,1Y,2Y,3Y,5Y 2017-01-09,0.0062,0.0075,0.0083,0.011 2017-01-08,0.0063,0.0076,0.0084,0.0112 2017-01-08,0.0063,0.0076,0.0084,0.0112 ``` jsoncons-1.3.2/doc/ref/csv/diagrams/000077500000000000000000000000001477700171100172615ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/csv/diagrams/basic_csv_encoder.png000066400000000000000000000122011477700171100234160ustar00rootroot00000000000000PNG  IHDRUep7 tEXtmxfile%3Cmxfile%20modified%3D%222020-03-31T16%3A34%3A51.268Z%22%20host%3D%22app.diagrams.net%22%20agent%3D%225.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F80.0.3987.149%20Safari%2F537.36%22%20etag%3D%22ljlubEiyVB8b1q8MmBtG%22%20version%3D%2212.9.6%22%20type%3D%22device%22%3E%3Cdiagram%20id%3D%22iK-0d-7Yl-5MlnfMu26I%22%20name%3D%22Page-1%22%3EzVZNc9owEP01PqZjW5DCMQGStgyZpnQGcmIUa2OrlSUqCzD99ZWwhC3bTJKZHJpLtG%2B1%2BnjvrUyAJnl5L%2FE2WwgCLIhDUgZoGsRxFKKR%2FmeQY4UMxhZIJSV2Ug0s6V9wlRbdUQKFN1EJwRTd%2BmAiOIdEeRiWUhz8aS%2BC%2BbtucQodYJlg1kVXlKisQkfDsMa%2FAE0zt3MU2kyO3WQLFBkm4tCA0CxAEymEqkZ5OQFmyHO8VHV3F7Lng0ng6i0Fs4efJZ8%2FLrN48meuVov8qfx2ZVfZY7azF37GBU02vwrBN3taUCVkEF8zvcPtsxmlZmQvpI6OJSl2nIDZKNTpQ0YVLLc4MdmD9oXGMpUzHUXn6ubB3SlAKigbkL3IPYgclDzqKTY7spxaU0WO40MtUTSwWNaQx2HYuiI9r1wTpweWu3fw%2BPkCj0mx3wBPdFv00vixxL5QxiaCacVMLYLTn8YLJcVvaGTQNRoj8jFS%2FH9ajDpadGgFTm7M46CjhOFCK%2BUzCSVVa0u6GT%2BZ8aehjaZlIzU9uoDrw6%2FdAiZoVJmwLjtFru6iBoXYyQReN53CMgX1epMD8Z66rqINxYY9gjlMAsOK7v0Hsk9Fu8N3QfXNzoYZ%2BH6JUcsH1bVtUfM9a60zbvlu1FqnoqWzzslS50u%2FyWXpfpHF84c1%2FgHp1epxDvs59HT8V56BpApzLZr%2B4FGcSpx3rKfbSvlm89uTCw6tXrYQZjTlxrHaKPo5QbemSan%2BVN3YRE4JMdv0vhP%2BS%2FIBjR%2B1BIjDnsZHPT6K39%2F4Oqw%2FlJWC9c8NNPsH%3C%2Fdiagram%3E%3C%2Fmxfile%3E6]L0IDATx^[MLJܠPWoBD6NB@sxr&Tr m7%>{SHRrB\5̹\ks=1~c|3G c/à W,{dx* R 'iZhӴ Rejs?P9YlR⬱"@VtڡTs4wwH9(jJJfART"H Q6JldP54پJ"8y$@qV+<&J59{gϚ-[VZ%dyٶmٱcСCbb0޹s9|ppT󴚪4J59hRMދ|_I{~s9:J5T۶mkg dT߿73g47nܰ X444دymݺnOn?~lM+q\bhQFٶϞ=+ȰfɺOzhȑ#/޽{cǎ=z1^ʕ+9s|7ėLUGtRA+6` ^O&t:tL0Ǽy|РAIJeͻw\uԩ:yK.5˗/bBnݺXQ˗/EJ>|xA|}mT|I >d>y7اO;.]ؾ %G\s!b>p34iRT>Ǯ]oi3y%fĢTOhA"I-U]׺dJAxrv%k|HVNnƊ꺧Tdvӷo߂ڲrusΝ k'kך77R=Z-k P[Su(hA?C:fͲ K[Lzf2oر6cė17 =c uJve\A\Bb޽f׮]%o 8RMBƯT/7{xTdR*cD&ױc@n2Uwdaƍ3O< Q4mʹd*%ϨL=R}9qٳgiݺuh֯_ooT9Ƿo… m-j\8pG޽|>!JM0e+ -5UgϞmN>%5UfF$47F,N26tMVjR+z4 ĐR%$ 2SRM2<\iӦK2ݻM˖- nby9|KbK`3zȑ]lքr{6j7]}@1λQ*Dկ7o^z {M6Ipդڮ];[9r9u4QWAu5w׬YcHp7?w3<|EŇIlT-S#2dgΜ ={FrweqxL81ȸ1ȠAqID2Ul"5wC ?qk׭[*LUd !TdR ,HSyOrWU* hp,YJ`СV"m۷A[}4~8p³T|HӧO63Æ#R (y&+7sqN"UIӨz""RuX}NZmTC8$:lIULj5j|~>)7J.FHuϟl*֛TH?HUoTbXҏԐ֔)S,Arn޼{}/(Ǒn;7](]=nlqW,SE 7<YT4YKU3<v6/2=LU)csS2U?,S78RB5ޏCfTZ-?ǚj>k5TERPW7PB>& ZjRSQ/USM"Uv9r`gGMREj|\FTE]zolA 6w<Vl?T]ǁ6a 'P oD7T\j>cT\xq}O?6#OJ:su!{̘17LZ2j}MX㴑s(4 jZjgk J)jZJF'ÎER'i* DT:&@J&P)U_$'(}ٳgfȐ!Yf }{us93qDC8:u2'O6׮] m}|n 2HkҤIѣGAbXD)a<#F0>}#Sձ!)Sqmۚ%KEf^l|̦M, _#1äTs=&UR|3g"ȫׯ_^zeϟokE.4/ :Ɔ(%^v~ZPB@wnA"dH_~V8?d/}AyDgzrS@ jqw…nFdnIvj &U*Gv +Ջ/Z<6DN/nM5nAgc>ﰚ;/^E2nw)@4HjcQaRaR~Q9r9zh%^1R^@bjKH?כlQu70) 7verQddZx,<:CN8/̋eaq"Nk Ur99g|j?0MxYԇTumuG_\B,;w QjX`0]_jZmڴ n-9%bT)jy2{xDBa"wZy޿.?P\YEI.~ܖ_Cϟ?7˗/S~ʛ 6l0gΜ וR_| j_$RGd)Ւx & YxY5@%O|KJH<T=d( THH#J#L" ;H)IENDB`jsoncons-1.3.2/doc/ref/csv/diagrams/basic_csv_options.png000066400000000000000000000257751477700171100235160ustar00rootroot00000000000000PNG  IHDRcbtEXtmxfile%3Cmxfile%20host%3D%22app.diagrams.net%22%20modified%3D%222020-03-31T16%3A36%3A09.669Z%22%20agent%3D%225.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F80.0.3987.149%20Safari%2F537.36%22%20etag%3D%22koZVZqufm5c5e1YCWLcL%22%20version%3D%2212.9.6%22%20type%3D%22device%22%3E%3Cdiagram%20id%3D%22yA7M8pUu49T19xTu_T4b%22%20name%3D%22Page-1%22%3EzVhdb9sgFP01ftxkmzhNHpuky%2FZQqVKkrdtLRc2tjYbBwiRx9usHNcRfSfOhKslTuIfLBZ97gEs8NM3KucR5%2BigIMC%2F0SemhmReGgY9G%2BscgmwoZjC2QSEqsUw0s6D9wIy26pASKlqMSgimat8FYcA6xamFYSrFuu70J1p41xwn0gEWMWR%2F9RYlKK3QU%2BTX%2BHWiSupkD3%2FZk2DlboEgxEesGhB48NJVCqKqVlVNghjzHSzXu257e7cIkcHXMgDv0lD7SeZT9%2FDOPAL%2Fmk5n4YqOsMFvaD37FBY1f4mL1InJFBS%2Fs6tXGUSLFkhMwUX0PTdYpVbDIcWx611oEGktVxrQV6GZ%2FlW5KkArKBmRXPQeRgZIb7WJ7I8eglVAwtPa6TkjgfNJGMgYWw1YDyTZ0TZNuWKZOYC38gDUCsd4EN0NeOOqQF%2B4gb3hJ8tAH5AG%2FafJC%2F9rkDQ7v15dYZJngVycPHbFr7y7JXdTjrscRcHJvLg1txQwXmtk2LVBS9WwZNO3fpv01stasbHTNNs7gevHPLoAxGqOMWQ97t9y4vSkoxFLGcHiHKSwTUIfFBKR1BfYT2shYtCNhDpPAsKKr9sW5K4t2hidB9Zft0wsKOjqoPtsOat5znTjdPTvsxKlo6cV5l9T2o89X2fA6KjtfLeFNqWB7TLhjA50pg%2B1Z7QKNLquD0Sfo4MyT47L6cVX5odPmtnQWBZ3j5lydRR3BhhfW2fh6OturmYNaQLelhe4Do5vCo7UQXFcLbvqGGH7wFCRVmOs9rF%2FhFCcSZz2F6JJOtTVRKCn%2BwlQwITXCBdeekzfKWAfCjCbcCEtrADQ%2BMQUi1e%2Fne9uRUULMNDsrznZNuldPpxSdUTsD4yPfiuHpVac269d7lcL6PxD08B8%3D%3C%2Fdiagram%3E%3C%2Fmxfile%3E4T IDATx^MV'`u Q *nTtUH(hAmH4 U]$b`EBJ.#]XnT FA&-0x9wBPޙs~ܙ{f{#### {8?cx1|z@SD16E~\9t12= d؃ {"qp0 1/€a|i=~*R HbAE`c^# P/&z:1re Ytb# L/Vec!K2Q2ce,:Bɰ# L/Vec!K2Q2ce,:Bɰ# L/Vec!K2Q2ce,:Bɰ# L/Vec!K2Q2ce,:Bɰ# L/Vec!K2Q2ce,:B k2|9p9}lf͚U.'~T'7.ͧh?y{nݺU7eʔ?x9yjOVӦM3L9tPG.y ;X3{A k2TzhQuHt;v,b$՝s-[D^"l`QbIy`b/}{YgϞ=ȑ#>M O?Eݻw/"l'{Ҿ͛7v-Z(gΜ1Uwy޼ys$ҤL){ǎQR>ڏmKamRۮj磶t\~Iv/[̈ L1Řk+[F7䗁/L0!6_~m~_?>6 GN-d1E=kE ǒE&vUΝ%2ʕ+K-W$鲫ڪKwT ]UD\,}ϼ$UiPXZĘTJ-"]a.Y~}GӖ3g/o>#s<)=b,P "L,Y++Z)/_mJvRR+W%bʘ׸̩SǏg.eUrwRŮhe,2fW:VƴJujVOrs޼y˗ǎ="Ƹ WF"$D2TvU::uQ{ RrVܞ1wVZKmuLJn̷ɲeoO mGڞ1O)Kt`U֬YgH?i=h17~螱81&Aݷ'p=c׮]3Kk̘1xuKJ1wD0bL4}>q'Kor(x:NL B)?@'9]g=8qD' N&ҫ}Tct44e~cz=M9iҤ贩?e#ms2N͘1yxە]vgϚW^ ˗GRJn/'N@`!`q+|!Wc=q2+̝;w\OA_1cex@I+kXJoe,{ʚ{YY4vwM={̞=L>gUK0c$<&PVk1ӊ_Uĸq$P$Tt2 .^5MlU>4?A b,?@tN " Tu"ǥ@u,`&'&0Uοߗy>\1r-hjRz2l]w@]A1 s $RdF4nu_Sݼhc9HIɰEtM_[WB@y @ۓDSa‹ 4moU 1HIɰEt!ϗÐ`gcs $dF4,Ϸ,Ob,Q|۞ [ ]{@ D2X0>2mo:,_>1#w@`dĿTʠ.!$[>oqv]y2c>$]7f8 H_|#u,EI+#`]p@ ~20%q1f:@ۃtliMb^^!#  AibR#_  P@A_I\<>$ؐ=M Fmg@ @[CS_zj dk@E@/jEcHg55=v8B?2F L'Uz0jjwڀ&PxR7Y_;qUQ݃fgc8 P@]KU_iiZhFu uJ@ T=ޔM3|c8FU@vU?EǿJ *H#M9b>C駟cBU` 6b,@ߠsgϞٳgӧ |-; g c^rcc#ъ+o.\hܹcruK ;^!Υ۷ͅ ̉'̸qJy9p9}ؖ-`k.sYիH-_?~l߾=oڴimIr+ʆcUίo߾5۶m36l0K,7ڌ?޺iMbh<O@k׮5k$3fٸqٻw/":I K%: 3U eRHM8|WfʕҥKQeŋQ5ƍQ&GD۷o.ڵkͦMrUvoݺvF-]4K{ᨊ^ 6پjpu~/_W~3ܹs^eҤIL#gMauqqr_xqTQ?9sL3Q̺OlK&Pۨ˗/9sd\Uy晗/_;vlTo-n #$QVD=ʼs=͟ǏUz{^Lc7soVz 1&L2+ɓ'+u6#jz&I _C1:* \;v.[,rPoݺ՜:uHO6GU tRe˖21/ɓHP GwڷM 'YIlDhݻ >ؒLyرQo޼9"rݹs;\zuسg#Ӗu㸈%=m8;$O&BpQHbhJ\I֙3gF~.2c @ LarIիU慛7o/wIH:ne޹4n~u7)j؟&9ӧ b/SeN=OTh?I:'oAZAL0 Xhi3u+WYٖmkCE,)*wL 3vQ{mϢEUlb,{/+mny^doIV6a„X_^oypq  VaĘ=^'͍⼎îS0!l;it/26Vyg̘1jˌ8ooGq u󀳫r7ٶ^rePfK1W.[ҮV]s{cv T5yTUglGN=d?\2f "41~f-R~s/+Ėʘ-拈=cҶ1.@]%P՞12fPܽ{wT#iuyΝ~ Bop7SN5? i}Y[{2$Ʋ|ZIK7kͲJŘQ6˞( =c%D} Om?? N=c.{ƒĘ(q]̻g,ݓ0U)ƲcR4ek!4ٮN]zMWY~ywWt̝;7ߞVl!{56In0_=6{XΩuϘLzelru{"Э<ŝ^H[L:=aR~&Ŭ58Þ[EOI\Nhe+c|YP{Tt3,f/c gL~ӔI| O2?M"{PEH:n~ObHV780)Ęle]¢I?㾁_y_ MF "bm : +|cvw1wy1EC/=]g}NE TeǣaPt uE@ 3XX ڛQUbАq@Mh6p$ k|j.ٰ-Gߠz0k :@=T=r#k 5%P`T Zo%Q/~YW;m݃QSj@D񏰶K1.z@SQӃh@[CS_x{=bMFm ݋ C |mMG/c~kR5=@{|y#߯cwm{0ePt1!בuLXgC?}| x ~2G-#Ny`ݩb,!]?EYm-|_ی}C1wz oaǭ䟯'962ր&;@}@0a]2 =+xh+|yd@e@ۓB[ah"M_[!Å Nw&$d(}[/"ce < hz@TFk} AcZ$$Rd"B1c AI0 xQ7nbGd =B) PU~t!&N1xqt I&P6~A2F@CNB(U忇H0 P#! e'a`bߑ#Ġ~h>w<(@@*bn7={ffϞmOnm&O\۷oͶm̆ ̒%KJ/^0֭3{mϟWabc߮]ٳgͫW"1|rsq}iӦ 4B  ˆ}'%ʚc}E>Bhl5]f֬YcD5fqH"Š B">@DY^1x:1|se3gΜhJ׹s^6mdN8aƍgn߾m.]}rJs%3~Q1!7nܓ% vZsA҇mŋͪUީ>|̚5+B%]On݊UZE4i_gc#ʘݖe)SDɓ'P;~jrqo߾C"q3/_:v(Cc =Le 422 իWG7oFرcs]ݙ;wٲeK%MH ,%'O &8]Wr>+ٳȉׯ~6aiS}AyH|%"pΝpxM]-9sQE/{EUĝ,D٭H{q{`i^ٽcǎ(frv?̅ ڿTْg3gF,wn WZ HLeYbl֭ԩS "EdsX=Rv/#ma$~3>k].}{m-"JrU{Ο?٥{~Yay{˖-3"'}i l1rvE0ڹ`4RR/̄ b߶ׯ_7Co#A b@] "Y2^KZN⊎<;Kdjm+W2(eSYQcG[hIFH?Wa%K{`Yc6Kqiеۍ_bR E+%>ׯLfiGV @c!G Y/_mJvRR+W%bʘ[r2Nj?~lT U*[ZS)miE/O4lVBc}P^)N=z޽{ t÷T\gV@PwucgL.{|Z`=cr}Ř콲!Dɟi=hI{~cwq8̞e^8 1= GIDO٧wf"{=ySqd S'}Y6sO%r[Ze,dr{rĉO>%ެ%JMѬӔz Ԏ69M'f̘Ή< .B b@0<$@I@1օ(a#Ji2+e[ypؕ*^;iEF5)@c5xI'1% W+^b, 0fu K!@E|@&CRM_ c]6B$&Òy>X`2$$@I@1օ(a#J`2, K J@ ȸ&CrM_ c]6B$&Òy>X`2$$@I@1օ(a#J`2, K J@ ȸ&CrM_ c]6B$&Òy>X`2$$@I@1օ(a#Jɐ mi{c^ @b, @^@y @ t# xM1ux0 B0A 5Ę8@B' =@c^ @b, @^@y @ t# xM1ux0 B0A 5Ę8@B' =@c^ @b, @^@y @ t# xM1ux0 B0A 5Ę8@B' =@c^ JJIDAT@b, @^@y @ t# xM1ux0 B0A 5Ę8@B' =@c^ @b, @^@y @ t# xM1ux0 B0A 5Ę8@B' =@c^ @b, @^@y @ t# xM1ux0 B0A 5Ę8@B' =@c^ @b, @^@y @ t# xM1ux0 B0A 5Ę8@B' =xlٲ8p̙3'ѢGE>}Lt%sMsQ{%Kl  B">@sM1E~ħbĉfܸqMvM_c [͘1#\M6۷/rСCf޽F+c/6۷o77/_Tn߾m.]=i&#F.i˗ѽ?͕+W̚5k?ϝ;7hgʔ)fݺuƍN4)_[n *Vbڵk'N`}o[իw*cv[n"֯_!O0رcbT9s>|8bC9|@ ƺ-l@G ĉ1qEԽ{͛#!%;wFBO?SuVs)c :%"D%-S3˖-͛QKbӬY̢EbK DJ.{RD"˸v[Ť,k&׿n)4XÇ81xc ]p!cW^ZLEwX~E, v]nms?w3ɓHh%ʿUn&mH>.v#@Uǒ qbLE+ (:Zr9|TAĘˠfZuеG>$6w˶Ҧ.;v,"Ib.1^UE1W<AJ"e/YKc'F+*cqSgD2fZY~b, :L1a:B 1f}Ṷ0c"HX\]K6{R|WgcǏ+sKci!ƺ`g_ i@cEYQ%nRϿHtݽ{7:(<'"'I՞G~?~l gLԓ4~tIT˔i_@ i@#ꗴi#n`& @<&n;<A XAp<@ "m@ c @b @ .zSIENDB`jsoncons-1.3.2/doc/ref/csv/encode_csv.md000066400000000000000000000245001477700171100201250ustar00rootroot00000000000000### jsoncons::csv::encode_csv Encodes a C++ data structure into the CSV data format. ```cpp #include template void encode_csv(const T& val, CharContainer& cont, const basic_csv_encode_options& options = basic_csv_encode_options()); (1) template void encode_csv(const T& val, std::basic_ostream& os, const basic_csv_encode_options& options = basic_csv_encode_options()); (2) template void encode_csv(const allocator_set& alloc_set, const T& val, CharContainer& cont, const basic_csv_encode_options& options = basic_csv_encode_options()); (3) (since 0.171.0) template void encode_csv(const allocator_set& alloc_set, const T& val, std::basic_ostream& os, const basic_csv_encode_options& options = basic_csv_encode_options()); (4) (since 0.171.0) ``` (1) Writes a value of type T into a character container in the CSV data format, using the specified (or defaulted) [options](basic_csv_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). (2) Writes a value of type T into an output stream in the CSV data format, using the specified (or defaulted) [options](basic_csv_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). Functions (3)-(4) are identical to (1)-(2) except an [allocator_set](../allocator_set.md) is passed as an additional argument. ### Examples [Encode a JSON array of "flat" objects (n_objects format)](#eg1) [Encode a JSON array of "flat" arrays (n_rows format)](#eg2) [Encode a JSON object of name-array members (m_columns format)](#eg3) [Encode a JSON array of objects to CSV with subfields](#eg4) [Encode nested JSON to CSV (since 1.2.0)](#eg5) [Encode nested JSON to CSV with column mapping (since 1.2.0)](#eg6)
```cpp #include #include #include #include namespace csv = jsoncons::csv; int main() { const std::string jtext = R"( [ { "customer_name": "John Roe", "has_coupon": true, "phone_number": "0272561313", "zip_code": "01001", "sales_tax_rate": 0.05, "total_amount": 431.65 }, { "customer_name": "Jane Doe", "has_coupon": false, "phone_number": "416-272-2561", "zip_code": "55416", "sales_tax_rate": 0.15, "total_amount": 480.7 }, { "customer_name": "Joe Bloggs", "has_coupon": false, "phone_number": "4162722561", "zip_code": "55416", "sales_tax_rate": 0.15, "total_amount": 300.7 }, { "customer_name": "John Smith", "has_coupon": false, "phone_number": null, "zip_code": "22313-1450", "sales_tax_rate": 0.15, "total_amount": 300.7 } ] )"; auto j = jsoncons::ojson::parse(jtext); std::string output; auto ioptions = csv::csv_options{} .quote_style(csv::quote_style_kind::nonnumeric); csv::encode_csv(j, output, ioptions); std::cout << output << "\n\n"; auto ooptions = csv::csv_options{} .assume_header(true); auto other = csv::decode_csv(output, ooptions); assert(other == j); } ``` Output: ``` customer_name,has_coupon,phone_number,zip_code,sales_tax_rate,total_amount "John Roe",true,"0272561313","01001",0.05,431.65 "Jane Doe",false,"416-272-2561","55416",0.15,480.7 "Joe Bloggs",false,"4162722561","55416",0.15,300.7 "John Smith",false,null,"22313-1450",0.15,300.7 ```
#### Encode a json array of arrays (n_rows format) ```cpp #include #include #include #include namespace csv = jsoncons::csv; int main() { const std::string jtext = R"( [ ["customer_name","has_coupon","phone_number","zip_code","sales_tax_rate","total_amount"], ["John Roe",true,"0272561313","01001",0.05,431.65], ["Jane Doe",false,"416-272-2561","55416",0.15,480.7], ["Joe Bloggs",false,"4162722561","55416",0.15,300.7], ["John Smith",false,null,"22313-1450",0.15,300.7] ] )"; auto j = jsoncons::json::parse(jtext); std::string output; auto ioptions = csv::csv_options{} .quote_style(csv::quote_style_kind::nonnumeric); csv::encode_csv(j, output, ioptions); std::cout << output << "\n\n"; auto ooptions = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_rows); auto other = csv::decode_csv(output, ooptions); assert(other == j); } ``` Output: ``` "customer_name","has_coupon","phone_number","zip_code","sales_tax_rate","total_amount" "John Roe",true,"0272561313","01001",0.05,431.65 "Jane Doe",false,"416-272-2561","55416",0.15,480.7 "Joe Bloggs",false,"4162722561","55416",0.15,300.7 "John Smith",false,null,"22313-1450",0.15,300.7 ```
#### Encode a json object of name-array members (m_columns format) ```cpp #include #include #include #include namespace csv = jsoncons::csv; int main() { const std::string jtext = R"( { "customer_name": ["John Roe","Jane Doe","Joe Bloggs","John Smith"], "has_coupon": [true,false,false,false], "phone_number": ["0272561313","416-272-2561","4162722561",null], "zip_code": ["01001","55416","55416","22313-1450"], "sales_tax_rate": [0.05,0.15,0.15,0.15], "total_amount": [431.65,480.7,300.7,300.7] } )"; auto j = jsoncons::ojson::parse(jtext); std::string output; auto ioptions = csv::csv_options{} .quote_style(csv::quote_style_kind::nonnumeric); csv::encode_csv(j, output, ioptions); std::cout << output << "\n\n"; auto ooptions = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::m_columns); auto other = csv::decode_csv(output, ooptions); assert(other == j); } ``` Output: ``` customer_name,has_coupon,phone_number,zip_code,sales_tax_rate,total_amount "John Roe",true,"0272561313","01001",0.05,431.65 "Jane Doe",false,"416-272-2561","55416",0.15,480.7 "Joe Bloggs",false,"4162722561","55416",0.15,300.7 "John Smith",false,null,"22313-1450",0.15,300.7 ```
#### Encode a JSON array of objects to CSV with subfields ```cpp #include #include #include #include namespace csv = jsoncons::csv; int main() { std::string jtext = R"( [ { "calculationPeriodCenters": ["NY","LON"], "paymentCenters": "TOR", "resetCenters": "LON" }, { "calculationPeriodCenters": "NY", "paymentCenters": "LON", "resetCenters": ["TOR","LON"] }, { "calculationPeriodCenters": ["NY","LON"], "paymentCenters": "TOR", "resetCenters": "LON" }, { "calculationPeriodCenters": "NY", "paymentCenters": "LON", "resetCenters": ["TOR","LON"] } ] )"; auto j = jsoncons::ojson::parse(jtext); auto options = csv::csv_options{} .subfield_delimiter(';'); std::string buf; csv::encode_csv(j, buf, options); std::cout << buf << "\n"; } ``` Output: ``` NY;LON,TOR,LON NY,LON,TOR;LON NY;LON,TOR,LON NY,LON,TOR;LON ```
#### Encode nested JSON to CSV (since 1.2.0) ```cpp #include #include #include #include namespace csv = jsoncons::csv; int main() { std::string jtext = R"( [ { "text": "Chicago Reader", "float": 1.0, "datetime": "1971-01-01T04:14:00", "boolean": true, "nested": { "time": "04:14:00", "nested": { "date": "1971-01-01", "integer": 40 } } }, { "text": "Chicago Sun-Times", "float": 1.27, "datetime": "1948-01-01T14:57:13", "boolean": true, "nested": { "time": "14:57:13", "nested": { "date": "1948-01-01", "integer": 63 } } } ] )"; auto j = jsoncons::ojson::parse(jtext); auto options = csv::csv_options{} .flat(false); std::string buf; csv::encode_csv(j, buf, options); std::cout << buf << "\n"; } ``` Output: ``` /text,/float,/datetime,/boolean,/nested/time,/nested/nested/date,/nested/nested/integer Chicago Reader,1.0,1971-01-01T04:14:00,true,04:14:00,1971-01-01,40 Chicago Sun-Times,1.27,1948-01-01T14:57:13,true,14:57:13,1948-01-01,63 ```
#### Encode nested JSON to CSV with column mapping (since 1.2.0) ```cpp #include #include #include #include namespace csv = jsoncons::csv; int main() { std::string jtext = R"( [ { "text": "Chicago Reader", "float": 1.0, "datetime": "1971-01-01T04:14:00", "boolean": true, "nested": { "time": "04:14:00", "nested": { "date": "1971-01-01", "integer": 40 } } }, { "text": "Chicago Sun-Times", "float": 1.27, "datetime": "1948-01-01T14:57:13", "boolean": true, "nested": { "time": "14:57:13", "nested": { "date": "1948-01-01", "integer": 63 } } } ] )"; auto j = jsoncons::ojson::parse(jtext); auto options = csv::csv_options{} .flat(false) .column_mapping({ {"/datetime","Timestamp"}, {"/text", "Newspaper"}, {"/nested/nested/integer","Count"} }); std::string buf; csv::encode_csv(j, buf, options); std::cout << buf << "\n"; } ``` Output: ``` Timestamp,Newspaper,Count 1971-01-01T04:14:00,Chicago Reader,40 1948-01-01T14:57:13,Chicago Sun-Times,63 ``` jsoncons-1.3.2/doc/ref/csv/quote_style_kind.md000066400000000000000000000007111477700171100213750ustar00rootroot00000000000000### jsoncons::csv::quote_style_kind ```cpp #include enum class quote_style_kind { minimal, all, nonnumeric, none }; ``` Value |Definition -----------|----------- minimal | Only quote fields that contain special characters, such as a line, field or subfield delimiter, or a quote character. all | Quote all fields nonnumeric | Quote all non-numeric fields none | Never quote fields jsoncons-1.3.2/doc/ref/deprecated.md000066400000000000000000000022521477700171100173220ustar00rootroot00000000000000## Deprecated Features As the `jsoncons` library has evolved, names have sometimes changed. To ease transition, jsoncons deprecates the old names but continues to support many of them. The deprecated names can be suppressed by defining macro JSONCONS_NO_DEPRECATED, which is recommended for new code. Category/class|Old name|Replacement --------|-----------|-------------- __corelib__| |  `basic_json_parser`| |   |`basic_json_parser(std::function, const TempAllocator&`|Set error handler in options  |`basic_json_parser(const basic_json_decode_options&,std::function, const TempAllocator&`|Set error handler in options  |`void update(string_view_type)`|Use `set_buffer` once or provide a chunk reader  |`void update(const char_type*, std::size_t)`|Use `set_buffer` once or provide a chunk reader `basic_json_reader`| |   |Constructors with `err_handler` parameter|Set `err_handler` in options instead `basic_json_options`| |   |`bigint_chars_format`|`bignum_chars_format`  |`bigint_chars_format::number`|`bignum_chars_format::raw` jsoncons-1.3.2/doc/ref/jmespath/000077500000000000000000000000001477700171100165125ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/jmespath/diagrams/000077500000000000000000000000001477700171100203015ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/jmespath/diagrams/jmespath_error.png000066400000000000000000000225231477700171100240370ustar00rootroot00000000000000PNG  IHDRptEXtmxfile%3Cmxfile%20modified%3D%222020-03-24T19%3A37%3A28.758Z%22%20host%3D%22app.diagrams.net%22%20agent%3D%22Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F80.0.3987.149%20Safari%2F537.36%22%20etag%3D%22sT_BTJLY1iuQgoSmLSYb%22%20version%3D%2212.9.2%22%20type%3D%22device%22%3E%3Cdiagram%20id%3D%22iK-0d-7Yl-5MlnfMu26I%22%20name%3D%22Page-1%22%3E7VhrT9swFP01%2FcjUxGlpP0JhbItAY0UqfEImuSTeHLs4bpvu188mzsNJymOKKHugSvge29fO8Tm3TgdolmRnAi%2Fjcx4CHbjDMBugk4HrOkM0Uf80ss0Rb2qASJDQDKqAOfkJxUyDrkgIqTVQck4lWdpgwBmDQFoYFoJv7GH3nNqrLnEELWAeYNpGFySUcY5ORsMK%2FwQkiouVnaHpSXAx2ABpjEO%2BqUHodIBmgnOZt5JsBlSTV%2FCSz%2Fu4o7fcmAAmXzLh9OIqY%2F7lPHZnD75cnCc32ZcDk2WN6co8cCrV%2BCP1gSyApSScme3LbcGJ4CsWgk47HKDjTUwkzJc40L0bpQKFxTKhKnJUs73NYk0QErIaZLZ9BjwBKbZqiOkdGwaNhKYm3FTnUbIe187CMxg2EojKxBVLqmGIegVph7tJEysmSQK3oKQn9k6cO3xnzE1azLU4AhYead%2BqKKA4TUlg0wIZkdeGQd2%2B0e0PIxOdZLWuk20RMLX56yKBDmqzdFhNe4yKeTuPIOUrEcDzEpFYRCCf9x%2BEVhVqH2jtxEYdB1ZgAiiWZG3Xrq5TNCt85UQ9WakXz5ZLKZ8iQ%2F7YZlK91DTyTO08zqiRJ6elledRUuVDv0hl0fo8dv2La%2FwNooPFpQ9rH54qauk2lZC8E3sib3%2F27CTO%2FQvt%2BZRCnrXn4X979m9P1FLZ95Szpbov9eHLe0LpjFOVRs9F8Pin8FQK%2FgNqPWiMpijsx8mjxhet4%2B7byuN%2FxcqobeWnLP9OrIwad9ryjvtaL3tOI5HztmZu34U%2FsxgEkZipY1PvfQRHAict8SljSVtutkEZZ9Bws4EwJRHTmlVSAYUfa5sS9cZ2ZDoSEoZ6mc5KYdeSHqzffDtxu6yPOpTk9mF9fMc8zoP7q2yMvYfEX5z5HdcfXV9ve32fa%2FHTweKL7z3lF9CbVMsuyv7Ii0%2BjlPVXPneKam8Xn8OGxya%2FWS1HbiMR6qtaqrD6KScfXv0ghk5%2FAQ%3D%3D%3C%2Fdiagram%3E%3C%2Fmxfile%3EQ10IDATx^mUǹ'Ԓ*X!@11E"Fbҫ?TM 4D?m$~4FE 1/DCM0!Z"F!J+ -}\}6sV{u֬~ 3k3=3k܀2E``$7p)VB!`9_􃲽I@fЎx2[z|v&zX촂vhj$c[gLXz|2z`:n}P19c]EXaL0&Az|u=] c 1AØ3z8_t5i`8c[gLXz|2z`:n}P19c]EXaL0&Az|u=] c 1AØ3z8_t5i`8c[gLXz|2z`:n}P19c]EXaL0&Az|u=] c 1AØ3z8_t5i`8c[gLXz|2z`:n}P19c]EXaLSt[t۰a8q uֹӧE}Ν;ݗ_~yѕiPz{SO=UI,2h ܎?6ob3[*D|NVrFb?~>[0 =: ~UHnPeK/}kUҶ, n-QE,ꢡ&(l:=M6+W˗ݻwI&qƵ^[x;_;$?Yȧ3f۷'N{?);wקN4cǎ5&)d4m4bŊVcƌn>fϞ6n^y!%JcǎCʛTᠠfC<00 s=|ɼՖV>/rsPty湓'O\*IJyseG;p[p5\QQFS%Ҵ<}ϥo~n֭^kkɒ%>F~m_KK+u몎%>7w\ /~;h[Jb \ +9#m{E'&]O3UZkΥi)j)X#ai$07œ\Qc#lE⎕3ɭpǤnkJx}/9%F?fΜq\t9rҶ?o|ErH@5Rw;#FDh7tؾ#Ldo9y#I&ȧ&Xtt%K$"f7ȪKr t"˖jLP0_:\I'zr1m#yf%/44rƮ/OXtJ̙N;a8k,a!R4̇H>YOus!U犚96rȶㆬ}u?+Wh <ː_*hӡ%p%퀪.[%%DN:hӑtٶm7>qM7yTْWbܒmӑfX҉\s蔋t(+'aIr,J|cnk鶬#G,Z'MGP#9ZtNns?׿z!w:cM2 DxVc(+Y.d~743OdiYkJ2M$Ÿ)(tz0i6&$DXJF'\MK$ҋ"3I=mFI.NQ;W4_d;trFHooUKNRN+׮]k LZm$X*DnLӓYM| }H~/+gn+5V^_o怎9C1Wױs%4ի|9>ew;yo}#ִz ^Ge>Zz|uVW_uiXeI=xsnl|TJtTMY r.Z.~R-ZQw|p˸hyk\/^&LnVwԩVW1EUni:Aun=n߭a=~ˇnilu~[r?Wn|t#t%Az|1Wu=gNYU0&vAnX*VڱXUCQRØCbwz|o~zXϚ)K^1˿FJ9 `:r]A!VoZz|VuWzX7b:cޜӑZe ek=k>zXϺeKQv >LE;֠PV+Ru=+:gl=LGYSN=r8ZKAaZoa=^{VjƔ{?\VՠP4XWg]EZhĹjzP|ң.ț!qc:-T{]B`ǗRκ<ڏ|`:fF50pJ݃B`-~u=oЭ?V|`:eDtT;SkV`Ǘ r(2uŚ#SZTVe:*k2TB2hq"@z4%tFo:,f-ND@(|`:*-G( @(|`:+k+(@tT.Y1 @hCtJ'L-=:k>0 aK sfrՇw_e<.o[nůL4ٳ߷{n裏r߃>b{ &9rķO_nʔ)nڵolO/}9[Vq?kKRU~>JZ?e:u۲e7IcV:2a #us?2a~BK& zs!f@`41x/wIodb!F{'.\hM2 nY į~+>A+bd&|O.1Lbn_1BrI}w5!b8:Sfz1RB K>SxbߟuoLG8[b@t@ ĥK$+b Ο?2ZR;Nw PIX.tq "ѣb$3/C `@r㿎w4qKCdL?5 b#<pGO~vCVNV;QtMxI_AS&#O?$#-BI1thG+\d:tCǍ7tZ(b:%Aڭd$yӑe!@2^ ٚͅ׳d:ЭpKfĈGX.,+ROxCkdt;m%-I0>@Yt3ZGѧW >>mNC"It<"4<"K^׳n}ɧWV:ެ̢tEY@@V1TQ旃Yұ:tI!@ f#Oyw"K1MG;>xge0UP @(Dk: M `:r#@M`f[bc:q.@@, N Ub:JH@:8p"000`+ \faNbæ.D! $7svĚ#gbTTQh@S X䚪ۊfc:lBTV&:ĎԭGUf1Dt;#XIIKfc:lBTuMr}TG]fQrT$T'P$ TGfa鰩 QAoT5 鈜Htm@6'lQPJ ÚtyLM] }C $7*HzX5+cs(#P$W, *{úM"p_hK@tszٰEhBF`\ZqQ=0 MtDJ? @;=}Yw7{+b6Z1MVC 2LGd9OqE7aw뭷SNjlK0QQKӑXI=x)S> b>n`:zI-b@j:Μ96lvFc,n/z^ڽʕ+t_v+V;XǸ `:H@ #Z+h;w~'4l0h"n:̆0"}QYMG81-_޽ꭷr??~͘1xb}vOׯoڴOݮv8qݻ=|po>wܹV}7ons17}t?y1گiӦՃI&1c>>|͞=mܸѽ+D9qw˗/x㍾o~ @aF8tPkt[v',d b޼yn׮]n-rJ\b4,YO'NL Q e܎;ܸqZY!ל9s4 Q2rɽb}yMb~GߤޣG8/\R Wg@ۼ6!ݤ(DQ7AY tmd@g̙3K  ~igq'Oj… zI{Үd9YPc#z%4O.ISO#Gիv?яK&ȍ 9Hn #ita۶m{Sxw0=. C2"COv$驎"qXnYNO֤=O轣FO7]#myzH?5Ga9 `:z[?iY': pU*F3 `:;@%Lr :(#8ekC@I^rP3I{U#f,GaG_ӝt|lhb4&N!P&@gl=2X4hh`aK&Fh`tf##(E#鈆!&9[9hb4&N!P&@gl=2X4hh`aK&Fh`tf##(E#鈆!&9[9hb4&N!P&@gl=2X4hh`aK&Fh`tf##(E#鈆!l4QrY@@}0e@@`:%7 GQ{Z 4QrY@@}0e@@`:%7 GQ{Z 4QrY@@}0e@@`:%7 GQ{Z 4QrY@@}0e@@`:%7 GQ{Z 4QrY@@}0e@@`:%7 GQ{Z 4QrY@@}0e@@`:%7 GQ{Z 4QrY@@}0e@@`:%7 GQ{Z 4QrY@@}0e@@`:%7 GQ{Z 4QrY@@}0e@@`:%7 GQ{ZC.]rK.u6lp'NL3g|;wѣG"qu|rpBwwdjPCoڷo;z۲e[fsk6@`:AE`@#tvcnU6M[QVo'qcǺmڴɭ[JǴi܊+ܤI[#Ǐw3f,^-we_wps޽UϘ1cÇ۶;j(_^cǎV $y湓'O.vFBI+W|e#+پ ~#Gt+WoWVv:/k.yfBfv5z53'N%Kx LVL_|/wl2c|ĈqI^{fΜ#ujڵkh$ǻSGb/5,2O<1Cl?!a4vLZwi166t4Fj:ZvC'oK8ʧ{zqAB%o:yk}YtdmWLb$IXrדq;ӑs缡Kڕth:v!uZ܂"'i`:,A,=O699Il1ٳݞ={t$0tFnhv}H#`I AN>ڶmo"t%k0=}Fgҝz e:OڣdȶCЭ \Vi] jmespath_expression Represents the compiled form of a JMESPath string. ### Functions
search Searches for all values that match a JMESPath expression
make_expression Returns a compiled JMESPath expression for later evaluation. (since 0.159.0)
### Examples [search function](#eg1) [jmespath_expression](#eg2) [custom_functions (since 1.0.0)](#eg3) [JMESPath Lexical Scoping using the new let expression (since 1.3.0)](#eg4) [Late binding of variables to an initial (global) scope via parameters (since 1.3.0)](#eg5)
#### search function [jsoncons::jmespath::search](search.md) takes two arguments, a [basic_json](../basic_json.md) and a JMESPath expression string, and returns a `basic_json` result. This is the simplest way to compile and evaluate a JMESPath expression. ```cpp #include #include using jsoncons::json; namespace jmespath = jsoncons::jmespath; int main() { // This examples is from the JMESPath front page std::string jtext = R"( { "locations": [ {"name": "Seattle", "state": "WA"}, {"name": "New York", "state": "NY"}, {"name": "Bellevue", "state": "WA"}, {"name": "Olympia", "state": "WA"} ] } )"; std::string expr = "locations[?state == 'WA'].name | sort(@) | {WashingtonCities: join(', ', @)}"; json doc = json::parse(jtext); json result = jmespath::search(doc, expr); std::cout << pretty_print(result) << "\n\n"; } ``` Output: ``` { "WashingtonCities": "Bellevue, Olympia, Seattle" } ``` Credit to [JMESPath](https://jmespath.org/) for this example
#### jmespath_expression A [jsoncons::jmespath::jmespath_expression](jmespath_expression.md) represents the compiled form of a JMESPath string. It allows you to evaluate a single compiled expression on multiple JSON documents. A `jmespath_expression` is immutable and thread-safe. ```cpp #include #include using jsoncons::json; namespace jmespath = jsoncons::jmespath; int main() { std::string jtext = R"( { "people": [ { "age": 20, "other": "foo", "name": "Bob" }, { "age": 25, "other": "bar", "name": "Fred" }, { "age": 30, "other": "baz", "name": "George" } ] } )"; // auto expr = jmespath::jmespath_expression::compile("people[?age > `20`].[name, age]"); // until 0.159.0 auto expr = jmespath::make_expression("people[?age > `20`].[name, age]"); // since 0.159.0 json doc = json::parse(jtext); json result = expr.evaluate(doc); std::cout << pretty_print(result) << "\n\n"; } ``` Output: ``` [ ["Fred", 25], ["George", 30] ] ``` Credit to [JMESPath Tutorial](https://jmespath.org/tutorial.html) for this Example
#### custom_functions (since 1.0.0) ```cpp #include #include #include #include #include namespace jmespath = jsoncons::jmespath; // When adding custom functions, they are generally placed in their own project's source code and namespace. namespace myspace { template class my_custom_functions : public jmespath::custom_functions { using reference = const Json&; using pointer = const Json*; static thread_local size_t current_index; public: my_custom_functions() { this->register_function("current_index", // function name 0, // number of arguments [](const jsoncons::span> params, jmespath::eval_context& context, std::error_code& ec) -> Json { return Json{current_index}; } ); this->register_function("generate_array", // function name 4, // number of arguments [](const jsoncons::span> params, jmespath::eval_context& context, std::error_code& ec) -> Json { JSONCONS_ASSERT(4 == params.size()); if (!(params[0].is_value() && params[2].is_expression())) { ec = jmespath::jmespath_errc::invalid_argument; return context.null_value(); } reference ctx = params[0].value(); reference countValue = get_value(ctx, context, params[1]); const auto& expr = params[2].expression(); const auto& argDefault = params[3]; if (!countValue.is_number()) { ec = jmespath::jmespath_errc::invalid_argument; return context.null_value(); } Json result{jsoncons::json_array_arg}; int count = countValue.template as(); for (size_t i = 0; i < count; i++) { current_index = i; std::error_code ec2; reference ele = expr.evaluate(ctx, context, ec2); if (ele.is_null()) { auto defaultVal = get_value(ctx, context, argDefault); result.emplace_back(std::move(defaultVal)); } else { result.emplace_back(ele); } } current_index = 0; return result; } ); this->register_function("add", // function name 2, // number of arguments [](jsoncons::span> params, jmespath::eval_context& context, std::error_code& ec) -> Json { JSONCONS_ASSERT(2 == params.size()); if (!(params[0].is_value() && params[1].is_value())) { ec = jmespath::jmespath_errc::invalid_argument; return context.null_value(); } reference arg0 = params[0].value(); reference arg1 = params[1].value(); if (!(arg0.is_number() && arg1.is_number())) { ec = jmespath::jmespath_errc::invalid_argument; return context.null_value(); } if (arg0.is() && arg1.is()) { int64_t v = arg0.template as() + arg1.template as(); return Json(v); } else { double v = arg0.template as() + arg1.template as(); return Json(v); } } ); } static reference get_value(reference ctx, jmespath::eval_context& context, const jmespath::parameter& param) { if (param.is_expression()) { const auto& expr = param.expression(); std::error_code ec; return expr.evaluate(ctx, context, ec); } else { return param.value(); } } }; template thread_local size_t my_custom_functions::current_index = 0; } // namespace myspace using json = jsoncons::json; int main() { std::string jtext = R"( { "devices": [ { "position": 1, "id": "id-xxx", "state": 1 }, { "position": 5, "id": "id-yyy", "state": 1 }, { "position": 9, "id": "id-mmm", "state": 2 } ] } )"; auto expr = jmespath::make_expression("generate_array(devices, `16`, &[?position==add(current_index(), `1`)] | [0], &{id: '', state: `0`, position: add(current_index(), `1`)})", myspace::my_custom_functions{}); auto doc = json::parse(jtext); auto result = expr.evaluate(doc); auto options = jsoncons::json_options{} .array_object_line_splits(jsoncons::line_split_kind::same_line); std::cout << pretty_print(result, options) << "\n\n"; } ``` Output: ```json [ {"id": "id-xxx", "position": 1, "state": 1}, {"id": "", "position": 2, "state": 0}, {"id": "", "position": 3, "state": 0}, {"id": "", "position": 4, "state": 0}, {"id": "id-yyy", "position": 5, "state": 1}, {"id": "", "position": 6, "state": 0}, {"id": "", "position": 7, "state": 0}, {"id": "", "position": 8, "state": 0}, {"id": "id-mmm", "position": 9, "state": 2}, {"id": "", "position": 10, "state": 0}, {"id": "", "position": 11, "state": 0}, {"id": "", "position": 12, "state": 0}, {"id": "", "position": 13, "state": 0}, {"id": "", "position": 14, "state": 0}, {"id": "", "position": 15, "state": 0}, {"id": "", "position": 16, "state": 0} ] ``` Credit to [PR #560](https://github.com/danielaparker/jsoncons/pull/560) for this example
#### JMESPath Lexical Scoping using the new let expression (since 1.3.0) ```cpp #include #include #include using jsoncons::json; namespace jmespath = jsoncons::jmespath; int main() { auto doc = json::parse(R"( [ {"home_state": "WA", "states": [ {"name": "WA", "cities": ["Seattle", "Bellevue", "Olympia"]}, {"name": "CA", "cities": ["Los Angeles", "San Francisco"]}, {"name": "NY", "cities": ["New York City", "Albany"]} ] }, {"home_state": "NY", "states": [ {"name": "WA", "cities": ["Seattle", "Bellevue", "Olympia"]}, {"name": "CA", "cities": ["Los Angeles", "San Francisco"]}, {"name": "NY", "cities": ["New York City", "Albany"]} ] } ] )"); std::string query = R"([*].[let $home_state = home_state in states[? name == $home_state].cities[]][])"; auto expr = jmespath::make_expression(query); json result = expr.evaluate(doc); auto options = jsoncons::json_options{} .array_array_line_splits(jsoncons::line_split_kind::same_line); std::cout << pretty_print(result, options) << "\n"; ``` Output: ```json [ ["Seattle", "Bellevue", "Olympia"], ["New York City", "Albany"] ] ``` Credit to [JEP: 18 Lexical Scoping](https://github.com/jmespath/jmespath.jep/blob/main/proposals/0018-lexical-scope.md) for this example
#### Late binding of variables to an initial (global) scope via parameters (since 1.3.0) ```cpp #include #include #include using jsoncons::json; namespace jmespath = jsoncons::jmespath; int main() { auto doc = json::parse(R"( { "results": [ { "name": "test1", "uuid": "33bb9554-c616-42e6-a9c6-88d3bba4221c" }, { "name": "test2", "uuid": "acde070d-8c4c-4f0d-9d8a-162843c10333" } ] } )"); auto expr = jmespath::make_expression("results[*].[name, uuid, $hostname]"); std::map params{ {"hostname", "localhost"} }; // (since 1.3.1) auto result = expr.evaluate(doc, params); auto options = jsoncons::json_options{} .array_array_line_splits(jsoncons::line_split_kind::same_line); std::cout << pretty_print(result) << "\n"; } ``` Output: ```json [ [ "test1", "33bb9554-c616-42e6-a9c6-88d3bba4221c", "localhost" ], [ "test2", "acde070d-8c4c-4f0d-9d8a-162843c10333", "localhost" ] ] ``` Credit to [JEP: 18 Lexical Scoping](https://github.com/jmespath/jmespath.jep/blob/main/proposals/0018-lexical-scope.md) for this example jsoncons-1.3.2/doc/ref/jmespath/jmespath_errc.md000066400000000000000000000045041477700171100216650ustar00rootroot00000000000000### jsoncons::jmespath::jmespath_errc ```cpp #include ```
The constant integer values scoped by `jmespath_errc` define the values for jmespath error codes. ### Member constants constant |Description ------------------------------------|------------------------------ `expected_identifier` | Expected identifier `expected_index` | Expected index `expected_A_Za_Z_` | Expected A-Z, a-z, or _ `expected_rbracket` | Expected ] `expected_rbrace` | Expected } `expected_colon` | Expected : `expected_dot` | Expected \".\" `expected_or` | Expected \"\|\|\" `expected_and` | Expected \"&&\" `expected_multi_select_list` | Expected multi-select-list `invalid_number` | Invalid number `invalid_literal` | Invalid literal `expected_comparator` | Expected <, <=, ==, >=, > or != `expected_key` | Expected key `invalid_argument` | Invalid argument type `unknown_function` | Unknown function `invalid_type` | Invalid type `unexpected_end_of_input` | Unexpected end of jmespath input `step_cannot_be_zero` | Slice step cannot be zero `syntax_error` | Syntax error `invalid_codepoint` | Invalid codepoint `illegal_escaped_character` | Illegal escaped character `unbalanced_parentheses` | Unbalanced parentheses `invalid_arity` | Function called with wrong number of arguments jsoncons-1.3.2/doc/ref/jmespath/jmespath_error.md000066400000000000000000000017631477700171100220670ustar00rootroot00000000000000### jsoncons::jmespath::jmespath_error ```cpp #include ```
`jsoncons::jmespath::jmespath_error` defines an exception type for reporting failures in jmespath queries. ![jmespath_error](./diagrams/jmespath_error.png) #### Constructors ```cpp jmespath_error(std::error_code ec); jmespath_error(std::error_code ec, std::size_t line, std::size_t column); jmespath_error(const jmespath_error& other); ``` #### Member functions std::size_t line() const noexcept Returns the line number to the end of the text where the exception occurred. Line numbers start at 1. std::size_t column() const noexcept Returns the column number to the end of the text where the exception occurred. Column numbers start at 1. const char* what() const noexcept Constructs an error message, including line and column position #### Inherited from std::system_error const std::error_code code() const noexcept Returns an error code for this exception ### Example jsoncons-1.3.2/doc/ref/jmespath/jmespath_expression.md000066400000000000000000000037131477700171100231320ustar00rootroot00000000000000### jsoncons::jmespath::jmespath_expression ```cpp #include template class jmespath_expression ``` #### Member types Type |Definition ---------------------------|------------------------------ char_type |Json::char_type string_type |std::basic_json #### Member functions Json evaluate(reference doc) const; (1) Json evaluate(reference doc, const std::vector>& params) const; (until 1.3.1) (2) Json evaluate(reference doc, const std::map& params) const; (since 1.3.1) Json evaluate(reference doc, std::error_code& ec) const; (3) Json evaluate(reference doc, const std::vector>& params, (until 1.3.1) std::error_code& ec) const; (4) Json evaluate(reference doc, const std::map& params, (since 1.3.1) std::error_code& ec) const; #### Parameters
doc Json value
params List of parameters to be provided to an initial (global) scope when the query is evaluated
ec out-parameter for reporting errors in the non-throwing overload
#### Exceptions (1),(3) Throws a [jmespath_error](jmespath_error.md) if JMESPath evaluation fails. (2),(4) Sets the out-parameter `ec` to the [jmespath_error_category](jmespath_errc.md) if JMESPath evaluation fails. jsoncons-1.3.2/doc/ref/jmespath/make_expression.md000066400000000000000000000030101477700171100222220ustar00rootroot00000000000000### jsoncons::jmespath::make_expression ```cpp #include template jmespath_expression make_expression(const json::string_view_type& expr); (until 1.0.0) (1) template jmespath_expression make_expression(const Json::string_view_type& expr, (since 1.0.0) const custom_functions& funcs = custom_functions()); template jmespath_expression make_expression(const json::string_view_type& expr, (2) std::error_code& ec); template jmespath_expression make_expression(const Json::string_view_type& expr, (3) (since 1.0.0) const custom_functions& funcs, std::error_code& ec) ``` Returns a compiled JMESPath expression for later evaluation. #### Parameters
expr JMESPath expression
funcs Custom functions
ec out-parameter for reporting errors in the non-throwing overload
#### Return value Returns a `jmespath_expression` object that represents the JMESPath expression. #### Exceptions (1) Throws a [jmespath_error](jmespath_error.md) if JMESPath compilation fails. (2) Sets the out-parameter `ec` to the [jmespath_error_category](jmespath_errc.md) if JMESPath compilation fails. jsoncons-1.3.2/doc/ref/jmespath/search.md000066400000000000000000000015421477700171100203030ustar00rootroot00000000000000### jsoncons::jmespath::search ```cpp #include template Json search(const Json& doc, const Json::string_view_type& expr); (1) template Json search(const Json& doc, const Json::string_view_type& expr, std::error_code& ec); (2) ``` Returns a Json value. #### Parameters
doc Json value
expr JMESPath expression
ec out-parameter for reporting errors in the non-throwing overload
#### Return value Returns a Json value. #### Exceptions (1) Throws a [jmespath_error](jmespath_error.md) if JMESPath evaluation fails. (2) Sets the out-parameter `ec` to the [jmespath_error_category](jmespath_errc.md) if JMESPath evaluation fails. jsoncons-1.3.2/doc/ref/jsonpatch/000077500000000000000000000000001477700171100166705ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/jsonpatch/apply_patch.md000066400000000000000000000041431477700171100215200ustar00rootroot00000000000000### jsoncons::jsonpatch::apply_patch ```cpp #include template void apply_patch(Json& target, const Json& patch); (1) template void apply_patch(Json& target, const Json& patch, std::error_code& ec); (2) ``` Applies a patch to a `json` document. #### Return value None #### Exceptions (1) Throws a [jsonpatch_error](jsonpatch_error.md) if `apply_patch` fails. (2) Sets the out-parameter `ec` to the [jsonpatch_error_category](jsonpatch_errc.md) if `apply_patch` fails. ### Examples #### Apply a JSON Patch with two add operations ```cpp #include #include using jsoncons::json; namespace jsonpatch = jsoncons::jsonpatch; int main() { json doc = json::parse(R"( { "foo": "bar"} )"); json patch = json::parse(R"( [ { "op": "add", "path": "/baz", "value": "qux" }, { "op": "add", "path": "/foo", "value": [ "bar", "baz" ] } ] )"); std::error_code ec; jsonpatch::apply_patch(target,patch,ec); std::cout << pretty_print(target) << '\n'; } ``` Output: ``` { "baz": "qux", "foo": ["bar","baz"] } ``` #### Apply a JSON Patch with three add operations, the last one fails ```cpp #include #include using jsoncons::json; namespace jsonpatch = jsoncons::jsonpatch; int main() { json target = json::parse(R"( { "foo": "bar"} )"); json patch = json::parse(R"( [ { "op": "add", "path": "/baz", "value": "qux" }, { "op": "add", "path": "/foo", "value": [ "bar", "baz" ] }, { "op": "add", "path": "/baz/bat", "value": "qux" } // nonexistent target ] )"); std::error_code ec; jsonpatch::apply_patch(target, patch, ec); std::cout << "(1) " << ec.message() << '\n'; std::cout << "(2) " << target << '\n'; } ``` Output: ``` (1) JSON Patch add operation failed (2) {"foo":"bar"} ``` Note that all JSON Patch operations have been rolled back, and target is in its original state. jsoncons-1.3.2/doc/ref/jsonpatch/diagrams/000077500000000000000000000000001477700171100204575ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/jsonpatch/diagrams/jsonpatch_error.png000066400000000000000000000226141477700171100243740ustar00rootroot00000000000000PNG  IHDRptEXtmxfile%3Cmxfile%20modified%3D%222020-03-24T19%3A31%3A26.078Z%22%20host%3D%22app.diagrams.net%22%20agent%3D%22Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F80.0.3987.149%20Safari%2F537.36%22%20etag%3D%22bbMrqHqXRbeoEAMBTKFk%22%20version%3D%2212.9.2%22%20type%3D%22device%22%3E%3Cdiagram%20id%3D%22iK-0d-7Yl-5MlnfMu26I%22%20name%3D%22Page-1%22%3E7VhdT9swFP01fWRq4hboYykMWAcaFKnwhKzkknhz7M5x23S%2FfjZxPhynULSIom1VpdrH9nVy7jnXSXtokmTnAi%2FiKx4C7fn9MOuh057ve310rH40ssmRwcgAkSChmVQBM%2FILipUGXZIQUmui5JxKsrDBgDMGgbQwLARf29OeOLV3XeAIHGAWYOqicxLKOEePh%2F0KvwASxcXOXt%2BMJLiYbIA0xiFf1yB01kMTwbnMW0k2AarJK3jJ133eMlpemAAmd1lwdn2XsenNLPYnP6dyfpU8ZF8OTJQVpktzw6lU88fqC1kAC0k4M5cvNwUngi9ZCDpsv4dO1jGRMFvgQI%2BulQoUFsuEqp6nmu5lFnuCkJDVIHPZ58ATkGKjppjRQ8OgkdDIdNdVPkrW41ouBgbDRgJRGbhiSTUMUW8g7Wg7aWLJJEngEZT0xN6J8%2FsfjLljhzmHI2DhWPtW9QKK05QENi2QEXlvGNTtB93%2BNDS906w2dLopOkxd%2FH0RQHdqq3S3WvbcK9ZtTUHKlyKA1yUisYhAvu4%2FCK0q5Ca0lrFhS8IKTADFkqzs2tWWRbPDN07UnZV6GdhyKeVTRMhv2yyql5pGnJEdxxs24uS0OHGeJVXe9E4qi1ZXsT%2B9vse3EB3Mb6awmsJLRS3dpBKSD2JPNNifPVuJ8%2F9Ce76kkFftefTfnt3bEzkq%2B55ytsAyiLsw5hOhdMKpCqPXInj%2BKDyVgv%2BA2gg6RCMUdmPlYeOk9fx9e%2FnwX%2FEycr38kuc%2FiJdR46G2fMh9q5kHXiOQ975udh%2BGL1kMgkjMVNrUix%2FBkcCJIz5lLGnLzTYo4wwabjYQpiRiWrNKKqDwE21Tol7ZxmYgIWGot2mtFHYt6cD6pSKKBLRZH7Uoye%2FA%2BuTogoRPwdfLYB4wvBzePozbjnFdYB87faFz%2BGlhcecHn%2FIEeo9q2UqZeya9vVr%2BUeVrlKVWTdZL3PbE76uiOUdgM1k7V7SmoVBXFU11q%2F9b8unVv1bo7Dc%3D%3C%2Fdiagram%3E%3C%2Fmxfile%3E#9_IDATx^}UջWd&8&9$ VC:X]*-$$e|G4GD1&"Á^{|-JT DNF/Y,>g}9g73s^Ys>=UD+< Q ,B@rDV&AzrģI]㓣d:HCz|$!GF!Ly郂=zHϻ@a80D>(HOÑ $!L!Lt郂=zHϻ@a80D>(HOÑ $!L!Lt郂=zHϻ@a80D>(HOÑ $!L!Lt郂=zHϻ@a80D>(HOÑ $!L!Lt郂=zHϻ@a80D>(HOÑ $!L!Lt郂=zHϻ@a80D>(HOÑ $!L!Lt郂=zHϻ@a80D>(HOÑ $!LQ ,Pk׮UG^={Zj8qX/^ڵKݼysmmm*1ܹݫ,YJ,A Z&C۩SԆ ԁoYkHՐ/IJP,#GU].j3#LG/ 26mR|zս{% AKiT ӑF݆7hR 6i`՚ҥKբET[[WfuU1f̘>+"' 4ab &`kqI;D }?p%2bO fRlyV̴040ϕ+mf|7,V;3+f}333v}z1tTJ̙b;b8m4a!̇>X\Hڹ¦΄ 80pܠղ~Z[+h0b)/kej/R+I^I=zŸ)Htz0a6&F,Q̄ثijO"/{9ccۦ#(q'0+/8vXEg߿ުxt_b Mo%Kڊr sOVeR.ChUŜwrZ1q=tR^13555}W:̳=tILtg:\ ^W(h "LF3L|U>/dؓ>w94̼1+_GRJGڹbÇ~_~\>2A'Ug>BO ꫑^1O8A'6酠W4:O<7<(O4d"{:-,6&C۷kct~zŜdͥp+RV:޽[8gjiZmO,y"VbRI W!5_xu*ߓK[! sW߃^1Aqy;WLA?/_\ȧǏWSLQޢ'?_ne:*V}-v!%>YifSNUO_z!*j #ouM+)tXsgc~R[u|q8nyibt7nPFRÇWϟ/t#긯\RP|=ATߥW*j{]㫶|(՟ =hGUͻvRDzT0Qy./}gyU/]s@q,L&vA!nH/-RڑVRL0m|wGz|/~zHOIJJ1ۿF#w_qJW+]IW\I!|8_ 'H``:"B]`:"BӑZhȉ@ooS, ѠK,=G#1_|Y٨MG р@ iӑh EA@!HG/V`:\I@50KVAYz qLt鐥(B 鐕N0@4  \G)o+VFs9˗G}>c5x\2~0N 2LG׼p)#_LTe30Qt+[nU7o._\iwԏ?MݫW"[駟2ꩧR}z J}}joo7xC^zB5j(5oC7e˖Wj3*?i&(  m>аMA:::I&m.h-2 dLnܸuuui@8 2=z݅I&-[g2 _}:s挮ڵk핚>[?Tի^ڰ)6St"CAل(v`:@d?jnnV.]VW_daNv ѓ5|1` /V7O@oC`@m:0q~K.iEM@A[7E}|g^ ߵ!  @Rg:JDQtJG1qV:x\M%{$h%kK% LG)Bx@@@,r^13Aw=Qt8>8->a Fg)xK~̝;Wu1Tyh{(uD(E#PlpQ^რtIW:TO"S$ mГ/tvԈ}tOpJtP,/(0u1\Fӑ䗃I1)tHQqj6\Lzw~da:0c6s$j_,ӑ$M  (ft$(*s" @@$PـHS-`:Y$gI BŬ#&8 F dR*i!NbLL]T 2'#e6`:"&FJa:Rf@ MryՁ-EfCftQ@2U 2;i 20Z d=A#m!3a:dꂨ@jd5U ;Y '`:j@ =A#k!!SDUC Ijyo= ωzpߓ[(|!lty *&rGCـH9pb $=ŋw%!l"@/.P"L,1գR̆,$Ӂ|FI[`9809M݆UM $~~qF5tP(̆\+LGGA3π#Voq 5j(5|puBm03gT( LGTb~zL:U9sF?^>}boP{%$+TWqEvZk.U[[[a7oS˗={۷ok1e}vxb߰au w@0Ho\MWb=>f͚ݻ O͝;WZ fCpTCh0ՠ"B sQ-RmmmWWg?:uJM4IܬZ[[T>^Z~z=;wڷo{ʕ+6lPhɓjĉz6cs&LWUGG2dѣGպuԎ; +=I9t^cر֭[<}/+R ^`:bÍ 1G)L===jʕ-F{n5nܸXt.2 dϟ'ѣGH`…jΝP2t͘1CoAP1%(3gר'N8 [*J4#F? x,%-^X`:baM .5f4+;:'OWȨ,X@OLiPSk֬Q]]]zU\hjjҿEQd*rƆb1ci:.\h?mӱd5p@ܹyoȋ2 LGdd@@AI0l+ ۶m D1sv(6Ub^-瀨頕^ !3Tn?mӁ/v^AU  5ΫPl#0jNgJZ[Y1p.+Q Ӂ7$0@, Pe:1rV뙎mh:y Z=6m>;B,d*Cm]鰷0x,֮iv}㡿`̉}MT'om۶M7f:L?r5@`:Ҥ*@R0LAa&hrfJGPԨiL#22   LGj@@@ 2p@0q LIENDB`jsoncons-1.3.2/doc/ref/jsonpatch/from_diff.md000066400000000000000000000022651477700171100211520ustar00rootroot00000000000000### jsoncons::jsonpatch::from_diff ```cpp #include template Json from_diff(const Json& source, const Json& target) ``` Create a JSON Patch from a diff of two json documents. #### Return value Returns a JSON Patch. ### Examples #### Create a JSON Patch ```cpp #include #include using jsoncons::json; namespace jsonpatch = jsoncons::jsonpatch; int main() { json source = json::parse(R"( {"/": 9, "foo": "bar"} )"); json target = json::parse(R"( { "baz":"qux", "foo": [ "bar", "baz" ]} )"); auto patch = jsonpatch::from_diff(source, target); std::error_code ec; jsonpatch::apply_patch(source, patch, ec); std::cout << "(1) " << pretty_print(patch) << '\n'; std::cout << "(2) " << pretty_print(source) << '\n'; } ``` Output: ``` (1) [ { "op": "remove", "path": "/~1" }, { "op": "replace", "path": "/foo", "value": ["bar","baz"] }, { "op": "add", "path": "/baz", "value": "qux" } ] (2) { "baz": "qux", "foo": ["bar","baz"] } ``` jsoncons-1.3.2/doc/ref/jsonpatch/jsonpatch.md000066400000000000000000000036541477700171100212130ustar00rootroot00000000000000### jsonpatch extension The jsonpatch extension implements the IETF standard [JavaScript Object Notation (JSON) Patch](https://tools.ietf.org/html/rfc6902)
apply_patch Apply JSON Patch operations to a JSON document.
from_diff Create a JSON patch from a diff of two JSON documents.
The JSON Patch IETF standard requires that the JSON Patch method is atomic, so that if any JSON Patch operation results in an error, the target document is unchanged. The patch function implements this requirement by generating the inverse commands and building an undo stack, which is executed if any part of the patch fails. ### Examples ```cpp #include #include using jsoncons::json; namespace jsonpatch = jsoncons::jsonpatch; int main() { // Apply a JSON Patch json doc = json::parse(R"( { "foo": "bar"} )"); json doc2 = doc; json patch = json::parse(R"( [ { "op": "add", "path": "/baz", "value": "qux" }, { "op": "add", "path": "/foo", "value": [ "bar", "baz" ] } ] )"); std::error_code ec; jsonpatch::apply_patch(doc, patch, ec); std::cout << "(1)\n" << pretty_print(doc) << '\n'; // Create a JSON Patch from two JSON documents auto patch2 = jsonpatch::from_diff(doc2,doc); std::cout << "(2)\n" << pretty_print(patch2) << '\n'; jsonpatch::apply_patch(doc2, patch2, ec); std::cout << "(3)\n" << pretty_print(doc2) << '\n'; } ``` Output: ``` (1) { "baz": "qux", "foo": ["bar","baz"] } (2) [ { "op": "replace", "path": "/foo", "value": ["bar","baz"] }, { "op": "add", "path": "/baz", "value": "qux" } ] (3) { "baz": "qux", "foo": ["bar","baz"] } ``` jsoncons-1.3.2/doc/ref/jsonpatch/jsonpatch_errc.md000066400000000000000000000013101477700171100222110ustar00rootroot00000000000000### jsoncons::jsonpatch::jsonpatch_errc ```cpp #include ```
The constant integer values scoped by `jsonpatch_errc` define the values for jsonpatch error codes. ### Member constants constant |Description ---------------------|------------------------------ `invalid_patch` |Invalid JSON Patch document `test_failed` |JSON Patch test operation failed `add_failed` |JSON Patch add operation failed `remove_failed` |JSON Patch remove operation failed `replace_failed` |JSON Patch replace operation failed `move_failed` |JSON Patch move operation failed `copy_failed` |JSON Patch copy operation failed jsoncons-1.3.2/doc/ref/jsonpatch/jsonpatch_error.md000066400000000000000000000025531477700171100224210ustar00rootroot00000000000000### jsoncons::jsonpatch::jsonpatch_error ```cpp #include ```
`jsoncons::jsonpatch::jsonpatch_error` defines an exception type for reporting failures in jsonpatch operations. ![jsonpatch_error](./diagrams/jsonpatch_error.png) #### Constructors jsonpatch_error(std::error_code ec) jsonpatch_error(const jsonpatch_error& other) #### Member functions const char* what() const noexcept Returns a message for this exception #### Inherited from std::system_error const std::error_code code() const noexcept Returns an error code for this exception ### Example ```cpp #include #include using jsoncons::json; int main() { json target = R"( { "foo": "bar"} )"_json; json patch = R"( [ { "op": "add", "path": "/baz", "value": "qux" }, { "op": "add", "path": "/foo", "value": [ "bar", "baz" ] }, { "op": "add", "path": "/baz/bat", "value": "qux" } // nonexistent target ] )"_json; try { jsonpatch::apply_patch(target, patch); } catch (const jsonpatch::jsonpatch_error& e) { std::cout << "(1) " << e.what() << '\n'; std::cout << "(2) " << target << '\n'; } } ``` Output: ``` (1) JSON Patch add operation failed (2) {"foo":"bar"} ``` jsoncons-1.3.2/doc/ref/jsonpath/000077500000000000000000000000001477700171100165255ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/jsonpath/basic_json_location.md000066400000000000000000000141341477700171100230540ustar00rootroot00000000000000### jsoncons::jsonpath::basic_json_location ```cpp #include template > (since 0.172.0) class basic_json_location ``` Two specializations for common character types are defined: Type |Definition ----------|------------------------------ json_location |`basic_json_location` wjson_location |`basic_json_location` Objects of type `basic_json_location` represents the location of a specific value in a JSON document. #### Member types Type |Definition ------------|------------------------------ char_type | `CharT` allocator_type | Allocator string_view_type | `jsoncons::basic_string_view` value_type | basic_path_element const_iterator | A constant [LegacyRandomAccessIterator](https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator) with a `value_type` of [basic_path_element](basic_path_element.md) iterator | An alias to `const_iterator` #### Constructors basic_json_location(const allocator_type& alloc=Allocator()); (1) basic_json_location(const basic_path_node& path, const allocator_type& alloc=Allocator()); (2) basic_json_location(const basic_json_location&); (3) basic_json_location(basic_json_location&&) noexcept; (4) (1) Constructs an empty `basic_json_location`. (2) Constructs a `basic_json_location` from a path node. (3) Copy constructor (4) Move constructor #### operator= basic_json_location& operator=(const basic_json_location&); basic_json_location& operator=(basic_json_location&&); #### Iterators iterator begin() const; iterator end() const; Iterator access to the tokens in the pointer. #### Accessors bool empty() const Checks if the location is empty std::size_t size() const const path_element_type& operator[](std::size_t index) const #### Modifiers void clear(); basic_json_location& append(const string_view_type& name) Appends `name` to the location. template basic_json_location& append(IntegerType index) Appends `index` to the location. This overload only participates in overload resolution if `IntegerType` is an integer type. basic_json_location& append(const basic_json_location& relative_location) Appends `relative_location` to the location. #### Static member functions static parse(const string_view_type& str); static parse(const string_view_type& str, std::error_code& ec); Constructs a `basic_json_location` from a normalized path, or an equivalent representation using the dot notation. #### Non-member functions
replace Replace a value in a JSON document at a specified location with a new value
get Returns a pointer to a JSON value in a JSON document at a specified location
remove Remove a JSON node from a JSON document at a specified location
template > std::basic_string, Allocator> to_basic_string(const basic_json_location& location, const Allocator& alloc = Allocator()) Returns a normalized path std::string to_string(const json_location& location) std::wstring to_wstring(const wjson_location& location) ### Examples The examples below uses the sample data file `books.json`, ```json { "books": [ { "category": "fiction", "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "category": "fiction", "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "category": "fiction", "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "category": "memoir", "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } ``` #### Get a pointer to the book at index 1 ``` jsonpath::json_location loc; loc.append("store").append("book").append(1); auto result = jsonpath::get(doc, loc); // since 0.175.0 if (result.second) { std::cout << *(result.first) << "\n"; } ``` #### Convert a JSONPath normalized path into a JSONPointer ```cpp #include #include #include using jsoncons::json; namespace jsonpath = jsoncons::jsonpath; namespace jsonpointer = jsoncons::jsonpointer; #include int main() { std::ifstream is(/*path_to_books_file*/); json doc = json::parse(is); auto expr = jsonpath::make_expression("$.books[?(@.category == 'fiction')]"); std::vector locations = expr.select_paths(doc, jsonpath::result_options::sort_descending); for (const auto& location : locations) { std::cout << jsonpath::to_string(location) << "\n"; } std::cout << "\n"; std::vector pointers; for (const auto& location : locations) { jsonpointer::json_pointer ptr; { for (const jsonpath::path_element& element : location) { if (element.has_name()) { ptr.append(element.name()); } else { ptr.append(element.index()); } } } pointers.push_back(ptr); } for (const auto& ptr : pointers) { std::cout << jsonpointer::to_string(ptr) << "\n"; } std::cout << "\n"; } ``` Output: ``` $['books'][2] $['books'][1] $['books'][0] /books/2 /books/1 /books/0 ``` jsoncons-1.3.2/doc/ref/jsonpath/basic_path_element.md000066400000000000000000000036441477700171100226640ustar00rootroot00000000000000### jsoncons::jsonpath::basic_path_element ```cpp #include template class basic_path_element (since 0.172.0) ``` Two specializations for common character types are defined: Type |Definition ----------|------------------------------ path_element |`basic_path_element` wpath_element |`basic_path_element` Objects of type `basic_path_element` represent an element (name or index) of a normalized path. #### Member types Type |Definition ------------|------------------------------ char_type | `CharT` allocator_type | Allocator char_allocator_type | Rebound Allocator for `char_type` string_type | `std::basic_string,char_allocator_type>` #### Constructors basic_path_element(const char_type* name, std::size_t length, const Allocator& alloc = Allocator()); (1) explicit basic_path_element(const string_type& name); (2) explicit basic_path_element(string_type&& name); (3) basic_path_element(std::size_t index, const Allocator& alloc = Allocator()); (4) basic_path_element(const basic_path_element&); (5) basic_path_element(basic_path_element&&) noexcept; (6) (1)-(3) Constructs a `basic_path_element` from a name. (4) Constructs a `basic_path_element` from an index. #### operator= basic_path_element& operator=(const basic_path_element&); basic_path_element& operator=(basic_path_element&&); #### Accessors bool has_name() const; Checks if the element has a name bool has_index() const; Checks if the element has an index const string_type& name() const Returns the name std::size_t index() const Returns the index jsoncons-1.3.2/doc/ref/jsonpath/basic_path_node.md000066400000000000000000000040611477700171100221520ustar00rootroot00000000000000### jsoncons::jsonpath::basic_path_node ```cpp #include template (since 0.172.0) class basic_path_node ``` Two specializations for common character types are defined: Type |Definition ----------|------------------------------ path_node |`basic_path_node` wpath_node |`basic_path_node` Objects of type `basic_path_node` represent a normalized path as a singly linked list where each node has a pointer to its (shared) parent node. #### Member types Type |Definition ------------|------------------------------ char_type | `CharT` string_view_type | `jsoncons::basic_string_view` #### Constructors basic_path_node(); (1) basic_path_node(const basic_path_node* parent, const string_view_type& name); (2) basic_path_node(const basic_path_node* parent, std::size_t index); (3) basic_path_node(const basic_path_node&); (4) (1) Constructs an empty `basic_path_node` with a null parent representing the root of a path. (2) Constructs a `basic_path_node` from a name. (3) Constructs a `basic_path_node` from an index. (4) Copy constructor #### operator= basic_path_node& operator=(const basic_path_node&); #### Accessors const basic_path_node* parent() const; Returns the parent of a path node std::size_t size() const; Returns the number of nodes in the path. path_node_kind node_kind() const; Returns the kind of the node const string_view_type& name() const; std::size_t index() const; #### Non-member functions template > std::basic_string, Allocator> to_basic_string(const basic_path_node& location, const Allocator& alloc = Allocator()) Returns a normalized path std::string to_string(const path_node& path) std::wstring to_wstring(const wpath_node& path) jsoncons-1.3.2/doc/ref/jsonpath/diagrams/000077500000000000000000000000001477700171100203145ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/jsonpath/diagrams/jsonpath_error.png000066400000000000000000000225231477700171100240650ustar00rootroot00000000000000PNG  IHDRptEXtmxfile%3Cmxfile%20modified%3D%222020-03-24T19%3A37%3A28.758Z%22%20host%3D%22app.diagrams.net%22%20agent%3D%22Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F80.0.3987.149%20Safari%2F537.36%22%20etag%3D%22sT_BTJLY1iuQgoSmLSYb%22%20version%3D%2212.9.2%22%20type%3D%22device%22%3E%3Cdiagram%20id%3D%22iK-0d-7Yl-5MlnfMu26I%22%20name%3D%22Page-1%22%3E7VhrT9swFP01%2FcjUxGlpP0JhbItAY0UqfEImuSTeHLs4bpvu188mzsNJymOKKHugSvge29fO8Tm3TgdolmRnAi%2Fjcx4CHbjDMBugk4HrOkM0Uf80ss0Rb2qASJDQDKqAOfkJxUyDrkgIqTVQck4lWdpgwBmDQFoYFoJv7GH3nNqrLnEELWAeYNpGFySUcY5ORsMK%2FwQkiouVnaHpSXAx2ABpjEO%2BqUHodIBmgnOZt5JsBlSTV%2FCSz%2Fu4o7fcmAAmXzLh9OIqY%2F7lPHZnD75cnCc32ZcDk2WN6co8cCrV%2BCP1gSyApSScme3LbcGJ4CsWgk47HKDjTUwkzJc40L0bpQKFxTKhKnJUs73NYk0QErIaZLZ9BjwBKbZqiOkdGwaNhKYm3FTnUbIe187CMxg2EojKxBVLqmGIegVph7tJEysmSQK3oKQn9k6cO3xnzE1azLU4AhYead%2BqKKA4TUlg0wIZkdeGQd2%2B0e0PIxOdZLWuk20RMLX56yKBDmqzdFhNe4yKeTuPIOUrEcDzEpFYRCCf9x%2BEVhVqH2jtxEYdB1ZgAiiWZG3Xrq5TNCt85UQ9WakXz5ZLKZ8iQ%2F7YZlK91DTyTO08zqiRJ6elledRUuVDv0hl0fo8dv2La%2FwNooPFpQ9rH54qauk2lZC8E3sib3%2F27CTO%2FQvt%2BZRCnrXn4X979m9P1FLZ95Szpbov9eHLe0LpjFOVRs9F8Pin8FQK%2FgNqPWiMpijsx8mjxhet4%2B7byuN%2FxcqobeWnLP9OrIwad9ryjvtaL3tOI5HztmZu34U%2FsxgEkZipY1PvfQRHAict8SljSVtutkEZZ9Bws4EwJRHTmlVSAYUfa5sS9cZ2ZDoSEoZ6mc5KYdeSHqzffDtxu6yPOpTk9mF9fMc8zoP7q2yMvYfEX5z5HdcfXV9ve32fa%2FHTweKL7z3lF9CbVMsuyv7Ii0%2BjlPVXPneKam8Xn8OGxya%2FWS1HbiMR6qtaqrD6KScfXv0ghk5%2FAQ%3D%3D%3C%2Fdiagram%3E%3C%2Fmxfile%3EQ10IDATx^mUǹ'Ԓ*X!@11E"Fbҫ?TM 4D?m$~4FE 1/DCM0!Z"F!J+ -}\}6sV{u֬~ 3k3=3k܀2E``$7p)VB!`9_􃲽I@fЎx2[z|v&zX촂vhj$c[gLXz|2z`:n}P19c]EXaL0&Az|u=] c 1AØ3z8_t5i`8c[gLXz|2z`:n}P19c]EXaL0&Az|u=] c 1AØ3z8_t5i`8c[gLXz|2z`:n}P19c]EXaL0&Az|u=] c 1AØ3z8_t5i`8c[gLXz|2z`:n}P19c]EXaLSt[t۰a8q uֹӧE}Ν;ݗ_~yѕiPz{SO=UI,2h ܎?6ob3[*D|NVrFb?~>[0 =: ~UHnPeK/}kUҶ, n-QE,ꢡ&(l:=M6+W˗ݻwI&qƵ^[x;_;$?Yȧ3f۷'N{?);wקN4cǎ5&)d4m4bŊVcƌn>fϞ6n^y!%JcǎCʛTᠠfC<00 s=|ɼՖV>/rsPty湓'O\*IJyseG;p[p5\QQFS%Ҵ<}ϥo~n֭^kkɒ%>F~m_KK+u몎%>7w\ /~;h[Jb \ +9#m{E'&]O3UZkΥi)j)X#ai$07œ\Qc#lE⎕3ɭpǤnkJx}/9%F?fΜq\t9rҶ?o|ErH@5Rw;#FDh7tؾ#Ldo9y#I&ȧ&Xtt%K$"f7ȪKr t"˖jLP0_:\I'zr1m#yf%/44rƮ/OXtJ̙N;a8k,a!R4̇H>YOus!U犚96rȶㆬ}u?+Wh <ː_*hӡ%p%퀪.[%%DN:hӑtٶm7>qM7yTْWbܒmӑfX҉\s蔋t(+'aIr,J|cnk鶬#G,Z'MGP#9ZtNns?׿z!w:cM2 DxVc(+Y.d~743OdiYkJ2M$Ÿ)(tz0i6&$DXJF'\MK$ҋ"3I=mFI.NQ;W4_d;trFHooUKNRN+׮]k LZm$X*DnLӓYM| }H~/+gn+5V^_o怎9C1Wױs%4ի|9>ew;yo}#ִz ^Ge>Zz|uVW_uiXeI=xsnl|TJtTMY r.Z.~R-ZQw|p˸hyk\/^&LnVwԩVW1EUni:Aun=n߭a=~ˇnilu~[r?Wn|t#t%Az|1Wu=gNYU0&vAnX*VڱXUCQRØCbwz|o~zXϚ)K^1˿FJ9 `:r]A!VoZz|VuWzX7b:cޜӑZe ek=k>zXϺeKQv >LE;֠PV+Ru=+:gl=LGYSN=r8ZKAaZoa=^{VjƔ{?\VՠP4XWg]EZhĹjzP|ң.ț!qc:-T{]B`ǗRκ<ڏ|`:fF50pJ݃B`-~u=oЭ?V|`:eDtT;SkV`Ǘ r(2uŚ#SZTVe:*k2TB2hq"@z4%tFo:,f-ND@(|`:*-G( @(|`:+k+(@tT.Y1 @hCtJ'L-=:k>0 aK sfrՇw_e<.o[nůL4ٳ߷{n裏r߃>b{ &9rķO_nʔ)nڵolO/}9[Vq?kKRU~>JZ?e:u۲e7IcV:2a #us?2a~BK& zs!f@`41x/wIodb!F{'.\hM2 nY į~+>A+bd&|O.1Lbn_1BrI}w5!b8:Sfz1RB K>SxbߟuoLG8[b@t@ ĥK$+b Ο?2ZR;Nw PIX.tq "ѣb$3/C `@r㿎w4qKCdL?5 b#<pGO~vCVNV;QtMxI_AS&#O?$#-BI1thG+\d:tCǍ7tZ(b:%Aڭd$yӑe!@2^ ٚͅ׳d:ЭpKfĈGX.,+ROxCkdt;m%-I0>@Yt3ZGѧW >>mNC"It<"4<"K^׳n}ɧWV:ެ̢tEY@@V1TQ旃Yұ:tI!@ f#Oyw"K1MG;>xge0UP @(Dk: M `:r#@M`f[bc:q.@@, N Ub:JH@:8p"000`+ \faNbæ.D! $7svĚ#gbTTQh@S X䚪ۊfc:lBTV&:ĎԭGUf1Dt;#XIIKfc:lBTuMr}TG]fQrT$T'P$ TGfa鰩 QAoT5 鈜Htm@6'lQPJ ÚtyLM] }C $7*HzX5+cs(#P$W, *{úM"p_hK@tszٰEhBF`\ZqQ=0 MtDJ? @;=}Yw7{+b6Z1MVC 2LGd9OqE7aw뭷SNjlK0QQKӑXI=x)S> b>n`:zI-b@j:Μ96lvFc,n/z^ڽʕ+t_v+V;XǸ `:H@ #Z+h;w~'4l0h"n:̆0"}QYMG81-_޽ꭷr??~͘1xb}vOׯoڴOݮv8qݻ=|po>wܹV}7ons17}t?y1گiӦՃI&1c>>|͞=mܸѽ+D9qw˗/x㍾o~ @aF8tPkt[v',d b޼yn׮]n-rJ\b4,YO'NL Q e܎;ܸqZY!ל9s4 Q2rɽb}yMb~GߤޣG8/\R Wg@ۼ6!ݤ(DQ7AY tmd@g̙3K  ~igq'Oj… zI{Үd9YPc#z%4O.ISO#Gիv?яK&ȍ 9Hn #ita۶m{Sxw0=. C2"COv$驎"qXnYNO֤=O轣FO7]#myzH?5Ga9 `:z[?iY': pU*F3 `:;@%Lr :(#8ekC@I^rP3I{U#f,GaG_ӝt|lhb4&N!P&@gl=2X4hh`aK&Fh`tf##(E#鈆!&9[9hb4&N!P&@gl=2X4hh`aK&Fh`tf##(E#鈆!&9[9hb4&N!P&@gl=2X4hh`aK&Fh`tf##(E#鈆!l4QrY@@}0e@@`:%7 GQ{Z 4QrY@@}0e@@`:%7 GQ{Z 4QrY@@}0e@@`:%7 GQ{Z 4QrY@@}0e@@`:%7 GQ{Z 4QrY@@}0e@@`:%7 GQ{Z 4QrY@@}0e@@`:%7 GQ{Z 4QrY@@}0e@@`:%7 GQ{Z 4QrY@@}0e@@`:%7 GQ{Z 4QrY@@}0e@@`:%7 GQ{ZC.]rK.u6lp'NL3g|;wѣG"qu|rpBwwdjPCoڷo;z۲e[fsk6@`:AE`@#tvcnU6M[QVo'qcǺmڴɭ[JǴi܊+ܤI[#Ǐw3f,^-we_wps޽UϘ1cÇ۶;j(_^cǎV $y湓'O.vFBI+W|e#+پ ~#Gt+WoWVv:/k.yfBfv5z53'N%Kx LVL_|/wl2c|ĈqI^{fΜ#ujڵkh$ǻSGb/5,2O<1Cl?!a4vLZwi166t4Fj:ZvC'oK8ʧ{zqAB%o:yk}YtdmWLb$IXrדq;ӑs缡Kڕth:v!uZ܂"'i`:,A,=O699Il1ٳݞ={t$0tFnhv}H#`I AN>ڶmo"t%k0=}Fgҝz e:OڣdȶCЭ \Vi] template Json flatten(const Json& value); (1) template Json unflatten(const Json& value); (2) ``` Flattens a json object or array to a single depth object of key-value pairs, and unflattens that object back to the original json. The keys in the flattened object are normalized json paths. The values are primitive (string, number, boolean, or null), empty object (`{}`) or empty array (`[]`). #### Return value (1) A flattened json object of JSONPath-value pairs (2) An unflattened json object ### Examples #### Flatten and unflatten ```cpp #include #include #include #include // for brevity using jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { json input = json::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 }, { "rater": "HikingAsylum", "assertion": "intermediate", "rated": "Hongmin", "rating": 0.75 } ] } )"); json flattened = jsonpath::flatten(input); std::cout << pretty_print(flattened) << "\n"; json original = jsonpath::unflatten(flattened); assert(original == input); } ``` Output: ``` { "$['application']": "hiking", "$['reputons'][0]['assertion']": "advanced", "$['reputons'][0]['rated']": "Marilyn C", "$['reputons'][0]['rater']": "HikingAsylum", "$['reputons'][0]['rating']": 0.9, "$['reputons'][1]['assertion']": "intermediate", "$['reputons'][1]['rated']": "Hongmin", "$['reputons'][1]['rater']": "HikingAsylum", "$['reputons'][1]['rating']": 0.75 } ``` ### See also [jsoncons::jsonpointer::flatten](../jsonpointer/flatten.md) jsoncons-1.3.2/doc/ref/jsonpath/functions/000077500000000000000000000000001477700171100205355ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/jsonpath/functions/abs.md000066400000000000000000000002411477700171100216210ustar00rootroot00000000000000### abs ``` number abs(number value) ``` Returns the absolute value of a number. It is a type error if the provided argument is not a number. ### Examples jsoncons-1.3.2/doc/ref/jsonpath/functions/avg.md000066400000000000000000000024741477700171100216430ustar00rootroot00000000000000### avg ``` number|null avg(array[number] value) ``` Returns the average of the items in an array of numbers, or null if the array is empty It is a type error if - the provided value is not an array - the array contains items that are not numbers ### Examples ```cpp #include #include #include // for brevity using jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { std::string data = R"( { "books": [ { "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } )"; json j = json::parse(data); // All titles whose price is greater than the average price std::string expr = R"($.books[?(@.price > avg($.books[*].price))].title)"; json result = jsonpath::json_query(j, expr); std::cout << result << "\n\n"; } ``` Output: ``` ["The Night Watch"] ``` jsoncons-1.3.2/doc/ref/jsonpath/functions/ceil.md000066400000000000000000000024041477700171100217730ustar00rootroot00000000000000### ceil ``` integer ceil(number value) ``` Returns the smallest integer value not less than the provided number. It is a type error if the provided argument is not a number. ### Examples ```cpp #include #include #include // for brevity using jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { std::string data = R"( { "books": [ { "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 } ] } )"; json j = json::parse(data); json result1 = jsonpath::json_query(j, "$.books[?(ceil(@.price) == 23.0)]"); std::cout << "(1) " << result1 << "\n\n"; json result2 = jsonpath::json_query(j, "$.books[?(ceil(@.price*100) == 2358.0)]"); // (since 0.164.0) std::cout << "(2) " << result2 << "\n\n"; ``` Output: ``` (1) [{"author":"Haruki Murakami","price":22.72,"title":"A Wild Sheep Chase"}] (2) [{"author":"Sergei Lukyanenko","price":23.58,"title":"The Night Watch"}] ``` jsoncons-1.3.2/doc/ref/jsonpath/functions/contains.md000066400000000000000000000030371477700171100227000ustar00rootroot00000000000000### contains ``` boolean contains(array|string source, any search) ``` If source is an array, returns true if the array contains an item that is equal to the search value, false otherwise. If source is a string, returns true if the string contains a substring that is equal to the search value, false otherwise. It is a type error if - the provided source is not an array or string, or - the provided source is a string but the provided search value is not a string. ### Examples ```cpp #include #include #include // for brevity using jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { std::string data = R"( { "books": [ { "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } )"; json j = json::parse(data); // All books that don't have a price std::string expr = "$.books[?(!contains(keys(@),'price'))]"; json result = jsonpath::json_query(j, expr); std::cout << result << "\n\n"; } ``` Output: ``` [{"author":"Phillips, David Atlee","title":"The Night Watch"}] ``` jsoncons-1.3.2/doc/ref/jsonpath/functions/ends_with.md000066400000000000000000000004221477700171100230410ustar00rootroot00000000000000### ends_with ``` boolean ends_with(string source, string suffix) ``` Returns true if the source string ends with the suffix string, otherwise false. It is a type error if - the provided source is not a string, or - the provided suffix is not a string ### Examples jsoncons-1.3.2/doc/ref/jsonpath/functions/floor.md000066400000000000000000000023101477700171100221740ustar00rootroot00000000000000### floor ``` integer floor(number value) ``` Returns the largest integer value not greater than the given number. It is a type error if the provided argument is not a number. ### Examples ```cpp #include #include #include // for brevity using jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { std::string data = R"( [ { "number" : 8.95 }, { "number" : -8.95 } ] )"; json j = json::parse(data); json result1 = jsonpath::json_query(j, "$[?(floor(@.number*100) == 895)]"); std::cout << "(1) " << result1 << "\n\n"; json result2 = jsonpath::json_query(j, "$[?(floor(@.number*100) == 894)]"); // (since 0.164.0) std::cout << "(2) " << result2 << "\n\n"; json result3 = jsonpath::json_query(j, "$[?(floor(@.number*100) == -895)]"); // (since 0.164.0) std::cout << "(3) " << result3 << "\n\n"; } ``` Output: ``` (1) [] (2) [{"number":8.95}] (3) [{"number":-8.95}] ``` (Note that the representable floating point number closest to 8.95*100 is strictly less than 895.0) jsoncons-1.3.2/doc/ref/jsonpath/functions/keys.md000066400000000000000000000002531477700171100220320ustar00rootroot00000000000000### keys ``` array[string] keys(object value) ``` Returns an array of keys in the object. It is a type error if the provided argument is not an object. ### Examples jsoncons-1.3.2/doc/ref/jsonpath/functions/length.md000066400000000000000000000025741477700171100223500ustar00rootroot00000000000000### length ``` integer|null length(array|object|string value) ``` Returns the length of an array, object or string. If array, returns the number of items in the array If object, returns the number of key-value pairs in the object If string, returns the number of codepoints in the string Otherwise, returns null. ### Examples ```cpp #include #include #include // for brevity using jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { std::string data = R"( { "books": [ { "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } )"; json j = json::parse(data); json result1 = jsonpath::json_query(j, "length($.books[*])"); std::cout << "(1) " << result1 << "\n\n"; json result2 = jsonpath::json_query(j, "length($.books[*].price)"); std::cout << "(2) " << result2 << "\n\n"; } ``` Output: ``` (1) [4] (2) [3] ``` jsoncons-1.3.2/doc/ref/jsonpath/functions/max.md000066400000000000000000000005441477700171100216470ustar00rootroot00000000000000### max ``` number|string|null max(array[number]|array[string] value) ``` Returns the highest number found in an array of numbers, or the highest string in an array of strings, or null if the array is empty. It is a type error if - the provided value is not an array - the array contains items that are not all numbers or all strings ### Examples jsoncons-1.3.2/doc/ref/jsonpath/functions/min.md000066400000000000000000000005401477700171100216410ustar00rootroot00000000000000### min ``` number|string|null min(array[number]|array[string] value) ``` Returns the lowest number found in an array of numbers, or the lowest string in an array of strings, or null if the array is empty It is a type error if - the provided value is not an array - the array contains items that are not all numbers or all strings ### Examples jsoncons-1.3.2/doc/ref/jsonpath/functions/prod.md000066400000000000000000000004211477700171100220200ustar00rootroot00000000000000### prod ```cpp number|null avg(array[number] value) ``` Returns the product of the items in an array of numbers, or null if the array is empty. It is a type error if - the provided value is not an array - the array contains items that are not numbers ### Examples jsoncons-1.3.2/doc/ref/jsonpath/functions/starts_with.md000066400000000000000000000004271477700171100234350ustar00rootroot00000000000000### starts_with ``` boolean starts_with(string source, string prefix) ``` Returns true if the source string starts with the prefix string, otherwise false. It is a type error if - the provided source is not a string, or - the provided prefix is not a string ### Examples jsoncons-1.3.2/doc/ref/jsonpath/functions/sum.md000066400000000000000000000024371477700171100216710ustar00rootroot00000000000000### sum ``` number sum(array[number] value) ``` Returns the sum of the items in an array of numbers. Returns 0 if the array is empty. It is a type error if any item in the array is not a number. ### Examples ```cpp #include #include #include // for brevity using jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { std::string data = R"( { "books": [ { "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } )"; json j = json::parse(data); // All titles whose price is greater than the average price std::string expr = R"($.books[?(@.price > sum($.books[*].price)/length($.books[*].price))].title)"; json result = jsonpath::json_query(j, expr); std::cout << result << "\n\n"; } ``` Output: ``` ["The Night Watch"] ``` jsoncons-1.3.2/doc/ref/jsonpath/functions/to_number.md000066400000000000000000000004171477700171100230530ustar00rootroot00000000000000### to_number ``` number to_number(string|number value) ``` If string, returns the parsed number. If number, returns the passed in value. It is a type error if - the provided value is not a string or number - the string cannot be parsed as a number ### Examples jsoncons-1.3.2/doc/ref/jsonpath/functions/tokenize.md000066400000000000000000000023421477700171100227100ustar00rootroot00000000000000### tokenize ``` array[string] tokenize(string source, string pattern) ``` Returns an array of strings formed by splitting the source string into an array of strings, separated by substrings that match the given regular expression pattern. It is a type error if either argument is not a string. ### Example ```cpp #include #include #include using json = jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { std::string data = R"( { "books": [ { "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami" }, { "title" : "Almost Transparent Blue", "author" : "Ryu Murakami" }, { "title" : "The Quiet American", "author" : "Graham Greene" } ] } )"; json j = json::parse(data); // All titles whose author's last name is 'Murakami' std::string expr = R"($.books[?(tokenize(@.author,'\\s+')[-1] == 'Murakami')].title)"; json result = jsonpath::json_query(j, expr); std::cout << pretty_print(result) << "\n\n"; } ``` Output: ```json [ "A Wild Sheep Chase", "Almost Transparent Blue" ] ``` jsoncons-1.3.2/doc/ref/jsonpath/get.md000066400000000000000000000017511477700171100176320ustar00rootroot00000000000000### jsoncons::jsonpath::get ```cpp #include template Json* get(Json& root, const basic_json_location& location); (until 0.175.0) template std::pair get(Json& root, const basic_json_location& location); (since 0.175.0) ``` Gets a pointer to a JSON value in a JSON document at a specified location. #### Parameters
root Root JSON value
location A basic_json_location
#### Return value Until 0.175.0, returns a pointer to the selected item, or null if not found. Since 0.175.0, returns a `std::pair`. If the get operation succeeded, the bool component is `true`, and the `Json*` component points to the value in the `root`. If the get operation failed, the bool component is `false`. ### Exceptions None. jsoncons-1.3.2/doc/ref/jsonpath/grammar.md000066400000000000000000000020761477700171100205020ustar00rootroot00000000000000path = absolute-path | relative-path absolute-path = "$" [qualified-path] qualified-path = recursive-location | relative-location recursive-location = ".." relative-path relative-location = "." relative-path expression = single-quoted-string expression =/ json-literal expression =/ jsonpath-expression expression =/ unary-expression / binary-expression / regex-expression / paren-expression paren-expression = "(" expression ")" unary-expression=unary-operator expression binary-expression = expression binary-operator expression regex-expression = expression regex-operator regex-literal regex-literal = "/" regex-character-literals "/" unary-operator = "!" / "-" binary-operator = "*" / "/" / "%" / "+" / "-" binary-operator =/ "&&" / "||" binary-operator =/ <" / "<=" / "==" / ">=" / ">" / "!=" regex-operator = "=~" function-expression = unquoted-string ( no-args / one-or-more-args ) no-args = "(" ")" one-or-more-args = "(" ( function-arg *( "," function-arg ) ) ")" function-arg = expression jsoncons-1.3.2/doc/ref/jsonpath/json_query.md000066400000000000000000000347701477700171100212600ustar00rootroot00000000000000### jsoncons::jsonpath::json_query ```cpp #include ``` ```cpp template Json json_query(const Json& root value, const Json::string_view_type& expr, (until 0.164.0) result_options options = result_options()); (1) template Json json_query(const Json& root value, const Json::string_view_type& expr, (since 0.164.0) result_options options = result_options(), const custom_functions& funcs = custom_functions()); ``` ```cpp template void json_query(const Json& root value, const Json::string_view_type& expr, (until 0.164.0) BinaryCallback callback result_options options = result_options()); (2) template void json_query(const Json& root value, const Json::string_view_type& expr, (since 0.164.0) BinaryCallback callback, result_options options = result_options(), const custom_functions& funcs = custom_functions()); ``` ```cpp template Json json_query(const allocator_set& alloc_set, const Json& root value, const Json::string_view_type& expr, (3) (since 0.170.0) result_options options = result_options(), const custom_functions& funcs = custom_functions()); ``` ```cpp template void json_query(const allocator_set& alloc_set, const Json& root value, const Json::string_view_type& expr, (4) (since 0.170.0) BinaryCallback callback, result_options options = result_options(), const custom_functions& funcs = custom_functions()); ``` (1) Evaluates the root value against the JSONPath expression `expr` and returns an array of values or normalized path expressions. (2) Evaluates the root value against the JSONPath expression `expr` and calls a provided callback repeatedly with the results. (3)-(4) Same as (1-2) except that `alloc` is used to allocate memory during expression compilation and evaluation. #### Parameters
root value Json value
expr JSONPath expression string
callback A function object that accepts a path and a reference to a Json value. It must have function call signature equivalent to

void fun(const Json::string_view_type& path, const Json& val);

type (until 0.161.0)) Since 0.161.0, typedefed to jsonpath_options.
options (since 0.161.0) Result options, a bitmask of type result_options
#### Return value (1) returns an array containing either values or normalized path expressions matching the JSONPath expression, or an empty array if there is no match. #### Exceptions Throws a [jsonpath_error](jsonpath_error.md) if JSONPath parsing fails. ### Examples #### Store examples The examples below use the sample data file `store.json`. ```json { "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ], "bicycle": { "color": "red", "price": 19.95 } } } ``` ```cpp #include #include #include namespace jsonpath = jsoncons::jsonpath; int main() { std::ifstream is("./input/store.json"); auto booklist = jsoncons::json::parse(is); // The authors of books that are cheaper than $10 jsoncons::json result1 = jsonpath::json_query(booklist, "$.store.book[?(@.price < 10)].author"); std::cout << "(1) " << result1 << "\n"; // The number of books jsoncons::json result2 = jsonpath::json_query(booklist, "length($..book)"); std::cout << "(2) " << result2 << "\n"; // The third book jsoncons::json result3 = jsonpath::json_query(booklist, "$..book[2]"); std::cout << "(3)\n" << pretty_print(result3) << "\n"; // All books whose author's name starts with Evelyn jsoncons::json result4 = jsonpath::json_query(booklist, "$.store.book[?(@.author =~ /Evelyn.*?/)]"); std::cout << "(4)\n" << pretty_print(result4) << "\n"; // The titles of all books that have isbn number jsoncons::json result5 = jsonpath::json_query(booklist, "$..book[?(@.isbn)].title"); std::cout << "(5) " << result5 << "\n"; // All authors and titles of books jsoncons::json result6 = jsonpath::json_query(booklist, "$['store']['book']..['author','title']"); std::cout << "(6)\n" << pretty_print(result6) << "\n"; // Union of two ranges of book titles jsoncons::json result7 = jsonpath::json_query(booklist, "$..book[1:2,2:4].title"); std::cout << "(7) " << result7 << "\n"; // Union of a subset of book titles identified by index jsoncons::json result8 = jsonpath::json_query(booklist, "$.store[@.book[0].title,@.book[1].title,@.book[3].title]"); std::cout << "(8) " << result8 << "\n"; // Union of third book title and all book titles with price > 10 jsoncons::json result9 = jsonpath::json_query(booklist, "$.store[@.book[3].title,@.book[?(@.price > 10)].title]"); std::cout << "(9) " << result9 << "\n"; // Intersection of book titles with category fiction and price < 15 jsoncons::json result10 = jsonpath::json_query(booklist, "$.store.book[?(@.category == 'fiction' && @.price < 15)].title"); std::cout << "(10) " << result10 << "\n"; // Normalized path expressions jsoncons::json result11 = jsonpath::json_query(booklist, "$.store.book[?(@.author =~ /Evelyn.*?/)]", jsonpath::result_options::path); std::cout << "(11) " << result11 << "\n"; // All titles whose author's second name is 'Waugh' jsoncons::json result12 = jsonpath::json_query(booklist,"$.store.book[?(tokenize(@.author,'\\\\s+')[1] == 'Waugh')].title"); std::cout << "(12) " << result12 << "\n"; // All keys in the second book jsoncons::json result13 = jsonpath::json_query(booklist,"keys($.store.book[1])"); std::cout << "(13) " << result13 << "\n"; } ``` Output: ``` (1) ["Nigel Rees","Herman Melville"] (2) [4] (3) [ { "author": "Herman Melville", "category": "fiction", "isbn": "0-553-21311-3", "price": 8.99, "title": "Moby Dick" } ] (4) [ { "author": "Evelyn Waugh", "category": "fiction", "price": 12.99, "title": "Sword of Honour" } ] (5) ["Moby Dick","The Lord of the Rings"] (6) [ "Nigel Rees", "Sayings of the Century", "Evelyn Waugh", "Sword of Honour", "Herman Melville", "Moby Dick", "J. R. R. Tolkien", "The Lord of the Rings" ] (7) ["Sword of Honour","Moby Dick","The Lord of the Rings"] (8) ["Sayings of the Century","Sword of Honour","The Lord of the Rings"] (9) ["The Lord of the Rings","Sword of Honour","The Lord of the Rings"] (10) ["Sword of Honour","Moby Dick"] (11) ["$['store']['book'][1]"] (12) ["Sword of Honour"] (13) [["author","category","price","title"]] ``` #### Result options ```cpp #include #include using jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { std::string s = "[1,2,3,4,5]"; json data = json::parse(s); std::string path = "$[4,1,1]"; auto result1 = jsonpath::json_query(data, path); std::cout << "(1) " << result1 << "\n\n"; auto result2 = jsonpath::json_query(data, path, jsonpath::result_options::path); std::cout << "(2) " << result2 << "\n\n"; //auto result3 = jsonpath::json_query(data, path, // jsonpath::result_options::value | // jsonpath::result_options::sort); (until 0.164.0) auto result3 = jsonpath::json_query(data, path, jsonpath::result_options::sort); (since 0.164.0) std::cout << "(3) " << result3 << "\n\n"; //auto result4 = jsonpath::json_query(data, path, // jsonpath::result_options::sort); (until 0.164.0) auto result4 = jsonpath::json_query(data, path, jsonpath::result_options::sort | jsonpath::result_options::path); (since 0.164.0) std::cout << "(4) " << result4 << "\n\n"; //auto result5 = jsonpath::json_query(data, path, // jsonpath::result_options::value | // jsonpath::result_options::nodups); (until 0.164.0) auto result5 = jsonpath::json_query(data, path, jsonpath::result_options::nodups); (since 0.164.0) std::cout << "(5) " << result5 << "\n\n"; //auto result6 = jsonpath::json_query(data, path, // jsonpath::result_options::nodups); (until 0.164.0) auto result6 = jsonpath::json_query(data, path, jsonpath::result_options::nodups | jsonpath::result_options::path); (since 0.164.0) std::cout << "(6) " << result6 << "\n\n"; //auto result7 = jsonpath::json_query(data, path, // jsonpath::result_options::value | // jsonpath::result_options::nodups | // jsonpath::result_options::sort); (until 0.164.0) auto result7 = jsonpath::json_query(data, path, jsonpath::result_options::nodups | jsonpath::result_options::sort); (since 0.164.0) std::cout << "(7) " << result7 << "\n\n"; //auto result8 = jsonpath::json_query(data, path, // jsonpath::result_options::nodups | // jsonpath::result_options::sort); (until 0.164.0) auto result8 = jsonpath::json_query(data, path, jsonpath::result_options::nodups | jsonpath::result_options::sort | jsonpath::result_options::path); (since 0.164.0) std::cout << "(8) " << result8 << "\n\n"; } ``` Output: ```json (1) [5,2,2] (2) ["$[4]","$[1]","$[1]"] (3) [2,2,5] (4) ["$[1]","$[1]","$[4]"] (5) [5,2] (6) ["$[4]","$[1]"] (7) [2,5] (8) ["$[1]","$[4]"] ``` #### Callback The examples use the sample data file `books.json`, ```json { "books": [ { "category": "fiction", "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "category": "fiction", "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "category": "fiction", "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "category": "memoir", "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } ``` ```cpp #include #include #include using jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { std::ifstream is(/*path_to_books_file*/); json data = json::parse(is); std::string path = "$.books[?(@.price >= 22.0)]"; auto callback = [](const std::string& path, const json& val) { std::cout << path << ": " << val << "\n"; }; jsonpath::json_query(data, path, callback, jsonpath::result_options::path); } ``` Output: ``` $['books'][0]: {"author":"Haruki Murakami","category":"fiction","price":22.72,"title":"A Wild Sheep Chase"} $['books'][1]: {"author":"Sergei Lukyanenko","category":"fiction","price":23.58,"title":"The Night Watch"} ``` #### Custom functions ```cpp #include #include using json = jsoncons::json; namespace jsonpath = jsoncons::jsonpath; template class my_custom_functions : public jsonpath::custom_functions { public: my_custom_functions() { this->register_function("divide", // function name 2, // number of arguments [](jsoncons::span> params, std::error_code& ec) -> Json { const Json& arg0 = params[0].value(); const Json& arg1 = params[1].value(); if (!(arg0.is_number() && arg1.is_number())) { ec = jsonpath::jsonpath_errc::invalid_type; return Json::null(); } return Json(arg0.as() / arg1.as()); } ); } }; int main() { json root = json::parse(R"([{"foo": 60, "bar": 10},{"foo": 60, "bar": 5}])"); json result = jsonpath::json_query(root, "$[?(divide(@.foo, @.bar) == 6)]", jsonpath::result_options(), my_custom_functions()); std::cout << pretty_print(result) << "\n\n"; } ``` Output: ``` [{"bar": 10,"foo": 60}] ``` jsoncons-1.3.2/doc/ref/jsonpath/json_replace.md000066400000000000000000000203251477700171100215150ustar00rootroot00000000000000### jsoncons::jsonpath::json_replace ```cpp #include ``` ```cpp template void json_replace(Json& root, const Json::string_view_type& expr, T&& new_value, result_options options = result_options::nodups); (until 0.164.0) template void json_replace(Json& root, const Json::string_view_type& expr, T&& new_value, (1) result_options options = result_options::nodups, const custom_functions& funcs = custom_functions()); (since 0.164.0) template void json_replace(Json& root, const Json::string_view_type& expr, T&& new_value, const custom_functions& funcs = custom_functions()); (since 0.171.0) ``` ```cpp template void json_replace(Json& root, const Json::string_view_type& expr, BinaryCallback callback, result_options options = result_options::nodups); (until 0.164.0) template (2) void json_replace(Json& root, const Json::string_view_type& expr, BinaryCallback callback, result_options options = result_options::nodups, const custom_functions& funcs = custom_functions()); (since 0.164.0) template void json_replace(Json& root, const Json::string_view_type& expr, BinaryCallback callback, const custom_functions& funcs = custom_functions()); (since 0.171.0) ``` ```cpp template void json_replace(const allocator_set& alloc_set, Json& root, const Json::string_view_type& expr, T&& new_value, (3) (since 0.171.0) const custom_functions& funcs = custom_functions()); ``` ```cpp template void json_replace(const allocator_set& alloc_set, Json& root, const Json::string_view_type& expr, BinaryCallback callback, (4) (since 0.171.0) const custom_functions& funcs = custom_functions()); ``` (1) Searches for all values that match the JSONPath expression `expr` and replaces them with the specified value (2) Searches for all values that match a JSONPath expression `expr` and, for each result, calls a callback provided by the user with a path and mutable reference to the value. (3)-(4) Same as (1-2) except that `alloc` is used to allocate memory during expression compilation and evaluation. #### Parameters
root JSON value
expr JSONPath expression string
new_value The value to use as replacement
callback (until 0.161.0) A function object that accepts a const reference to a Json value and returns a Json value. It must have function call signature equivalent to

Json fun(const Json& val);

callback (since 0.161.0) A function object that accepts a path and a reference to a Json value. It must have function call signature equivalent to

void fun(const Json::string_view_type& path, Json& val);

#### Exceptions Throws a [jsonpath_error](jsonpath_error.md) if JSONPath evaluation fails. ### Examples The examples use the sample data file `books.json`, ```json { "books": [ { "category": "fiction", "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "category": "fiction", "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "category": "fiction", "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "category": "memoir", "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } ``` #### Change the price of A Wild Sheep Chase ```cpp #include #include #include using namespace jsoncons; using namespace jsoncons::jsonpath; int main() { std::ifstream is(/*path_to_books_file*/); json data = json::parse(is); jsonpath::json_replace(data,"$.books[?(@.title == 'A Wild Sheep Chase')].price",20.0); std::cout << pretty_print(data) << "\n\n"; } ``` Output: ```json { "books": [ { "author": "Haruki Murakami", "category": "fiction", "price": 20.0, "title": "A Wild Sheep Chase" }, { "author": "Sergei Lukyanenko", "category": "fiction", "price": 23.58, "title": "The Night Watch" }, { "author": "Graham Greene", "category": "fiction", "price": 21.99, "title": "The Comedians" }, { "author": "Phillips, David Atlee", "category": "memoir", "title": "The Night Watch" } ] } ``` #### Make a discount on all books ```cpp #include #include #include #include using namespace jsoncons; using namespace jsoncons::jsonpath; int main() { std::ifstream is(/*path_to_books_file*/); json data = json::parse(is); auto f = [](const std::string& /*location*/, json& price) { price = std::round(price.as() - 1.0); }; // make a discount on all books jsonpath::json_replace(data, "$.books[*].price", f); std::cout << pretty_print(data); } ``` Output: ```json { "books": [ { "author": "Haruki Murakami", "category": "fiction", "price": 22.0, "title": "A Wild Sheep Chase" }, { "author": "Sergei Lukyanenko", "category": "fiction", "price": 23.0, "title": "The Night Watch" }, { "author": "Graham Greene", "category": "fiction", "price": 21.0, "title": "The Comedians" }, { "author": "Phillips, David Atlee", "category": "memoir", "title": "The Night Watch" } ] } ``` #### Add a missing price ```cpp #include #include #include #include using namespace jsoncons; using namespace jsoncons::jsonpath; int main() { std::ifstream is(/*path_to_books_file*/); json data = json::parse(is); auto f = [](const std::string& /*location*/, json& book) { if (book.at("category") == "memoir" && !book.contains("price")) { book.try_emplace("price",140.0); } }; jsonpath::json_replace(data, "$.books[*]", f); std::cout << pretty_print(data); } ``` Output: ```json { "books": [ { "author": "Haruki Murakami", "category": "fiction", "price": 22.72, "title": "A Wild Sheep Chase" }, { "author": "Sergei Lukyanenko", "category": "fiction", "price": 23.58, "title": "The Night Watch" }, { "author": "Graham Greene", "category": "fiction", "price": 21.99, "title": "The Comedians" }, { "author": "Phillips, David Atlee", "category": "memoir", "price": 140.0, "title": "The Night Watch" } ] } ``` jsoncons-1.3.2/doc/ref/jsonpath/jsoncons-jsonpath-abnf.md000066400000000000000000000023651477700171100234410ustar00rootroot00000000000000``` Path = AbsolutePath / RelativePath AbsolutePath = Root S *AdditionalElements Root = "$" RelativePath = S NameOrWildcard S *AdditionalElements NameOrWildcard = Name / Wildcard S = *( WSP / CR / LF ) AdditionalElements = (("." / "..") NameOrWildcard) / Predicate Predicate = "[" S Expr S "]" Name = UnquotedName / SingleQuotedName / DoubleQuotedName Expr = RelativePath / Slice / Union / Filter Wildcard = "*" Name = UnquotedName / SingleQuotedName / DoubleQuotedName UnquotedName = UnquotedNameCharacter *AdditionalUnquotedNameCharacter SingleQuotedName = "'" *SingleQuotedNameCharacter "'" DoubleQuotedName = '"' *DoubleQuotedNameCharacter '"' UnquotedNameCharacter = ? any unicode character except *, spaces, '.' and '[' ? AdditionalUnquotedNameCharacter = ? any unicode character except spaces, '.' and '[' ? SingleQuotedNameCharacter = ? any unicode character except an unescaped "'" (single quote) ? DoubleQuotedNameCharacter = ? any unicode character except an unescaped '"' (double quote) ? Slice = [ SignedInteger ] ":" [ SignedInteger ] [ ":" [ NonZeroSignedInteger ] ] Filter = "?(" FilterExpr ")" Union = RelativePathOrFilter / "," RelativePathOrFilter *("," RelativePathOrFilter) RelativePathOrFilter = RelativePath / Filter ``` jsoncons-1.3.2/doc/ref/jsonpath/jsonpath.md000066400000000000000000000225611477700171100207030ustar00rootroot00000000000000### jsonpath extension The jsonpath extension implements [Stefan Goessner's JSONPath](http://goessner.net/articles/JsonPath/). It provides functions for search and "search and replace" using JSONPath expressions. ### Classes
jsonpath_expression Represents the compiled form of a JSONPath string. (since 0.161.0)
basic_json_location Represents the location of a specific value in a JSON document. (since 0.172.0)
basic_path_node Represents a normalized path as a singly linked list where each node has a pointer to its (shared) parent node. (since 0.172.0)
### Functions
make_expression Returns a compiled JSONPath expression for later evaluation. (since 0.161.0)
json_query Searches for all values that match a JSONPath expression
json_replace Search and replace using JSONPath expressions.
flatten
unflatten
Flattens a json object or array.
### jsoncons JSONPath [JSONPath](http://goessner.net/articles/JsonPath/) is a loosely standardized syntax for querying JSON. There are many implementations and they differ in significant ways, see Christoph Burgmer's [JSONPath comparison](https://cburgmer.github.io/json-path-comparison/). For details about the jsoncons implementation, see the document [JsonCons JSONPath](https://danielaparker.github.io/JsonCons.Net/articles/JsonPath/JsonConsJsonPath.html). In addition, the C++ implementation supports the following features: - A length property on arrays and strings that returns the number of elements in an array, or the number of codepoints in a string, e.g. `$[?(@.length == 2)]`. - Custom functions, allowing the user to augment the list of built in JSONPath functions with user-provided functions (since 0.164.0). ### Examples The examples use the sample data file `books.json`, ```json { "books": [ { "category": "fiction", "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "category": "fiction", "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "category": "fiction", "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "category": "memoir", "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } ``` [Using json_query](#eg1) [Using json_replace](#eg2) [Using make_expression](#eg3) [Custom functions](#eg4)
#### Using json_query ``` #include #include #include using json = jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { std::ifstream is(/*path_to_books_file*/); json data = json::parse(is); auto result1 = jsonpath::json_query(data, "$.books[1,1,3].title"); std::cout << "(1)\n" << pretty_print(result1) << "\n\n"; auto result2 = jsonpath::json_query(data, "$.books[1,1,3].title", jsonpath::result_options::path); std::cout << "(2)\n" << pretty_print(result2) << "\n\n"; //auto result3 = jsonpath::json_query(data, "$.books[1,1,3].title", // jsonpath::result_options::value | // jsonpath::result_options::nodups); (until 0.164.0) auto result3 = jsonpath::json_query(data, "$.books[1,1,3].title", jsonpath::result_options::nodups); (since 0.164.0) std::cout << "(3)\n" << pretty_print(result3) << "\n\n"; //auto result4 = jsonpath::json_query(data, "$.books[1,1,3].title", // jsonpath::result_options::nodups); (until 0.164.0) auto result4 = jsonpath::json_query(data, "$.books[1,1,3].title", jsonpath::result_options::nodups | jsonpath::result_options::path); (since 0.164.0) std::cout << "(4)\n" << pretty_print(result4) << "\n\n"; } ``` Output: ``` (1) [ "The Night Watch", "The Night Watch", "The Night Watch" ] (2) [ "$['books'][1]['title']", "$['books'][1]['title']", "$['books'][3]['title']" ] (3) [ "The Night Watch", "The Night Watch" ] (4) [ "$['books'][1]['title']", "$['books'][3]['title']" ] ```
#### Using json_replace ``` #include #include #include using json = jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { std::ifstream is(/*path_to_books_file*/); json data = json::parse(is); auto f = [](const std::string& /*location*/, json& price) { price = std::round(price.as() - 1.0); }; jsonpath::json_replace(data, "$.books[*].price", f); std::cout << pretty_print(data) << "\n"; } ``` Output: ``` { "books": [ { "author": "Haruki Murakami", "category": "fiction", "price": 22.0, "title": "A Wild Sheep Chase" }, { "author": "Sergei Lukyanenko", "category": "fiction", "price": 23.0, "title": "The Night Watch" }, { "author": "Graham Greene", "category": "fiction", "price": 21.0, "title": "The Comedians" }, { "author": "Phillips, David Atlee", "category": "memoir", "title": "The Night Watch" } ] } ```
#### Using make_expression A [jsoncons::jsonpath::Using make_expression](Using make_expression.md) represents the compiled form of a JSONPath expression. It allows you to evaluate a single compiled expression on multiple JSON documents. A `Using make_expression` is immutable and thread-safe. ``` #include #include #include using json = jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { auto expr = jsonpath::make_expression("$.books[1,1,3].title"); std::ifstream is(/*path_to_books_file*/); json data = json::parse(is); json result1 = expr.evaluate(data); std::cout << "(1)\n" << pretty_print(result1) << "\n\n"; json result2 = expr.evaluate(data, jsonpath::result_options::path); std::cout << "(2)\n" << pretty_print(result2) << "\n\n"; //json result3 = expr.evaluate(data, jsonpath::result_options::value | // jsonpath::result_options::nodups); (until 0.164.0) json result3 = expr.evaluate(data, jsonpath::result_options::nodups); (since 0.164.0) std::cout << "(3)\n" << pretty_print(result3) << "\n\n"; //json result4 = expr.evaluate(data, jsonpath::result_options::nodups); (until 0.164.0) json result4 = expr.evaluate(data, jsonpath::result_options::nodups | jsonpath::result_options::path); (since 0.164.0) std::cout << "(4)\n" << pretty_print(result4) << "\n\n"; } ``` Output: ``` (1) [ "The Night Watch", "The Night Watch", "The Night Watch" ] (2) [ "$['books'][1]['title']", "$['books'][1]['title']", "$['books'][3]['title']" ] (3) [ "The Night Watch", "The Night Watch" ] (4) [ "$['books'][1]['title']", "$['books'][3]['title']" ] ```
#### Custom functions ```cpp #include #include using json = jsoncons::json; namespace jsonpath = jsoncons::jsonpath; template class my_custom_functions : public jsonpath::custom_functions { public: my_custom_functions() { this->register_function("divide", // function name 2, // number of arguments [](jsoncons::span> params, std::error_code& ec) -> Json { const Json& arg0 = params[0].value(); const Json& arg1 = params[1].value(); if (!(arg0.is_number() && arg1.is_number())) { ec = jsonpath::jsonpath_errc::invalid_type; return Json::null(); } return Json(arg0.as() / arg1.as()); } ); } }; int main() { json root = json::parse(R"([{"foo": 60, "bar": 10},{"foo": 60, "bar": 5}])"); json result = jsonpath::json_query(root, "$[?(divide(@.foo, @.bar) == 6)]", jsonpath::result_options(), my_custom_functions()); // (since 0.164.0) std::cout << pretty_print(result) << "\n\n"; } ``` Output: ``` [{"bar": 10,"foo": 60}] ``` jsoncons-1.3.2/doc/ref/jsonpath/jsonpath_error.md000066400000000000000000000017631477700171100221150ustar00rootroot00000000000000### jsoncons::jsonpath::jsonpath_error ```cpp #include ```
`jsoncons::jsonpath::jsonpath_error` defines an exception type for reporting failures in jsonpath queries. ![jsonpath_error](./diagrams/jsonpath_error.png) #### Constructors ```cpp jsonpath_error(std::error_code ec); jsonpath_error(std::error_code ec, std::size_t line, std::size_t column); jsonpath_error(const jsonpath_error& other); ``` #### Member functions std::size_t line() const noexcept Returns the line number to the end of the text where the exception occurred. Line numbers start at 1. std::size_t column() const noexcept Returns the column number to the end of the text where the exception occurred. Column numbers start at 1. const char* what() const noexcept Constructs an error message, including line and column position #### Inherited from std::system_error const std::error_code code() const noexcept Returns an error code for this exception ### Example jsoncons-1.3.2/doc/ref/jsonpath/jsonpath_expression.md000066400000000000000000000032051477700171100231540ustar00rootroot00000000000000### jsoncons::jsonpath::jsonpath_expression ```cpp #include template class jsonpath_expression ``` #### Member functions
evaluate Select values from a JSON document
select (since 0.172.0) Select values from a JSON document
select_paths (since 0.172.0) Select paths of values selected from a JSON document
update (since 0.172.0) Update a JSON document in place
```cpp template void update(const_reference root, BinaryOp op); (1) (since 0.172.0) ``` (1) Evaluates the root value against the compiled JSONPath expression and calls a provided callback repeatedly with the results. #### Parameters
root Root JSON value
op A function object that accepts a path and a reference to a Json value. It must have function call signature equivalent to

void fun(const basic_path_node<Json::char_type>& path, Json& val);

#### Non-member functions
make_expression Returns a `jsonpath_expression` for later evaluation. (since 0.161.0)
jsoncons-1.3.2/doc/ref/jsonpath/jsonpath_expression/000077500000000000000000000000001477700171100226325ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/jsonpath/jsonpath_expression/evaluate.md000066400000000000000000000063101477700171100247620ustar00rootroot00000000000000### jsoncons::jsonpath::jsonpath_expression::evaluate ```cpp Json evaluate(reference root, result_options options = result_options()); (1) ``` ```cpp template void evaluate(reference root, BinaryOp op, result_options options = result_options()); (2) ``` (1) Evaluates the root value against the compiled JSONPath expression and returns an array of values or normalized path expressions. (2) Evaluates the root value against the compiled JSONPath expression and calls a provided callback repeatedly with the results. Note: This function is kept for backwards compatability. New code should use the [select](select.md) function. #### Parameters
root Root JSON value
op A function object that accepts a path and a reference to a Json value. It must have function call signature equivalent to

void fun(const Json::string_view_type& path, const Json& val);

result_options Result options, a bitmask of type result_options
### Examples The examples below uses the sample data file `books.json`, ```json { "books": [ { "category": "fiction", "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "category": "fiction", "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "category": "fiction", "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "category": "memoir", "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } ``` #### Select values from root value ```cpp #include #include using json = jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { auto expr = jsonpath::make_expression("$.books[?(@.price > avg($.books[*].price))].title"); std::ifstream is(/*path_to_books_file*/); json root = json::parse(is); json result = expr.evaluate(root); std::cout << pretty_print(result) << "\n\n"; } ``` Output: ``` [ "The Night Watch" ] ``` #### Select values with locations from root value ```cpp #include #include using json = jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { auto expr = jsonpath::make_expression("$.books[?(@.price >= 22.0)]"); std::ifstream is(/*path_to_books_file*/); json root = json::parse(is); auto callback = [](const std::string& path, const json& val) { std::cout << path << ": " << val << "\n"; }; expr.evaluate(root, callback, jsonpath::result_options::path); } ``` Output: ``` $['books'][0]: {"author":"Haruki Murakami","category":"fiction","price":22.72,"title":"A Wild Sheep Chase"} $['books'][1]: {"author":"Sergei Lukyanenko","category":"fiction","price":23.58,"title":"The Night Watch"} ``` jsoncons-1.3.2/doc/ref/jsonpath/jsonpath_expression/select.md000066400000000000000000000051571477700171100244430ustar00rootroot00000000000000### jsoncons::jsonpath::jsonpath_expression::select ```cpp Json select(const_reference root, result_options options = result_options()); (1) (since 0.172.0) ``` ```cpp template void select(const_reference root, BinaryOp op, result_options options = result_options()); (2) (since 0.172.0) ``` (1) Evaluates the root value against the compiled JSONPath expression and returns an array of values. (2) Evaluates the root value against the compiled JSONPath expression and calls a provided callback repeatedly with the results. #### Parameters
root Root JSON value
op A function object that accepts a path and a reference to a Json value. It must have function call signature equivalent to

void fun(const basic_path_node<Json::char_type>& path, const Json& val);

result_options Result options, a bitmask of type result_options
### Examples The examples below uses the sample data file `books.json`, ```json { "books": [ { "category": "fiction", "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "category": "fiction", "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "category": "fiction", "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "category": "memoir", "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } ``` #### Receive locations and values selected from a root value (since 0.172.0) ```cpp #include #include using json = jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { auto expr = jsoncons::jsonpath::make_expression("$.books[*]"); std::ifstream is(/*path_to_books_file*/); json doc = json::parse(is); auto op = [&](const jsonpath::path_node& path, const json& value) { if (value.at("category") == "memoir" && !value.contains("price")) { std::cout << jsonpath::to_string(path) << ": " << value << "\n"; } }; expr.select(root, op); } ``` Output: ``` $['books'][3]: {"author":"Phillips, David Atlee","category":"memoir","title":"The Night Watch"} ``` jsoncons-1.3.2/doc/ref/jsonpath/jsonpath_expression/select_paths.md000066400000000000000000000024641477700171100256400ustar00rootroot00000000000000### jsoncons::jsonpath::jsonpath_expression::select ```cpp std::vector> select_paths(const_reference root, result_options options = result_options::nodups | result_options::sort); (1) (since 0.172.0) ``` (1) Evaluates the root value against the compiled JSONPath expression and returns the locations of the selected values in the root value. #### Parameters
root Root JSON value
options (since 0.161.0) Result options, a bitmask of type result_options
### Examples #### Return locations of selected values ```cpp #include #include using json = jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { auto expr = jsoncons::jsonpath::make_expression("$.books[*]"); std::ifstream is(/*path_to_books_file*/); json doc = json::parse(is); std::vector paths = expr.select_paths(doc); for (const auto& path : paths) { std::cout << jsonpath::to_string(path) << "\n"; } } ``` Output: ``` [ $['books'][0] $['books'][1] $['books'][2] $['books'][3] ] ``` jsoncons-1.3.2/doc/ref/jsonpath/jsonpath_expression/update.md000066400000000000000000000030121477700171100244320ustar00rootroot00000000000000### jsoncons::jsonpath::jsonpath_expression::update ```cpp template void update(reference root, BinaryOp op); (1) (since 0.172.0) ``` (1) Evaluates the root value against the compiled JSONPath expression and calls a provided callback repeatedly with the results. #### Parameters
root Root JSON value
op A function object that accepts a path and a reference to a Json value. It must have function call signature equivalent to

void fun(const basic_path_node<Json::char_type>& path, Json& val);

The callback receives nodes with duplicates removed, and paths sorted in descending order. ### Examples #### Update in place ```cpp #include #include using json = jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { auto expr = jsoncons::jsonpath::make_expression("$.books[*]"); std::ifstream is(/*path_to_books_file*/); json doc = json::parse(is); auto callback = [](const jsonpath::path_node& /*path*/, json& book) { if (book.at("category") == "memoir" && !book.contains("price")) { book.try_emplace("price", 140.0); } }; expr.update(doc, callback); } ``` Output: ``` { "author": "Phillips, David Atlee", "category": "memoir", "price": 140.0, "title": "The Night Watch" } ``` jsoncons-1.3.2/doc/ref/jsonpath/jsonpath_grammer.md000066400000000000000000000050611477700171100224110ustar00rootroot00000000000000## Grammar The grammar is specified using ABNF, as described in RFC4234 ``` json-path = root-selector / selector_rhs root-selector = "$" selector = sub-selector / index-selector / identifier selector =/ "*" / union_expression selector =/ function-expression selector_rhs = "." ( selector / index-selector / identifier / "*" ) selector_rhs =/ union_selector index-selector = selector bracket-specifier / bracket-specifier union = "[" ( selector *( "," selector ) ) "]" bracket-specifier = "[" (number / "*" / slice-selector) "]" / "[]" bracket-specifier =/ "[?" selector "]" slice-selector = [number] ":" [number] [ ":" [number] ] function-selector = unquoted-string ( no-args / one-or-more-args ) no-args = "(" ")" one-or-more-args = "(" ( function-arg *( "," function-arg ) ) ")" function-arg = selector current-node = "@" preserved-escape = escape (%x20-26 / %28-5B / %x5D-10FFFF) raw-string-escape = escape ("'" / escape) literal = "`" json-value "`" unescaped-literal = %x20-21 / ; space ! %x23-5B / ; # - [ %x5D-5F / ; ] ^ _ %x61-7A ; a-z %x7C-10FFFF ; |}~ ... escaped-literal = escaped-char / (escape %x60) number = ["-"]1*digit digit = %x30-39 identifier = unquoted-string / quoted-string unquoted-string = (%x41-5A / %x61-7A / %x5F) *( ; A-Za-z_ %x30-39 / ; 0-9 %x41-5A / ; A-Z %x5F / ; _ %x61-7A) ; a-z quoted-string = quote 1*(unescaped-char / escaped-char) quote unescaped-char = %x20-21 / %x23-5B / %x5D-10FFFF escape = %x5C ; Back slash: \ quote = %x22 ; Double quote: '"' escaped-char = escape ( %x22 / ; " quotation mark U+0022 %x5C / ; \ reverse solidus U+005C %x2F / ; / solidus U+002F %x62 / ; b backspace U+0008 %x66 / ; f form feed U+000C %x6E / ; n line feed U+000A %x72 / ; r carriage return U+000D %x74 / ; t tab U+0009 %x75 4HEXDIG ) ; uXXXX U+XXXX ; The ``json-value`` is any valid JSON value ``` jsoncons-1.3.2/doc/ref/jsonpath/make_expression.md000066400000000000000000000127761477700171100222600ustar00rootroot00000000000000### jsoncons::jsonpath::make_expression ```cpp #include ``` ```cpp template jsonpath_expression make_expression(const Json::string_view_type& expr); (until 0.164.0) ``` ```cpp template (1) jsonpath_expression make_expression(const Json::string_view_type& expr, const custom_functions& funcs = custom_functions()); (since 0.164.0) ``` ```cpp template jsonpath_expression make_expression(const Json::string_view_type& expr, std::error_code& ec); (2) ``` ```cpp template jsonpath_expression make_expression(const Json::string_view_type& expr, const custom_functions& funcs, std::error_code& ec); (3) (since 0.164.0) ``` ```cpp template (4) (since 0.170.0) jsonpath_expression make_expression(const allocator_set& alloc_set, Json::string_view_type& expr, const custom_functions& funcs = custom_functions()); ``` ```cpp template (5) (since 0.170.0) jsonpath_expression make_expression(const allocator_set& alloc_set, Json::string_view_type& expr, std::error_code& ec); ``` ```cpp template (6) (since 0.170.0) jsonpath_expression make_expression(const allocator_set& alloc_set, Json::string_view_type& expr, const custom_functions& funcs, std::error_code& ec); ``` (1) Makes a [jsonpath_expression](jsonpath_expression.md) from the JSONPath expression `expr`. (2-3) Makes a [jsonpath_expression](jsonpath_expression.md) from the JSONPath expression `expr`. (4-6) Same as (1-3) except that `alloc` is used to allocate memory during expression compilation and evaluation. #### Parameters
expr JSONPath expression string
funcs Custom functions
ec out-parameter for reporting errors in the non-throwing overload
#### Return value Returns a [jsonpath_expression](jsonpath_expression.md) object that represents the JSONPath expression. #### Exceptions (1) throws a [jsonpath_error](jsonpath_error.md) if JSONPath compilation fails. (2) sets the out-parameter `ec` to the [jsonpath_error_category](jsonpath_errc.md) if JSONPath compilation fails. ### Examples #### Custom functions ```cpp #include #include using json = jsoncons::json; namespace jsonpath = jsoncons::jsonpath; template class my_custom_functions : public jsonpath::custom_functions { public: my_custom_functions() { this->register_function("divide", // function name 2, // number of arguments [](jsoncons::span> params, std::error_code& ec) -> Json { const Json& arg0 = params[0].value(); const Json& arg1 = params[1].value(); if (!(arg0.is_number() && arg1.is_number())) { ec = jsonpath::jsonpath_errc::invalid_type; return Json::null(); } return Json(arg0.as() / arg1.as()); } ); } }; int main() { json root = json::parse(R"([{"foo": 60, "bar": 10},{"foo": 60, "bar": 5}])"); auto expr = jsonpath::make_expression("$[?(divide(@.foo, @.bar) == 6)]", my_custom_functions()); json result = expr.evaluate(root); std::cout << result << "\n\n"; } ``` Output: ``` [{"bar": 10,"foo": 60}] ``` #### make_expression with stateful allocator ```cpp #include // Assuming C++ 17 #include #include #include "free_list_allocator.hpp" // for free_list_allocator using my_alloc = free_list_allocator; // an allocator with a single-argument constructor using my_json = jsoncons::basic_json; namespace jsonpath = jsoncons::jsonpath; int main() { auto alloc = my_alloc(1); // until 0.171.0 // jsoncons::json_decoder decoder(jsoncons::result_allocator_arg, // alloc, alloc); // since 0.170.1 jsoncons::json_decoder decoder(alloc, alloc); std::ifstream is(/*path_to_books_file*/); jsoncons::basic_json_reader,my_alloc> reader(is, decoder, alloc); reader.read(); my_json doc = decoder.get_result(); std::string_view p{"$.books[?(@.category == 'fiction')].title"}; auto expr = jsonpath::make_expression(combine_allocators(alloc), p); auto result = expr.evaluate(doc); std::cout << pretty_print(result) << "\n\n"; } ``` Output: ```json [ "A Wild Sheep Chase", "The Night Watch", "The Comedians" ] ``` jsoncons-1.3.2/doc/ref/jsonpath/path_node_kind.md000066400000000000000000000003301477700171100220110ustar00rootroot00000000000000### jsoncons::jsonpath::path_node_kind ```cpp enum class result_options { root, name, index }; (since 0.172.0) ``` Indicates the kind of path node jsoncons-1.3.2/doc/ref/jsonpath/remove.md000066400000000000000000000076351477700171100203570ustar00rootroot00000000000000### jsoncons::jsonpath::remove ```cpp #include template std::size_t remove(Json& root, const basic_json_location& location); (1) template std::size_t remove(Json& root, const jsoncons::basic_string_view& path_string); (2) ``` (1) Removes a single node at the specified location. Returns the number of nodes removed (0 or 1). (2) Finds all the nodes that match the given JSONPath expression and removes them one by one. Returns the number of nodes removed. #### Parameters
root Root JSON value
location A basic_json_location
#### Return value The number of items removed. ### Exceptions None ### Examples #### Remove nodes one by one at a specified location ```cpp #include #include using jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { std::string json_string = R"( { "books": [ { "category": "fiction", "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "category": "fiction", "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "category": "fiction", "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "category": "memoir", "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } )"; json doc = json::parse(json_string); auto expr = jsonpath::make_expression("$.books[?(@.category == 'fiction')]"); std::vector locations = expr.select_paths(doc, jsonpath::result_options::sort_descending | jsonpath::result_options::sort_descending); for (const auto& location : locations) { std::cout << jsonpath::to_string(location) << "\n"; } std::cout << "\n"; for (const auto& location : locations) { jsonpath::remove(doc, location); } std::cout << jsoncons::pretty_print(doc) << "\n\n"; } ``` Output: ``` $['books'][2] $['books'][1] $['books'][0] { "books": [ { "author": "Phillips, David Atlee", "category": "memoir", "title": "The Night Watch" } ] } ``` #### Remove nodes in a single step ```cpp #include #include using jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { std::string json_string = R"( { "books": [ { "category": "fiction", "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "category": "fiction", "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "category": "fiction", "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "category": "memoir", "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } )"; json doc = json::parse(json_string); std::size_t n = jsonpath::remove(doc, "$.books[?(@.category == 'fiction')]"); std::cout << "Number of nodes removed: " << n << "\n\n"; std::cout << jsoncons::pretty_print(doc) << "\n\n"; } ``` Output: ``` Number of nodes removed: 3 { "books": [ { "author": "Phillips, David Atlee", "category": "memoir", "title": "The Night Watch" } ] } ``` jsoncons-1.3.2/doc/ref/jsonpath/replace.md000066400000000000000000000072531477700171100204710ustar00rootroot00000000000000### jsoncons::jsonpath::replace ```cpp #include template std::pair replace(Json& root, const basic_json_location& location, const Json& new_value, bool create_if_missing=false) ``` Replace a JSON value in a JSON document at a specified location. If `create_if_missing` is `false`, the target location must exist for the replacement to succeed. If `create_if_missing` is `true`, and if the target location specifies object members that do not already exist, the missing objects and members are added. #### Parameters
root Root JSON value
location A basic_json_location
new_value Replacement value
create_if_missing Create key-object pairs when object key is missing
#### Return value Returns a `std::pair`. If the replacement succeeded, the bool component is `true`, and the `Json*` component points to the new value in the `root`. If the replacement failed, the bool component is `false`. #### Exceptions None ### Examples ```cpp #include #include #include #include using jsoncons::json; namespace jsonpath = jsoncons::jsonpath; int main() { std::string json_string = R"( {"books": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour" }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3" } ] } )"; json doc = json::parse(json_string); json new_value{13.0}; jsonpath::json_location loc0 = jsonpath::json_location::parse("$.books[0].price"); auto result0 = jsonpath::replace(doc, loc0, new_value); assert(result0.second); assert(result0.first == std::addressof(doc.at("books").at(0).at("price"))); assert(doc.at("books").at(0).at("price") == new_value); jsonpath::json_location loc1 = jsonpath::json_location::parse("$.books[1].price"); auto result1 = jsonpath::replace(doc, loc1, new_value); assert(!result1.second); // create_if_missing is true result1 = jsonpath::replace(doc, loc1, new_value, true); assert(result1.second); assert(result1.first == std::addressof(doc.at("books").at(1).at("price"))); assert(doc.at("books").at(1).at("price") == new_value); jsonpath::json_location loc2 = jsonpath::json_location::parse("$.books[2].kindle.price"); auto result2 = jsonpath::replace(doc, loc2, new_value, true); assert(result2.second); assert(result2.first == std::addressof(doc.at("books").at(2).at("kindle").at("price"))); assert(doc.at("books").at(2).at("kindle").at("price") == new_value); std::cout << pretty_print(doc) << "\n\n"; } ``` Output: ```json { "books": [ { "author": "Nigel Rees", "category": "reference", "price": 13.0, "title": "Sayings of the Century" }, { "author": "Evelyn Waugh", "category": "fiction", "price": 13.0, "title": "Sword of Honour" }, { "author": "Herman Melville", "category": "fiction", "isbn": "0-553-21311-3", "kindle": { "price": 13.0 }, "title": "Moby Dick" } ] } ``` jsoncons-1.3.2/doc/ref/jsonpath/result_options.md000066400000000000000000000011341477700171100221370ustar00rootroot00000000000000### jsoncons::jsonpath::result_options ```cpp enum class result_options { value = 1, path = 2, no_dups = 4 | path, sort = 8 | path }; (until 0.164.0) enum class result_options { value=0, nodups=1, sort=2, path=4 }; (since 0.164.0) enum class result_options { value=0, nodups=1, sort=2, sort_descending=4, path=8 }; (since 0.172.0) ``` A [BitmaskType](https://en.cppreference.com/w/cpp/named_req/BitmaskType) used to specify result options for JSONPath queries. jsoncons-1.3.2/doc/ref/jsonpointer/000077500000000000000000000000001477700171100172515ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/jsonpointer/add.md000066400000000000000000000103151477700171100203230ustar00rootroot00000000000000### jsoncons::jsonpointer::add Adds a value to an object or inserts it into an array at the target location. If a value already exists at the target location, that value is replaced. ```cpp #include template void add(Json& target, const basic_json_pointer& location, T&& value, bool create_if_missing = false); (1) (since 0.167.0) template void add(Json& target, const basic_json_pointer& location, T&& value, std::error_code& ec); (2) (since 0.167.0) template void add(Json& target, const basic_json_pointer& location, T&& value, bool create_if_missing, std::error_code& ec); (3) (since 0.167.0) template void add(Json& target, const StringSource& location_str, T&& value, bool create_if_missing = false); (4) template void add(Json& target, const StringSource& location_str, T&& value, std::error_code& ec); (5) template void add(Json& target, const StringSource& location_str, T&& value, bool create_if_missing, std::error_code& ec); (6) (since 0.162.0) ``` Inserts a value into the target at the specified location, or if the location specifies an object member that already has the same key, assigns the new value to that member - If `location` specifies an array index, a new value is inserted into the array at the specified index. - If `location` specifies an object member that does not already exist, a new member is added to the object. - If `location` specifies an object member that does exist, that member's value is replaced. #### Parameters
target JSON value
location A basic_json_pointer
location_str A JSON Pointer provided as a string, string view, or C-string
value New or replacement value
create_if_missing (since 0.162.0) Create key-object pairs when object key is missing
ec out-parameter for reporting errors in the non-throwing overload
#### Return value None ### Exceptions (1) Throws a [jsonpointer_error](jsonpointer_error.md) if `add` fails. (2)-(3) Sets the out-parameter `ec` to the [jsonpointer_error_category](jsonpointer_errc.md) if `add` fails. ### Examples #### Insert or assign an object member at a location_str that already exists ```cpp #include #include using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { auto target = json::parse(R"( { "foo": "bar", "baz" : "abc"} )"); std::error_code ec; jsonpointer::add(target, "/baz", json("qux"), ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << target << '\n'; } } ``` Output: ```json {"baz":"qux","foo":"bar"} ``` #### Add a value to a location_str after creating objects when missing object keys ```cpp #include #include #include using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { std::vector keys = {"foo","bar","baz"}; jsonpointer::json_pointer location_str; for (const auto& key : keys) { location_str /= key; } json doc; jsonpointer::add(doc, location_str, "str", true); std::cout << pretty_print(doc) << "\n\n"; } ``` Output: ```json { "foo": { "bar": { "baz": "str" } } } ``` jsoncons-1.3.2/doc/ref/jsonpointer/add_if_absent.md000066400000000000000000000150201477700171100223330ustar00rootroot00000000000000### jsoncons::jsonpointer::add_if_absent Adds a value to an object or inserts it into an array at the target location, if a value does not already exist at that location. ```cpp #include template void add_if_absent(Json& target, const basic_json_pointer& location, T&& value, bool create_if_missing = false); (1) template void add_if_absent(Json& target, const basic_json_pointer& location, T&& value, std::error_code& ec); (2) template void add_if_absent(Json& target, const basic_json_pointer& location, T&& value, bool create_if_missing, std::error_code& ec); (3) template void add_if_absent(Json& target, const StringSource& location_str, T&& value, bool create_if_missing = false); (4) template void add_if_absent(Json& target, const StringSource& location_str, T&& value, std::error_code& ec); (5) template void add_if_absent(Json& target, const StringSource& location_str, T&& value, bool create_if_missing, std::error_code& ec); (6) ``` Inserts a value into the target at the specified location, if the location doesn't specify an object member that already has the same key. - If `location` specifies an array index, a new value is inserted into the array at the specified index. - If `location` specifies an object member that does not already exist, a new member is added to the object. #### Parameters
target JSON value
location A basic_json_pointer
location_str A JSON Pointer provided as a string, string view, or C-string
value New value
create_if_missing (since 0.162.0) Create key-object pairs when object key is missing
ec out-parameter for reporting errors in the non-throwing overload
#### Return value None ### Exceptions (1) Throws a [jsonpointer_error](jsonpointer_error.md) if `add_if_absent` fails. (2) Sets the out-parameter `ec` to the [jsonpointer_error_category](jsonpointer_errc.md) if `add_if_absent` fails. ### Examples #### Add a member to a target location that does not already exist ```cpp #include #include // for brevity using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { auto target = json::parse(R"( { "foo": "bar"} )"); std::error_code ec; jsonpointer::add_if_absent(target, "/baz", json("qux"), ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << target << '\n'; } } ``` Output: ```json {"baz":"qux","foo":"bar"} ``` #### Add an element to the second position in an array ```cpp #include #include using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { auto target = json::parse(R"( { "foo": [ "bar", "baz" ] } )"); std::error_code ec; jsonpointer::add_if_absent(target, "/foo/1", json("qux"), ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << target << '\n'; } } ``` Output: ```json {"foo":["bar","qux","baz"]} ``` #### Add a value at the end of an array ```cpp #include #include using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { auto target = json::parse(R"( { "foo": [ "bar", "baz" ] } )"); std::error_code ec; jsonpointer::add_if_absent(target, "/foo/-", json("qux"), ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << target << '\n'; } } ``` Output: ```json {"foo":["bar","baz","qux"]} ``` #### Try to add an object member at a location that already exists ```cpp #include #include using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { auto target = json::parse(R"( { "foo": "bar", "baz" : "abc"} )"); std::error_code ec; jsonpointer::add_if_absent(target, "/baz", json("qux"), ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << target << '\n'; } } ``` Output: ``` Key already exists ``` #### Try to add a value to a location in an array that exceeds the size of the array ```cpp #include #include using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { auto target = json::parse(R"( { "foo": [ "bar", "baz" ] } )"); std::error_code ec; jsonpointer::add(target, "/foo/3", json("qux"), ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << target << '\n'; } } ``` Output: ``` Index exceeds array size ``` #### Add a value to a location after creating objects when missing object keys ```cpp #include #include #include using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { std::vector keys = { "foo","bar","baz" }; jsonpointer::json_pointer location; for (const auto& key : keys) { location /= key; } json doc; jsonpointer::add_if_absent(doc, location, "str", true); std::cout << pretty_print(doc) << "\n\n"; } ``` Output: ```json { "foo": { "bar": { "baz": "str" } } } ``` jsoncons-1.3.2/doc/ref/jsonpointer/basic_json_pointer.md000066400000000000000000000137241477700171100234540ustar00rootroot00000000000000### jsoncons::jsonpointer::basic_json_pointer ```cpp #include template class basic_json_pointer ``` Two specializations for common character types are defined: Type |Definition ----------|------------------------------ json_pointer |`basic_json_pointer` (since 0.159.0) json_ptr |`basic_json_pointer` (until 0.159.0) wjson_pointer |`basic_json_pointer` (since 0.159.0) wjson_ptr |`basic_json_pointer` (unitl 0.159.0) Objects of type `basic_json_pointer` represent a JSON Pointer. #### Member types Type |Definition ------------|------------------------------ char_type | `CharT` string_type | `std::basic_string` string_view_type | `jsoncons::basic_string_view` const_iterator | A constant [LegacyRandomAccessIterator](https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator) with a `value_type` of `std::basic_string` iterator | An alias to `const_iterator` #### Constructors basic_json_pointer(); (1) explicit basic_json_pointer(const string_view_type& str); explicit basic_json_pointer(const string_view_type& str, std::error_code& ec); (2) basic_json_pointer(const basic_json_pointer&); (3) basic_json_pointer(basic_json_pointer&&) noexcept; (4) (1) Constructs an empty `basic_json_pointer`. (2) Constructs a `basic_json_pointer` from a string representation or a URI fragment identifier (starts with `#`). #### operator= basic_json_pointer& operator=(const basic_json_pointer&); basic_json_pointer& operator=(basic_json_pointer&&); #### Modifiers basic_json_pointer& append(const string_type& s); (since 0.172.0) Appends the token s. template basic_json_pointer& append(IntegerType index) (since 0.172.0) Appends the token `index`. This overload only participates in overload resolution if `IntegerType` is an integer type. basic_json_pointer& operator/=(const string_type& s) Appends the token s. template basic_json_pointer& operator/=(IntegerType index) Appends the token `index`. This overload only participates in overload resolution if `IntegerType` is an integer type. basic_json_pointer& operator+=(const basic_json_pointer& ptr) Concatenates the current pointer and the specified pointer `ptr`. #### Iterators iterator begin() const; iterator end() const; Iterator access to the tokens in the pointer. #### Accessors bool empty() const Checks if the pointer is empty string_type to_string() const Returns a JSON Pointer represented as a string value, escaping any `/` or `~` characters. #### Static member functions static parse(const string_view_type& str); static parse(const string_view_type& str, std::error_code& ec); Constructs a `basic_json_pointer` from a string representation or a URI fragment identifier (starts with `#`). #### Non-member functions basic_json_pointer operator/(const basic_json_pointer& lhs, const basic_string& s); Concatenates a JSON Pointer pointer and a string. Effectively returns basic_json_pointer(lhs) /= s. template basic_json_pointer operator/(const basic_json_pointer& lhs, IntegerType index); Concatenates a JSON Pointer pointer and an index. Effectively returns basic_json_pointer(lhs) /= index. This overload only participates in overload resolution if `IntegerType` is an integer type. template basic_json_pointer operator+( const basic_json_pointer& lhs, const basic_json_pointer& rhs ); Concatenates two JSON Pointers. Effectively returns basic_json_pointer(lhs) += rhs. template bool operator==(const basic_json_pointer& lhs, const basic_json_pointer& rhs); template bool operator!=(const basic_json_pointer& lhs, const basic_json_pointer& rhs); std::string to_string(const json_pointer& ptr); (since 0.172.0) std::wstring to_wstring(const wjson_pointer& ptr); (since 0.172.0) template std::basic_ostream& operator<<(std::basic_ostream& os, const basic_json_pointer& ptr); Performs stream output ### Examples #### Iterate over the tokens in a JSON Pointer ```cpp #include #include // for brevity namespace jsonpointer = jsoncons::jsonpointer; int main() { jsonpointer::json_pointer ptr("/store/book/1/author"); std::cout << "(1) " << ptr << "\n\n"; std::cout << "(2)\n"; for (const auto& token : ptr) { std::cout << token << "\n"; } std::cout << "\n"; } ``` Output: ``` (1) /store/book/1/author (2) store book 1 author ``` #### Append tokens to a JSON Pointer ```cpp #include #include namespace jsonpointer = jsoncons::jsonpointer; int main() { jsonpointer::json_pointer ptr; ptr /= "a/b"; ptr /= ""; ptr /= "m~n"; std::cout << "(1) " << ptr << "\n\n"; std::cout << "(2)\n"; for (const auto& token : ptr) { std::cout << token << "\n"; } std::cout << "\n"; } ``` Output: ``` (1) /a~1b//m~0n (2) a/b m~n ``` #### Concatentate two JSONPointers ```cpp #include #include namespace jsonpointer = jsoncons::jsonpointer; int main() { jsonpointer::json_pointer ptr("/a~1b"); ptr += jsonpointer::json_pointer("//m~0n"); std::cout << "(1) " << ptr << "\n\n"; std::cout << "(2)\n"; for (const auto& token : ptr) { std::cout << token << "\n"; } std::cout << "\n"; } ``` Output: ``` (1) /a~1b//m~0n (2) a/b m~n ``` jsoncons-1.3.2/doc/ref/jsonpointer/contains.md000066400000000000000000000027001477700171100214100ustar00rootroot00000000000000### jsoncons::jsonpointer::contains ```cpp #include template bool contains(const Json& root, const basic_json_pointer& location); template bool contains(const Json& root, const StringSource& location_str); ``` #### Parameters
root Root JSON value
location A basic_json_pointer
location_str A JSON Pointer provided as a string, string view, or C-string
#### Return value Returns `true` if the json doc contains the given JSON Pointer, otherwise `false' ### Examples #### Examples from [RFC6901](https://tools.ietf.org/html/rfc6901) ```cpp #include #include namespace jsonpointer = jsoncons::jsonpointer; int main() { // Example from RFC 6901 auto j = jsoncons::json::parse(R"( { "foo": ["bar", "baz"], "": 0, "a/b": 1, "c%d": 2, "e^f": 3, "g|h": 4, "i\\j": 5, "k\"l": 6, " ": 7, "m~n": 8 } )"); std::cout << "(1) " << jsonpointer::contains(j, "/foo/0") << '\n'; std::cout << "(2) " << jsonpointer::contains(j, "e^g") << '\n'; } ``` Output: ```json (1) true (2) false ``` jsoncons-1.3.2/doc/ref/jsonpointer/diagrams/000077500000000000000000000000001477700171100210405ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/jsonpointer/diagrams/jsonpointer_error.png000066400000000000000000000225601477700171100253360ustar00rootroot00000000000000PNG  IHDRptEXtmxfile%3Cmxfile%20modified%3D%222020-03-24T19%3A34%3A41.440Z%22%20host%3D%22app.diagrams.net%22%20agent%3D%22Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F80.0.3987.149%20Safari%2F537.36%22%20etag%3D%22wRRdzmeu8VQxVFAc2fc3%22%20version%3D%2212.9.2%22%20type%3D%22device%22%3E%3Cdiagram%20id%3D%22iK-0d-7Yl-5MlnfMu26I%22%20name%3D%22Page-1%22%3E7Vhbb9owFP41PHYicWjhkdHLNtRqHZOgT5UVnybuEps5BsJ%2B%2FezGuTgJl2pRqbYhJHw%2B28fOd853YtNDkzi9EXgZ3nICUc%2Ftk7SHLnuu6%2FTRUP1oZJsh3sgAgaDEDCqBGf0F%2BUyDriiBxBooOY8kXdqgzxkDX1oYFoJv7GFPPLJXXeIAGsDMx1ETnVMiwwwdDvol%2FgloEOYrO33TE%2BN8sAGSEBO%2BqUDoqocmgnOZteJ0ApEmL%2Bclm3e9o7fYmAAmj5lwdfc9ZdP7WehOfk7l%2FDZ%2BSL%2BcGS9rHK3MAydSjR%2BrL6Q%2BLCXlzGxfbnNOBF8xAtptv4c%2BbkIqYbbEvu7dqCxQWCjjSFmOaja3ma8JQkJagcy2b4DHIMVWDTG954ZBk0IjY27KeBSsh5VYeAbDJgWCwnHJkmoYol5B2sVu0sSKSRrDI6jUEycnzu2%2FM%2BaGDeYaHAEjY61bZfkRThLq27RASuXCMKjbD7r9YWCsy7TSdbnNDaY2v8gdaKMyS5vltBcrn7czBAlfCR8Op4jEIgB5WH9ArCrUDGglYoOWgOWYgAhLurZrV1sUzQpfOVVPVuSLZ6dLkT65h%2ByxzaRqqan5Gdl%2BnEHNT0ZLw89LShUPfVSWBevb0J3eLfA3CM7m91NYT2FfUUu2iYT4ncgTeaeTZytx7l8oz30ZclCeF%2F%2Fl2b08USPLnhPOlno5EF1I84lG0YRHyo2ei%2BDlo%2FBECv4DKj3oHI0Q6UbMg9q71nFPrebzf0XNqKnmfap%2FJ2pGtWNtccx9rZw9p%2BbIeVs9N4%2FDn1kIgkrMVNjU1Y%2FiQOC4kXxKWNJON1ugjDOoqdlAOKIB0zkLumQoQMuUqkvb2HTElBC9TGulsGtJB9KvX1DcNumjlkxyuzhnex5h8Dif3rnPi7E%2FuH92ZztK7GOnV7oGPy0sHn30Kd5Bb3I1aaOsi2r5R5WvVpZac9I6sOwM%2FKkqWuMVWA%2FWsRXNubAdoWFXFU2Z5T8u2fDyfyt09Rs%3D%3C%2Fdiagram%3E%3C%2Fmxfile%3E=IDATx^}Uջ0FAMSC!zHQZLŒ:fNL*aD*4Z1$^E"'LCxk{>{ę9k9k}Zk>DCT+I>}TB0DdA14K1@$3HPxñi&z76v|^{3gb:Q]]uuu\awYUeLƍ&9By]58p=љs,HsΙ\0`mٲhz-\O~s8\p]|I={6m޼97%DŽwў/U[+.Z˸޽ۼyLRСC4w\#AiΝ1![w-0J tP f?>mozj40Aa֖3-<7_<׀؟n _|/̓ Ob|0k֬\ǎ3q^|w{E&;v4b4lq2iH;-0:~M!f78Ҽla?6W 6ږXygsN^It߃LkА_r.HK$EK6~MuP.iFܰssEJP rUxv ]rTW#=_|ьSLɻEtt9rm!P?o|*w1\Oi^͐v^n͑L&<}r~b '`k v<?sKex;A;KfCL/L}^iOA=bgY9c׽95/.s&N>|Xd3!h<Vʽy\Hҹ"τUWWZ裏+A û ieBc:^DmoPV}'^DØ$LKK1~^4h1Hi^=a{ͻ};c: k^2K~3v3rO{)^^F^9 caW:4 "g^{[Keż=zlg =tAѨCw1#G+W_uW {Rggg ڮ`M0̈́}V^y2:tY 23>K-=W ti:d%E0ƍMA˅Š1k$r~+Lw5ͻ'H9 gxƱǍ|彦/NTa:W$_xqܸqgׯ٪xtW" o%K*L8*xI U{BÇyy>`L !k}ztTUU.Lw>@|ĸM}ÛA+ޕ7-H>QLG!ӡ=_dCKę3I_nȁ`λv+_GRJGҹbԃyo߾\>D2~'UӧO>O }DXӡ5_duC*˹&[!p*="9 cN)uئ^r9'L@SN%~o}մz#rGf?>j^{|iV_iid^=MF'O4za*j #o VZxsrU>jOi'z1WbG--W+kh4|p:{l0QU}dti҅=BW_C[?-Xa> (i9G]:AUdzebG⠥zhOIQ0I)Ut(ӶAuw׮:(ĿkH0Es]`:Π(] q=Y.hC{|s\qC+s#zP(5Xڿr_+7K7)=R3&a:KmI Q_~}_5H|tD7tZRI =bS=r׿#-Ql-o=r_A~G#lf$S#EP(X^׮*- GIB0՚A!(X\A= JP]Ѧk*-+3B U.BveV~7Zj}G/x TWW_T}?|`Gy>C慨ݬvp[jVmr1侼kx~'^xmۖ۲>V:Nm  |^9hhhFZb=駟r<µkd,eOoo96b |  NMM1<@~^ao͛̕{i?ӂ Llc.KϿY{8ôӡ@@"o?\K/BQWWg&d<7˄,C؜D,%*L---Tm:]t.?uTL&8Bg?Xe~[{&F^okk3>LGƍ  xW:q_π^ŸrJnA n߾k(g*t? M}@UL>[Uxþ?[C2鋹ɧ=#d;W^5=Aʯ}m  P4g:WdmB+|k:Vfrbt5b2AOde t3=0E6nB +2iΟ?Z[[s=ӑoCd9 T̙0>[0:uAT P1S1}JfCX) "C$WYFLGH$V:@ MrWltt *Z&ZbG#)Qb8XT  7'9Л@Zz$m6`:tf>LN]T &sG#-sTLGL Q ?'9萟@Rzm6`:t`:tꂨ@b$5U 0q8"VnG$. f6`:tΞ= fH(LGhT( P,b-cڴit)0a$tpUU-YMh{9s星O8A'O6?Skk'&{ss@ ]~9sc߿?۷.^ov?N&M2]5qDzPSSC4dӧÇӌ3hݺum۶JOo7nܸӯ_?׏?{B:D&n(D 8tPnիW?a[uuuc?~|h,_6 .41cCdCxbjkk#FcF3g-nk@le{0H7y֬Y5رc&˗/T핸i`=Fiǟy^`YHZtD†@(tmdn@{n)SE =  ~nw͚5eV5Ռy]6r!Ɔccm:Ν;k?cٲeT]]+߭[_~9(E(nK ~[^ + ---bLܹs{u:krk:xľx[0Wzd5P| uE9`:\PE @TaOjV:-lqdȹ { Ql?a:fDC*@#F* {kx:y ^=>}9;,d.o߿ o ?q(0*t4b:?d,O2֊}dM+č;p@4}#5F1ODHX=4b+o0Nri|gE+IA$ӑMkH@I@}q>om(Kj`:\EHUC P&˜2JE =*BƲLGYˇA@7Lrb40YT}`KtfGHP(L3@b40YT}`KtfGHP(L3@b40YT}`KtfGHP(L3@b40YT}`KtfGHP(L3@b40YT}`KtfGHP(L3@b40YT}`KtfGHP(L3@'9\ dLGFgA@@ =0G   )0t-@tdJnt@@#ӑ{   "ӑ)YHLGz2dLGFgA@@ =0G   )0t-@tdJnt@@#ӑ{   "ӑ)YHLGz2dLGFgA@@ =0G   )0t-@tdJnt@@#ӑ{   "ӑ)YHLGz2dLGFgA@@ =0G   )0t-@tdJnt@@#ӑ{   "ӑ)YHLGz2dLGFgA@@ =0G   )0t-W nZh]ƌϛ2۷oG"qZd ͛7ƎH Ei߾}t1ڸq#Z9iҤ6J Q *j$i:Nm7IPb:Z[[I6@P* *O?b1l0jjj2jnnF'ҥK:::r#'Nɓ'{'n7nGٳz Bs̡Ç;p@SǏV 8:ʵˆ/?#!?O?4ݼy.olTΝkWWW{啝|ر֯_oX.D O5D33g… a'3yxUS˴xbjkk#۸&K3eS7 /_oE15jkk}K OǏ7F/{{͐Ojo1M;p@ݶA( 0M~c'@gc::;;Yٖdž."^nرw/C˿~{u?ԸDN DC l};}͘1vmVD|û!7\gvm#˖7}6ȜxrdDMKt[ 00&(.L_zd v257 kvt%fa!ۼQt~@ %Ӂ a: |A{xW šxlْ;.ცV}^ᾋ:aܹY3A#_`:bLnT1"!>-[+V~ܙ{{?7A@]z QQ@(O0#=Ԩ8! $@"`:F@@@`:   H3;IIENDB`jsoncons-1.3.2/doc/ref/jsonpointer/flatten.md000066400000000000000000000101701477700171100212270ustar00rootroot00000000000000### jsoncons::jsonpointer::flatten ```cpp #include template Json flatten(const Json& value); (1) template Json unflatten(const Json& value, unflatten_options options = unflatten_options::none); (2) (since 0.150.0) ``` (1) flattens a json object or array into a single depth object of JSON Pointer-value pairs. - The keys in the flattened object are JSONPointer's. - (until 0.160.0) The values are primitive (string, number, boolean, or null). Empty objects or arrays become null. - (since 0.160.0) The values can be string, number, boolean, null, empty object (`{}`) or empty array (`[]`). (2) unflattens a json object of JSON Pointer-value pairs. There is no unique solution, an integer appearing in a path could be an array index or it could be an object key. The default is to attempt to preserve arrays. [unflatten_options](unflatten_options.md) provides additonal options. #### Return value (1) A flattened json object of JSON Pointer-value pairs (2) An unflattened json object ### Examples #### Flatten and unflatten a json object with non-numeric keys ```cpp #include #include // for brevity using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { json input = json::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 }, { "rater": "HikingAsylum", "assertion": "intermediate", "rated": "Hongmin", "rating": 0.75 } ] } )"); json flattened = jsonpointer::flatten(input); std::cout << pretty_print(flattened) << "\n\n"; json unflattened = jsonpointer::unflatten(flattened); assert(unflattened == input); } ``` Output: ``` { "/application": "hiking", "/reputons/0/assertion": "advanced", "/reputons/0/rated": "Marilyn C", "/reputons/0/rater": "HikingAsylum", "/reputons/0/rating": 0.9, "/reputons/1/assertion": "intermediate", "/reputons/1/rated": "Hongmin", "/reputons/1/rater": "HikingAsylum", "/reputons/1/rating": 0.75 } ``` #### Flatten and unflatten a json object with numberlike keys ```cpp int main() { json input = json::parse(R"( { "discards": { "1000": "Record does not exist", "1004": "Queue limit exceeded", "1010": "Discarding timed-out partial msg" }, "warnings": { "0": "Phone number missing country code", "1": "State code missing", "2": "Zip code missing" } } )"); json flattened = jsonpointer::flatten(input); std::cout << "(1)\n" << pretty_print(flattened) << "\n"; json unflattened1 = jsonpointer::unflatten(flattened); std::cout << "(2)\n" << pretty_print(unflattened1) << "\n"; json unflattened2 = jsonpointer::unflatten(flattened, jsonpointer::unflatten_options::assume_object); std::cout << "(3)\n" << pretty_print(unflattened2) << "\n"; } ``` Output: ``` (1) { "/discards/1000": "Record does not exist", "/discards/1004": "Queue limit exceeded", "/discards/1010": "Discarding timed-out partial msg", "/warnings/0": "Phone number missing country code", "/warnings/1": "State code missing", "/warnings/2": "Zip code missing" } (2) { "discards": { "1000": "Record does not exist", "1004": "Queue limit exceeded", "1010": "Discarding timed-out partial msg" }, "warnings": ["Phone number missing country code", "State code missing", "Zip code missing"] } (3) { "discards": { "1000": "Record does not exist", "1004": "Queue limit exceeded", "1010": "Discarding timed-out partial msg" }, "warnings": { "0": "Phone number missing country code", "1": "State code missing", "2": "Zip code missing" } } ``` ### See also [jsoncons::jsonpath::flatten](../jsonpath/flatten.md) jsoncons-1.3.2/doc/ref/jsonpointer/get.md000066400000000000000000000173401477700171100203570ustar00rootroot00000000000000### jsoncons::jsonpointer::get Selects a value. ```cpp #include template Json& get(Json& root, const basic_json_pointer& location, bool create_if_missing = false); (1) template const Json& get(const Json& root, const basic_json_pointer& location); (2) template Json& get(Json& root, const basic_json_pointer& location, std::error_code& ec); (3) template const Json& get(const Json& root, const basic_json_pointer& location, std::error_code& ec); (4) template Json& get(Json& root, const basic_json_pointer& location, bool create_if_missing, std::error_code& ec); (5) template Json& get(Json& root, const StringSource& location_str, bool create_if_missing = false); (6) template const Json& get(const Json& root, const StringSource& location_str); (7) template Json& get(Json& root, const StringSource& location_str, std::error_code& ec); (8) template const Json& get(const Json& root, const StringSource& location_str, std::error_code& ec); (9) template Json& get(Json& root, const StringSource& location_str, bool create_if_missing, std::error_code& ec); (10) ``` #### Parameters
root Root JSON value
location A basic_json_pointer
location_str A JSON Pointer provided as a string, string view, or C-string
create_if_missing (since 0.162.0) Create key-object pairs when object key is missing
ec out-parameter for reporting errors in the non-throwing overload
#### Return value (1), (3) and (5) return the selected item by reference. json j(json_array_arg, {"baz","foo"}); json& item = jsonpointer::get(j,"/0"); // "baz" (2) and (4) return the selected item by const reference. const json j(json_array_arg, {"baz","foo"}); const json& item = jsonpointer::get(j,"/1"); // "foo" ### Exceptions (1)-(2) throw a [jsonpointer_error](jsonpointer_error.md) if get fails. (3)-(5) set the out-parameter `ec` to the [jsonpointer_error_category](jsonpointer_errc.md) if get fails. ### Examples #### Select author from second book ```cpp #include #include using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { auto j = json::parse(R"( [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 } ] )"); // Using exceptions to report errors try { json result = jsonpointer::get(j, "/1/author"); std::cout << "(1) " << result << '\n'; } catch (const jsonpointer::jsonpointer_error& e) { std::cout << e.what() << '\n'; } // Using error codes to report errors std::error_code ec; const json& result = jsonpointer::get(j, "/0/title", ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << "(2) " << result << '\n'; } } ``` Output: ```json (1) "Evelyn Waugh" (2) "Sayings of the Century" ``` #### Using jsonpointer::json_pointer with jsonpointer::get ```cpp #include #include using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { auto j = json::parse(R"( { "a/b": ["bar", "baz"], "m~n": ["foo", "qux"] } )"); jsonpointer::json_pointer ptr; ptr /= "m~n"; ptr /= "1"; std::cout << "(1) " << ptr << "\n\n"; std::cout << "(2)\n"; for (const auto& item : ptr) { std::cout << item << "\n"; } std::cout << "\n"; json item = jsonpointer::get(j, ptr); std::cout << "(3) " << item << "\n"; } ``` Output: ``` (1) /m~0n/1 (2) m~n 1 (3) "qux" ``` #### Examples from [RFC6901](https://tools.ietf.org/html/rfc6901) ```cpp #include #include using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { auto j = json::parse(R"( { "foo": ["bar", "baz"], "": 0, "a/b": 1, "c%d": 2, "e^f": 3, "g|h": 4, "i\\j": 5, "k\"l": 6, " ": 7, "m~n": 8 } )"); try { const json& result1 = jsonpointer::get(j, ""); std::cout << "(1) " << result1 << '\n'; const json& result2 = jsonpointer::get(j, "/foo"); std::cout << "(2) " << result2 << '\n'; const json& result3 = jsonpointer::get(j, "/foo/0"); std::cout << "(3) " << result3 << '\n'; const json& result4 = jsonpointer::get(j, "/"); std::cout << "(4) " << result4 << '\n'; const json& result5 = jsonpointer::get(j, "/a~1b"); std::cout << "(5) " << result5 << '\n'; const json& result6 = jsonpointer::get(j, "/c%d"); std::cout << "(6) " << result6 << '\n'; const json& result7 = jsonpointer::get(j, "/e^f"); std::cout << "(7) " << result7 << '\n'; const json& result8 = jsonpointer::get(j, "/g|h"); std::cout << "(8) " << result8 << '\n'; const json& result9 = jsonpointer::get(j, "/i\\j"); std::cout << "(9) " << result9 << '\n'; const json& result10 = jsonpointer::get(j, "/k\"l"); std::cout << "(10) " << result10 << '\n'; const json& result11 = jsonpointer::get(j, "/ "); std::cout << "(11) " << result11 << '\n'; const json& result12 = jsonpointer::get(j, "/m~0n"); std::cout << "(12) " << result12 << '\n'; } catch (const jsonpointer::jsonpointer_error& e) { std::cerr << e.what() << '\n'; } } ``` Output: ```json (1) {"":0," ":7,"a/b":1,"c%d":2,"e^f":3,"foo":["bar","baz"],"g|h":4,"i\\j":5,"k\"l":6,"m~n":8} (2) ["bar","baz"] (3) "bar" (4) 0 (5) 1 (6) 2 (7) 3 (8) 4 (9) 5 (10) 6 (11) 7 (12) 8 ``` #### Get a value at a location after creating objects when missing object keys ```cpp #include #include #include using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { std::vector keys = {"foo","bar","baz"}; jsonpointer::json_pointer location; for (const auto& key : keys) { location /= key; } json doc; json result = jsonpointer::get(doc, location, true); std::cout << pretty_print(doc) << "\n\n"; } ``` Output: ```json { "foo": { "bar": { "baz": {} } } } ``` ### See also [basic_json_pointer](basic_json_pointer.md) jsoncons-1.3.2/doc/ref/jsonpointer/jsonpointer.md000066400000000000000000000116261477700171100221530ustar00rootroot00000000000000### jsonpointer extension [JSON Pointer](https://tools.ietf.org/html/rfc6901) defines a string syntax to locate a specific value in a JSON document. A JSON Pointer is a string of zero or more tokens, each token prefixed by `/` characters. These tokens denote keys in JSON objects or indexes in JSON arrays. An empty string with zero tokens points to the root of a json document. The characters `~` and `/` have special meanings in JSON Pointer, so if a key in a JSON object has these characters, `~` needs to be escaped as `~0`, and `/` needs to be escaped as `~1`. When applied to a JSON array, the character `-` indicates one past the last element in the array. ### Classes
basic_json_pointer Objects of type basic_json_pointer represent a JSON Pointer.
### Functions
contains Returns true if the json document contains the given JSON Pointer
get Get a value from a JSON document using JSON Pointer path notation.
add Inserts a value in a JSON document using JSON Pointer path notation, or if the path specifies an object member that already has the same key, assigns the new value to that member.
insert (until 0.162.0) Same as add_if_absent
add_if_absent (since 0.162.0)) Inserts a value in a JSON document using JSON Pointer path notation, if the path doesn't specify an object member that already has the same key.
remove Removes a value from a JSON document using JSON Pointer path notation.
replace Replaces a value in a JSON document using JSON Pointer path notation.
flatten
unflatten
Flattens a json object or array into a single depth object of JSON Pointer-value pairs.
### Examples #### Select author from second book ```cpp #include #include // for brevity using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { auto j = json::parse(R"( [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 } ] )"); // Using exceptions to report errors try { json result = jsonpointer::get(j, "/1/author"); std::cout << "(1) " << result << '\n'; } catch (const jsonpointer::jsonpointer_error& e) { std::cout << e.what() << '\n'; } // Using error codes to report errors std::error_code ec; const json& result = jsonpointer::get(j, "/0/title", ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << "(2) " << result << '\n'; } } ``` Output: ```json (1) "Evelyn Waugh" (2) "Sayings of the Century" ``` #### Using jsonpointer::json_pointer with jsonpointer::get ```cpp #include #include using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { auto j = json::parse(R"( { "a/b": ["bar", "baz"], "m~n": ["foo", "qux"] } )"); jsonpointer::json_pointer ptr; // (since 0.159.0) // jsonpointer::json_ptr ptr; // (until 0.159.0) ptr /= "m~n"; ptr /= 1; // (since 0.159.0) //ptr /= "1"; // (until 0.159.0) std::cout << "(1) " << ptr << "\n\n"; std::cout << "(2)\n"; for (const auto& item : ptr) { std::cout << item << "\n"; } std::cout << "\n"; json item = jsonpointer::get(j, ptr); std::cout << "(3) " << item << "\n"; } ``` Output: ``` (1) /m~0n/1 (2) m~n 1 (3) "qux" ``` #### Add a value to a location after creating objects when missing object keys (since 0.162.0) ```cpp #include #include #include using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { std::vector keys = {"foo","bar","baz"}; jsonpointer::json_pointer location; for (const auto& key : keys) { location /= key; } json doc; jsonpointer::add(doc, location, "str", true); std::cout << pretty_print(doc) << "\n\n"; } ``` Output: ```json { "foo": { "bar": { "baz": "str" } } } ``` jsoncons-1.3.2/doc/ref/jsonpointer/jsonpointer_errc.md000066400000000000000000000015321477700171100231610ustar00rootroot00000000000000### jsoncons::jsonpointer::jsonpointer_errc ```cpp #include ```
The constant integer values scoped by `jsonpointer_errc` define the values for jsonpointer error codes. ### Member constants constant |Description ------------------------------------|------------------------------ `expected_slash` |Expected / `index_exceeds_array_size` |Index exceeds array size `expected_0_or_1` |Expected '0' or '1' after escape character '~' `invalid_index` |Invalid array index `name_not_found` |Name not found `key_already_exists` |Key already exists `expected_object_or_array` |Expected object or array `end_of_input` |Unexpected end of input jsoncons-1.3.2/doc/ref/jsonpointer/jsonpointer_error.md000066400000000000000000000024111477700171100233540ustar00rootroot00000000000000### jsoncons::jsonpointer::jsonpointer_error ```cpp #include ```
`jsoncons::jsonpointer::jsonpointer_error` defines an exception type for reporting failures in jsonpointer operations. ![jsonpointer_error](./diagrams/jsonpointer_error.png) #### Constructors jsonpointer_error(std::error_code ec) jsonpointer_error(const jsonpointer_error& other) #### Member functions const char* what() const noexcept Returns an error message #### Inherited from std::system_error const std::error_code code() const noexcept Returns an error code for this exception ### Example ```cpp #include #include using jsoncons::json; int main() { string s = "[1,2,3,4,]"; try { jsoncons::json val = jsoncons::json::parse(s); } catch(const jsoncons::jsonpointer_error& e) { std::cout << "Caught jsonpointer_error with category " << e.code().category().name() << ", code " << e.code().value() << " and message " << e.what() << '\n'; } } ``` Output: ``` Caught jsonpointer_error with category jsoncons.jsonpointer, code 0x6 and message "Name not found" ``` jsoncons-1.3.2/doc/ref/jsonpointer/remove.md000066400000000000000000000047651477700171100211040ustar00rootroot00000000000000### jsoncons::jsonpointer::remove Removes a `json` element. ```cpp #include template void remove(Json& target, const basic_json_pointer& location); (1) template void remove(Json& target, const basic_json_pointer& location, std::error_code& ec); (2) template void remove(Json& target, const StringSource& location_str); (3) template void remove(Json& target, const StringSource& location_str, std::error_code& ec); (4) ``` Removes the value at the location specifed by `location`. #### Parameters
target JSON value
location A basic_json_pointer
location_str A JSON Pointer provided as a string, string view, or C-string
ec out-parameter for reporting errors in the non-throwing overload
#### Return value None ### Exceptions (1) Throws a [jsonpointer_error](jsonpointer_error.md) if `remove` fails. (2) Sets the out-parameter `ec` to the [jsonpointer_error_category](jsonpointer_errc.md) if `remove` fails. ### Examples #### Remove an object member ```cpp #include #include namespace jsonpointer = jsoncons::jsonpointer; int main() { auto target = json::parse(R"( { "foo": "bar", "baz" : "qux"} )"); std::error_code ec; jsonpointer::remove(target, "/baz", ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << target << '\n'; } } ``` Output: ```json {"foo":"bar"} ``` #### Remove an array element ```cpp #include #include using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { auto target = json::parse(R"( { "foo": [ "bar", "qux", "baz" ] } )"); std::error_code ec; jsonpointer::remove(target, "/foo/1", ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << target << '\n'; } } ``` Output: ```json {"foo":["bar","baz"]} ``` jsoncons-1.3.2/doc/ref/jsonpointer/replace.md000066400000000000000000000107601477700171100212120ustar00rootroot00000000000000### jsoncons::jsonpointer::replace ```cpp #include template void replace(Json& target, const basic_json_pointer& location, T&& value, bool create_if_missing = false); (1) template void replace(Json& target, const basic_json_pointer& location, T&& value, std::error_code& ec); (2) template void replace(Json& target, const basic_json_pointer& location, T&& value, bool create_if_missing, std::error_code& ec); (3) template void replace(Json& target, const StringSource& location_str, T&& value, bool create_if_missing = false); (4) template void replace(Json& target, const StringSource& location_str, T&& value, std::error_code& ec); (5) template void replace(Json& target, const StringSource& location_str, T&& value, bool create_if_missing, std::error_code& ec); (6) ``` Replaces the value at the location specified by `location` with a new value. If `create_if_missing` is `false`, the target location must exist for the replacement to succeed. If `create_if_missing` is `true`, and if the target location specifies object members that do not already exist, the missing objects and members are added. #### Parameters
target JSON value
location A basic_json_pointer
location_str A JSON Pointer provided as a string, string view, or C-string
value Replacement value
create_if_missing (since 0.162.0) Create key-object pairs when object key is missing
ec out-parameter for reporting errors in the non-throwing overload
#### Return value None #### Exceptions (1) Throws a [jsonpointer_error](jsonpointer_error.md) if `replace` fails. (2) Sets the out-parameter `ec` to the [jsonpointer_error_category](jsonpointer_errc.md) if `replace` fails. ### Examples #### Replace an object value ```cpp #include #include using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { auto target = json::parse(R"( { "baz": "qux", "foo": "bar" } )"); std::error_code ec; jsonpointer::replace(target, "/baz", json("boo"), ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << target << '\n'; } } ``` Output: ```json { "baz": "boo", "foo": "bar" } ``` #### Replace an array value ```cpp #include #include using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { auto target = json::parse(R"( { "foo": [ "bar", "baz" ] } )"); std::error_code ec; jsonpointer::replace(target, "/foo/1", json("qux"), ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << pretty_print(target) << '\n'; } } ``` Output: ```json { "foo": ["bar","qux"] } ``` #### Replace a value at a location after creating objects when missing object keys ```cpp #include #include #include using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; int main() { std::vector keys = {"foo","bar","baz"}; jsonpointer::json_pointer location; for (const auto& key : keys) { location /= key; } json doc; jsonpointer::replace(doc, location, "str", true); std::cout << pretty_print(doc) << "\n\n"; } ``` Output: ```json { "foo": { "bar": { "baz": "str" } } } ``` jsoncons-1.3.2/doc/ref/jsonpointer/unflatten_options.md000066400000000000000000000010141477700171100233420ustar00rootroot00000000000000### jsoncons::jsonpointer::unflatten_options ```cpp #include enum class unflatten_options{none,object=1}; ``` Specifies how to preserve arrays while unflattening a json object of JSON Pointer-value pairs. There is no unique solution. An integer appearing in a path could be an array index or it could be an object key. Value |Definition -----------|----------- none|Default is to attempt to preserve arrays assume_object|Assume an integer appearing in a path is an object key jsoncons-1.3.2/doc/ref/jsonschema/000077500000000000000000000000001477700171100170315ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/jsonschema/custom-error-messages.md000066400000000000000000000056461477700171100236340ustar00rootroot00000000000000### Custom Error Messages (since 1.2.0) jsoncons optionally allows schema authors to provide custom error messages via an `errorMessage` keyword. To enable this feature, you need to provide an `expression_options` argument with `enable_custom_error_message` set to `true` when preparing a JSON Schema document with `make_json_schema`. The `errorMessage` keyword can be set to either - A string that represents a custom message, or - An object that maps message keys to custom messages An example of an object that maps message keys to custom messages is ```json { "maxItems" : "At most 3 numbers are allowed in 'foo'", "type" : "Only numbers are allowed in 'foo'", "format.date": "Date format must be YYYY-MM-DD" } ``` Maps are visible in the lexical scope of a schema. Message keys are JSON Schema keywords, except for `format`, where they have the form format. This implementation of key-message maps draws on the experience of [networknt json-schema-validator](https://github.com/networknt/json-schema-validator/blob/master/doc/cust-msg.md). We do not currently support parameterized messages. ### Example ```cpp #include #include #include namespace jsonschema = jsoncons::jsonschema; int main() { std::string schema_str = R"( { "type": "object", "properties": { "date": { "type": "string", "format": "date" }, "foo": { "type": "array", "maxItems": 3, "items" : { "type" : "number" }, "errorMessage" : { "maxItems" : "At most 3 numbers are allowed in 'foo'", "type" : "Only numbers are allowed in 'foo'" } }, "bar": { "type": "string", "errorMessage" : "Type of `bar` must be string" } }, "errorMessage": { "format.date": "Date format must be YYYY-MM-DD" } } )"; auto options = jsonschema::evaluation_options{} .enable_custom_error_message(true) .require_format_validation(true); auto schema = jsoncons::json::parse(schema_str); auto compiled = jsonschema::make_json_schema(schema, options); std::string data_str = R"( { "foo": [1, 2, "three"], "bar": 123, "date": "05-13-1955" } )"; auto data = jsoncons::json::parse(data_str); std::vector messages; auto reporter = [&](const jsonschema::validation_message& msg) -> jsonschema::walk_result { messages.push_back(msg.message()); return jsonschema::walk_result::advance; }; compiled.validate(data, reporter); for (const auto& msg : messages) { std::cout << msg << "\n"; } } ``` Output: ``` Type of `bar` must be string Date format must be YYYY-MM-DD Only numbers are allowed in 'foo' ``` jsoncons-1.3.2/doc/ref/jsonschema/diagrams/000077500000000000000000000000001477700171100206205ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/jsonschema/diagrams/schema_error.png000066400000000000000000000207131477700171100240020ustar00rootroot00000000000000PNG  IHDRkHtEXtmxfile%3Cmxfile%20modified%3D%222020-12-11T03%3A32%3A53.828Z%22%20host%3D%22app.diagrams.net%22%20agent%3D%225.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F87.0.4280.88%20Safari%2F537.36%22%20etag%3D%22nWQxAdRldKqpQSNP5H0O%22%20version%3D%2214.0.1%22%20type%3D%22device%22%3E%3Cdiagram%20id%3D%22iK-0d-7Yl-5MlnfMu26I%22%20name%3D%22Page-1%22%3E3Vddb9sgFP01eexkmzhJH9O067ao1bpMSvoUIXNr02HIMEmc%2FfrhGn9gO%2F2S1UWLIgUOcIHDORcyQLM4vZZ4E90IAmzgOSQdoMuB57kOmuifDDnkyPDcyYFQUmI6VcCC%2FoFipEG3lEBidVRCMEU3NhgIziFQFoalFHu724Ng9qwbHEILWASYtdElJSrK0YnvVPgXoGFUzOw6piXGRWcDJBEmYl%2BD0NUAzaQQKi%2FF6QxYRl7BSz7u85HWcmESuHrNgKvbnymf3y0ib%2FZ7rpY38X367cxE2WG2NRtOlO4%2F1V9IA9goKrhZvjoUnEix5QSysM4AXewjqmCxwUHWutcq0FikYqZrri62l1nMCVJBWoPMsq9BxKDkQXcxrSPDoJFQoaB9dR4l61HtLIYGw0YCYRm4YkkXDFFvIG18nDS55YrGsAYtPfnPifOcE2Nu0mKuxRFwMs18q2sBw0lCA5sWSKlaGQaz8n1W%2FuSb2mVaa7o8FBWuF78qAmSV2qisWg17qhXjjh5BIrYygJclorAMQb3sPyBWFmofaO3E%2FI4DKzAJDCu6s3NX1ymaGb4LqndW6mVoy6WUTxEh37YZVE81jTjndhzXb8TJaWnFeZJUuelXqSzc3UTe%2FHaFf0B4trybw24OZ6jtzyCCGPfhygfK2EwwHSYbi%2BDpo%2FFESfELai1ohM4R6cfHaOzbhHofaOROikf%2FoZGf09KLRh6flJFR48osr9C3Ohn5DSu7H2vl9lX7lUcgqcJcH5t%2BVlIcShy3xKeNpWy52QblgkPDzQbCjIY806yWCmj8IrMp1Q%2FCqWmIKSHZNJ2Zws4lPVjfndjW91CH9VGHkrw%2B7vDhkHBYL%2Be33uNqGvh3j96iI7s%2BJoKvT%2Be52Hz1uKOPfPZ0UdZHtnxn5ntPlu03Wz6joRPJln5TME0hvDZbumM7EJr0lS11tfqnmHev%2Fm%2Bjq78%3D%3C%2Fdiagram%3E%3C%2Fmxfile%3Eo9vIDATx^Uzǿ$ݮvj ވ5@`]k,Qv FZP`- 5vuG7$dRK puݶKLysaf33g9w½|=9̽#\!Kx 9_£E! {)DdĈh. yBa,(K@Jh(@E (i@DFXD0PʙK@Jh(@E (i@DFXD0PʙK@Jh(@E (i@DFXD0PʙK@Jh(@E (i@DFXD0PʙK@Jh(@E (i@DFXD0PʙK@Jh(@E (i@DFXD0PʙK@Jh(@E (i@DFXD0PʙK@Jh ХKd[&M6VټyzjL6-4Μ9sN\x1czs k=q&d28q7nāP5ӺcًQzA}TEd͚< i7eBy_#{KJŮxP"~}(,@)v͚56l+l2ٳ8x &LymѢE8w\T|*%5qĨBK>%O>=Zm߾'Oľ}G}>{ldO.ӟǏGU˗;=ԩS|cǎ|8z(f͚cǎQ5$X_bW=~a<ԯA&ey xGlٳ18I%9w\:u*ᨯk)iygEy[oСCX`AWҖvbcQi%by(F-[Dx-^8QƑY䗎Wlk'';Ca͝5S:cfT  y#k׮… !'p…|$V޼K.PGdr Br${Hl12+G.i+>#\2A̙3cرcϟO\It׮]&<%-^:k~d CYIeZ.IKEek +- X>a6$PΚb픩̽.>nܸHJ\ӥ-%Vy \Aٱ4">ȌWioV[T*,Alܛ~ .77

I@!2^DOtr .̙3=SJeNNqm.{.ՙo`Yt"y ά2]N˳dW@^<[= ;Ӗ\rKDFP\g* >5g.!^($@IjwM<'\tMO'iSPItP)sO' @Sp )D<d/s} n۶mч )8s5O?T*/s͌]ͦ-'j_c.rzRH P~Ák)@ϮM/jWޥɞ_fUԫV@  P2..* mvP|/ o{D ,'F=[AsfO$EW +*6&@ ,C*P|h {K_UES!+ !T<-EO6z/}Qy5Oi, PYhB)5 =mkȗVE W$*0(/ 1_WQ*L)@Uݤ uh WR=/|i\\Ѓ W7S*G@&,)@ZY%誈TY2L*FM(IU/UE\U ECZ4 _(@a!BتmԀ Tm ހ|1SkUDʕZLq0P򇵲 ȗKUgmTY2B٨JQ죨m>M^\uBΗnYUD\7 @RU$JS_(@HCÑVHH=WD(@e = @p-KR (@U*m P~flA$PUJ +H;*ukUDwPzI} &*}xD+yb 3IO(@a+AoHm\x[-[g<{ꩧrO?>(~m̜9/bT@~;VZ[n/n馨{g{'3<}Ocpp{|={ܹsQj[**O۟,tY~xWkE|^~ȼvw@*'x"zM(@哝H$pUUt۔;\}P ,X7pC41ϝ;7_yH0x<#xB?GѤyN믿>Wl%:u*)/]w5k" Tgާ~"_~eԗ~/L/OU.\_6$@M#uGsv6]s5i{=(_u;Ȉ-ٚ5kaÆHdTX}$og%?'|2SD]UR?{Yv[GL/ 6(W*f x-?~!hѢT%""" ғ-LuB׆uN5e0\J_LG*G}*{؂;ـH! qQ= 9A3&q&@L{HIvu%='<KiOZDj;n s>*"@{$$2… }1l2dJWt N'  ^v!,֯-@b+kԳfG$@7qS*7lNz LĶL/Spd.ia4:9•~y ; TN`z,<bnZEr[Z|NXxDN@52OuԫSzE " jt9 >(@. $ yXQЪ^ P @ygybn/ Pnd6UIJY2(@eoKϔIH}i PzR3E >StQǶ(@ 8?SYV@eoKϔI f|m<T LiH;_yn: PzR3E t#Jг#+ݣ|Ggs@XJCPܤ|G' ]4{ P@A{@(J P] ,!+ &@jpjrTn+ Y  PCxVw ,4dG(@} #.x >x#@5(@ړYb&W(@mRpbY/Q(@Eɵ( Ym? hXt%(@- aR<,k*E?Xk:Sb1vhLGŬY~zرSY~`9owH7tȑ΄%Z 6m,S͝;vɓ;bŊkD4D@/^M&MJ'tR a„ {"\":r͞=wa)r\VC9sD?ǎ<|g\=N@,@W @*&>͆C> jC*%@o2|/޽{g̘U"ZK,&,2@Ŵ/]NY`A^ҟ+c'b&uӧO{gm4W4O Pr#k}$l d֭* yh$aҏ` -4ry)S.p Ja,;of`63nuz]H]*"d혐tOqE$U@i'V@yI3ٷO 4a+~ĉ;i{@y'f[pB?#U̙3&Y[pa'%mfC {]d N^re4{@yIj !~ǘ[{=!&_2:tXٴo!3^)8=mG3tIOs 85ߌ5(HT\~zg}rwb A ,Kay>/_r;"UIFԶoW*-`JHbTP|(@&@ʍ (@(`Е(@( (77AWrFRP0JnZ߀P P ]MYPJ P@+ Pr#k} P@)@ (t%7 Pndo@ ((@&@ʍ (@(`Е(@( (77AWrFWZO <|z@ '@ϔIHP   (@"  $B$@$?SZ$ p @r[HHgJ$@$@(@x  LiHHo! O)- 89@-$@$@ P3E   HHH? H$@$@ '@ϔIHP   (@"  $B$@$?SZ$ p @r[HHgJ$@$@(@x  LiHHo! O)- 89@-$@$@ P3E   HHH? H$@$@ '@ϔIHP   (@1vXL',p c*lLB؈ZNp~/tɵ_axMh^, 9lSb;kl8`Q5Mpbc?gXy; KT/$@dbdO2A`RD,&"mŶET^V2tSKK&h%8FE(* cڸ]7`nݔ$ @DiLlT bxDg:== ~E L_me=1W#*@:n;YS"!.S! s@kOrPA!,CQ $%@2.ͬ~Ѐgb?y"MCRY钤ԥqZYd (@Ni˛B' (/2+)8RI ._D. _VMܥ6"@*^y* See|0$ PI-iC̽'!p W iPR69`.U]!m/}" P(@-y0)@a?!@3Y~T'%8fJ|LF%ݤvR Pi7sKIz~ɼO ss@꧞[ R.I= s \O^J(@5ݷVwiZ% s%`,3;5(XtHɱ @P,J$@DOXHHA aIENDB`jsoncons-1.3.2/doc/ref/jsonschema/diagrams/validation_error.png000066400000000000000000000210501477700171100246670ustar00rootroot00000000000000PNG  IHDRZjtEXtmxfile%3Cmxfile%20modified%3D%222020-12-11T03%3A30%3A03.364Z%22%20host%3D%22app.diagrams.net%22%20agent%3D%225.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F87.0.4280.88%20Safari%2F537.36%22%20etag%3D%22nQ8sruTt9vT6MG2S-Ikm%22%20version%3D%2214.0.1%22%20type%3D%22device%22%3E%3Cdiagram%20id%3D%22iK-0d-7Yl-5MlnfMu26I%22%20name%3D%22Page-1%22%3E3Vdbb9sgGP01eexkmzhJH9P0si1qtS6Tkj5VyHy16WzIMEmc%2FfpBjC%2FY7lVeFy2KFDjABxzO%2BSADNEuyK4HX0TUnEA88h2QDdD7wPNdBE%2FWjkX2ODE%2BdHAgFJaZTBSzobyhGGnRDCaRWR8l5LOnaBgPOGATSwrAQfGd3e%2BCxPesah9ACFgGO2%2BiSEhnl6MR3Kvwz0DAqZnYd05LgorMB0ggTvqtB6GKAZoJzmZeSbAaxJq%2FgJR93%2BURruTABTL5mwMXNj4zNbxeRN%2Fs1l8vr5C77emKibHG8MRtOpeo%2FVV%2FIAlhLyplZvtwXnAi%2BYQR0WGeAznYRlbBY40C37pQKFBbJJFY1VxXbyyzmBCEhq0Fm2VfAE5Bir7qY1pFh0EioUNCuOo%2BS9ah2FkODYSOBsAxcsaQKhqg3kDZ%2BmjSxYZImcA9KeuKfE%2Bc5R8bcpMVciyNgZKp9q2pBjNOUBjYtkFG5Mgzq8p0uf%2FJN7TyrNZ3viwpTi18VAXSlNkpXq2GHWjHuySNI%2BUYE8LJEJBYhyJf9B8TKQu0DrZ2Y33FgBSYgxpJu7dzVdYpmhm%2Bcqp2VehnacinlU0TIt20G1VNNI86pHcf1G3FyWlpxDpIqN%2F0qlYXb68ib36zwdwhPlrdz2M7hBLVUpoqUYJ3M%2BnDmA43jGY9VGD0WweGj8FQK%2FhNqLWiEThHpx8to7Nukeh1m9vy%2FY%2BZOmkf%2FoZmf09OLZh4flZlR49osr9G3uhn5DTu7H2vn9nX7hUUgqMRMHZt6WlIcCpy0xKeMJW252QZlnEHDzQZS2SJkWrNKKqDwM21Tqh6FU9OQUEL0NJ2Zws4lPVjfndjW91CH9VGHkrw%2B7vHhkDC4X85vvMfVNPBvH71FR4Z9THVuPZonY%2FPl444%2B8unTRVkf2fKdme89WbbfbPmMho4kW%2FpNwTSF8Nps6Y7tQGjSV7ZU1erfYt69%2Bs%2BNLv4A%3C%2Fdiagram%3E%3C%2Fmxfile%3Eͬ*IDATx^Uzǿ$ݮF(%5Djoܠ)ZD-i%[ ;-0kmkVj\V myfys03;3sfor1ss>y`|Y#0Z@Nw\ݻqҥcƌ)%HR\QnNƍq!ʹ۹,#G\Y(H e$:a2bIK-n僒y %'Y&h |r,]Coo/>.\ .3[ouȌOʚ0aB0ӓ?usoǎ8}48|>|`&p]~Ƒ#G0 'e=:{gcI<{lЗF[|-Z(QѬ/Jk핲u*駸;#`˖-G1XOسYT% %9ypڵk`$Jŋ7#*Ē%Kk׮$E 2`!/H5*K]<5u$+Vh}.)"9틚KL#?TyR_L]ܾI+*Ǥ><ܺ[H?'X4 %бj߰qUhT8RvPmE5Gˍ6n"cdpDIAqڴi l_2M/}_IsO UFgG4+eJrn.Lrwرľ49Օ77vhn_p}!bW>6{',hKr:͛7/h..A,rPt]L:ТߗG% 9PFrOm۶e0 0ɽsȞ\2q=~AJʗCG3ɹ}8D\efZ>#S`D$8 @ ж4XW^^['39wͅKb"q3$y6QKL/te\Β\47TP$u!f˽.nLzՂj,W wxXX' X!Жe*LҞɺ''r4d4}`OLkP+ߗY\A~bt;Jړ1bDKY39woVR=h_LZ,H~_3ړk!9+v_s?O58H,mI.T;zbOWix J]BjwF{.t.z"]AJteseg9蒰*rFOWn߾=E$Jt;'> q7]rqJetV\=QfoP7V]IIN𦐜@&CCщ@ %nii:=89v/ -,UN('k$J$mҒuU 7 wVVt EdOML,38++Cj)nCoV?%g9;bk_"b쥔LhQr9ujZJXsj"FySdN]y-vPrvrDRw )vP^RwMWPr]Gk)<(TFI;ܱ7^ˉ<%g,S% Z^vx;r|GLR( Ż%W`G4Z4%g01]ҠҒ*:#esXEg˄SrhdjF3oӳ;JP-)J$Y16hŅNeIh/fw\`%gx_(9CP(@gƃA˒Ђ:  &ŃA3o33ۼg\$@fv;\#3'|O?4nfO< wuW SO=-[r[|'`̙@`"y^|Ep %ʤ_=C{>ܯH9"M?%=54WKi$a\'x/ /!c~"?ۜ9sGse'Zn\Yؒ$S1Ftw(^ƭ2^m󞞞!51aa\TY& %O;rME6*e%q(ˌљ܌34q]t1Nrk֬ H>:Tyf,/AE))5NJ.Iv("䤭C? ࢃ{'39ٛӥBA3v$7L%I/:䌼[ 7 [(7\*Jr=TIHܞɹrJ0㓃eUf5Qr޼( @ MxJ@zR~OODر#8L"bW䢧+G{rKӃCo֐*tteVIJ].m5vJJVO$`Pn=ܾq3OrOgIn&_j%L(zHƽ2stw\7N NȌMNKޛM>R(T*u%Wt1$PiCTn_di1%V5䪑GN[(899EeF )dHy֭Rr^Jϼ1j:g:i8% =?&h[' :罔yc$P5u\'3oBwS>I)Ny/%g5 N7C}+n4넞Rr~QTϺupJz~K7FMMoIyg:i8% =?&)5[E{RrcϚIru\w^J{}y+,Zy}#wݺH[u֜ NJ,vذ-l}<-g|vlHK›#mJF( H}MW00 JP(9Y7CX 4p&ΐ%XwArn*L׭@,!@ɱSd%@e%V%J.? l&\Pr`U!t$9Y7ۏ !`($Д%%X,9Y7۩¢I\!X+](%g(I}MwPH J..^ 3 ru3[J.u*3$g 唡K˗gJ eCY7Cd(ZR)9CmSrgf1ȍ%DJu?X ϺC)%W*Bf^ ϺC)%WDdDr#+_ nP'@ɕSIܹsXnvލ1cTmtR)HUGgReU%WŬۦT+6wCvGlmIQ@9(r8WTs#F`ҥطo_;WVрSNaԩ .Ď;c͚56lի[r+8p@Pq!?Qƍcm:~8fΜcΝlT~ R,x T%Wج̒;vXC*Xj6mYқ3gكI&5Ķ|syDR- d2qĦ,Y]vQQ&Yfa޽:s,KAi=yϤ'Nq7(ʼ%~OL+ |>I,Jlj֑V<|-N6-/^\޵k̙3͟͝??Z_R+^'36&>+gm9?~[f{# Pr­hљ%'ORҙԶmۂU>Y$7o޼!ePR,*9Yzt_7@ILVg{"N#9+fc:'7G VB[s24ɵ#9wM.kܸqLMfrI3GwITrnw&\rlo'(N̒ &4eŋ2N>=e Krdiҽȑ#C{\)X"hO{rYIVGk[,9's=(7;uKϤӕz"T=ztpZ]O#vکmJf ϡ%W,\Qr9hQi\[HZJN<\`dPNHF_(EIe@(VĖ:KLR6EŬ؎3JP2Iɴ3JP2Iɴ3JP2Iɴ3JP2Iɴ3JP2Iɴ3JP2Iɴ3JP2Iɴ3JP2Iɴ3JP2Iɴ3JP2Iɴ3JP2Iɴ3JP2Iɴjtt z杭NAox (9?ƨIHRR@%$@$@~& HAK I3oHH J.$^B$@$'Jϼ1j  (x (9?ƨIHRR@%$@$@~& HAK I3oHH J.$^B$@$'Jϼ1j  (x (9?ƨIHRR@%$@$@~& HAK I3oHH J.$^B$@$'Jϼ1j  (x (9?ƨIHRR@%$@$@~& HAK I3oHH J.$^B$@$'Jϼ1j  (x (9?ƨIHRR@%$@$@~[Q:T>1f16`Φͪںm.iVyx @(W2%K[oUrK\-bE$%Ypeδ.X`#}`;38)N ܮG:\p̄z k*aI\zEPqĉK `TL-+Z`l[╙k\XPul3 4%@ɱ!'9O$5 PP=pAx|x]]pEHSD\qiyYaB<RATNb˕"_Esٞn7i7a֝&jCM;jht0v&n懒{(e>BK'^ҢˎnuG㖽\B WVi j>-ClqIƛI O\4[Vtpr8ED{Ys_,ݴf. r٬^9(C%h<}L Od˷R..+bTr$Ӷ{-˙%3Њr&3$RBK+f3x)L3{Dr*,39ُK>Jo46+\LXbsdJ3~/4Wr$[ܥUw]|\]qdjO.IrGU]6B+k CrӌT)J!nRrg(S2Kd$f(A'>:f9izt-o:˶4*uǯ:{rrڬ}\blPQ(Ȳ\R @(8&3m"$P"JDجHH\\Y @(a*  r Prfm$@$@%WeiߝIENDB`jsoncons-1.3.2/doc/ref/jsonschema/evaluation_options.md000066400000000000000000000037731477700171100233070ustar00rootroot00000000000000### jsoncons::jsonschema::evaluation_options ```cpp #include class evaluation_options; ```
Allows configuration of JSON Schema evaluation. #### Constructors evaluation_options(); Constructs an `evaluation_options` with default values. evaluation_options(const evaluation_options& other); Copy constructor #### Member functions evaluation_options& operator=(const evaluation_options& other); Assignment operator const std::string& default_version() const; evaluation_options& default_version(const std::string& version); Get or set a default [schema version](schema_version.md). The default version determines the schema dialect that is used if the `$schema` keyword is not present in the top level of the JSON Schema document. Defaults to `schema_version::draft202012()`. bool compatibility_mode() const; evaluation_options& compatibility_mode(bool value); Get or set the compatibility mode. If set to `true`, the JSON Schema 2019-09 and 2020-12 implementations support the Draft 7 "definitions" and "dependencies" keywords. The default is `false`. bool require_format_validation() const; evaluation_options& require_format_validation(bool value); Determines whether `format` is an assertion. The default is `false`. const std::string& default_base_uri() const; evaluation_options& default_base_uri(const std::string& base_uri); (since 1.0.0) Get or set a default base URI. In the case that a schema does not have an `$id` with an absolute URI, the default base URI will be used to resolve relative references. It defaults to 'https://jsoncons.com'. bool enable_custom_error_message() const; evaluation_options& enable_custom_error_message(bool value); Determines whether custom error messages in a schema are supported. The default is `false`. #### Non-member functions bool operator==(const evaluation_options& lhs, const evaluation_options& rhs); Checks if the contents of `lhs` and `rhs` are equal. jsoncons-1.3.2/doc/ref/jsonschema/json_schema.md000066400000000000000000000015601477700171100216460ustar00rootroot00000000000000### jsoncons::jsonschema::json_schema ```cpp #include template class json_schema ``` A `json_schema` represents the compiled form of a JSON Schema document. A `json_schema` is immutable and thread-safe. The class satisfies the requirements of MoveConstructible and MoveAssignable, but not CopyConstructible or CopyAssignable. #### Member functions
is_valid Validates input JSON against a JSON Schema and returns false upon the first schema violation
validate Validates input JSON against a JSON Schema.
walk (since 0.175.0) Walks through a JSON Schema.
jsoncons-1.3.2/doc/ref/jsonschema/json_schema/000077500000000000000000000000001477700171100213225ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/jsonschema/json_schema/is_valid.md000066400000000000000000000075151477700171100234460ustar00rootroot00000000000000### jsoncons::jsonschema::json_schema::is_valid ```cpp bool is_valid(const Json& instance) const; ``` Validates input JSON against a JSON Schema and returns false upon the first schema violation. #### Parameters
instance Input Json
#### Return value `true` if the instance is valid, otherwise `false`. #### Exceptions None. ### Examples #### Validate before decode ```cpp #include #include #include #include #include using jsoncons::json; namespace jsonschema = jsoncons::jsonschema; namespace ns { struct os_properties { std::string command; }; struct db_properties { std::string query; }; struct api_properties { std::string target; }; struct job_properties { std::string name; std::variant run; }; } // namespace ns JSONCONS_N_MEMBER_TRAITS(ns::os_properties, 1, command) JSONCONS_N_MEMBER_TRAITS(ns::db_properties, 1, query) JSONCONS_N_MEMBER_TRAITS(ns::api_properties, 1, target) JSONCONS_N_MEMBER_TRAITS(ns::job_properties, 2, name, run) int main() { std::string schema_str = R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "job", "description": "job properties json schema", "$defs": { "os_properties": { "type": "object", "properties": { "command": { "description": "this is the OS command to run", "type": "string", "minLength": 1 } }, "required": [ "command" ], "additionalProperties": false }, "db_properties": { "type": "object", "properties": { "query": { "description": "this is db query to run", "type": "string", "minLength": 1 } }, "required": [ "query" ], "additionalProperties": false }, "api_properties": { "type": "object", "properties": { "target": { "description": "this is api target to run", "type": "string", "minLength": 1 } }, "required": [ "target" ], "additionalProperties": false } }, "type": "object", "properties": { "name": { "description": "name of the flow", "type": "string", "minLength": 1 }, "run": { "description": "job run properties", "type": "object", "oneOf": [ { "$ref": "#/$defs/os_properties" }, { "$ref": "#/$defs/db_properties" }, { "$ref": "#/$defs/api_properties" } ] } }, "required": [ "name", "run" ], "additionalProperties": false } )"; std::string data_str = R"( { "name": "testing flow", "run" : { "command": "some command" } } )"; try { json schema = json::parse(schema_str); // Throws schema_error if JSON Schema compilation fails jsonschema::json_schema compiled = jsonschema::make_json_schema(std::move(schema)); // Test that input is valid before attempting to decode json data = json::parse(data_str); if (compiled.is_valid(data)) { const ns::job_properties v = data.as(); std::string output; jsoncons::encode_json_pretty(v, output); std::cout << output << '\n'; // Verify that output is valid json test = json::parse(output); assert(compiled.is_valid(test)); } else { std::cout << "Invalid input\n"; } } catch (const std::exception& e) { std::cout << e.what() << '\n'; } } ``` Output: ``` { "name": "testing flow", "run": { "command": "some command" } } ``` jsoncons-1.3.2/doc/ref/jsonschema/json_schema/validate.md000066400000000000000000000124501477700171100234370ustar00rootroot00000000000000### jsoncons::jsonschema::json_schema::validate ```cpp void validate(const Json& instance) const; (1) void validate(const Json& instance, Json& patch) const; (2) template void validate(const Json& instance, const MsgReporter& reporter) const; (3) template void validate(const Json& instance, const MsgReporter& reporter, Json& patch) const; (4) void validate(const Json& instance, json_visitor& visitor) const; (5) ``` (1) Validates input JSON against a JSON Schema with a default error reporter that throws upon the first schema violation. (2) Validates input JSON against a JSON Schema with a default error reporter that throws upon the first schema violation. Writes a JSONPatch document to the output parameter. (3) Validates input JSON against a JSON Schema with a provided error reporter that is called for each schema violation. (4) Validates input JSON against a JSON Schema with a provided error reporter that is called for each schema violation. Writes a JSONPatch document to the output parameter. (5) Validates input JSON against a JSON Schema and writes the validation messages to a [json_visitor](../../corelib/basic_json_visitor.md). #### Parameters
instance Input Json
reporter A function object with signature equivalent to
           walk_result fun(const validation_message& msg);
patch A JSONPatch document that may be applied to the input JSON to fill in missing properties that have "default" values in the schema.
visitor A [json_visitor](../../corelib/basic_json_visitor.md) that receives JSON events corresponding to an array of validation messages.
#### Return value None. #### Exceptions (1) - (2) Throws a [validation_error](../validation_error.md) for the first schema violation. ### Examples ```cpp #include #include #include using jsoncons::ojson; namespace jsonschema = jsoncons::jsonschema; int main() std::string schema_str = R"( { "$id": "https://example.com/arrays.schema.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "description": "A representation of a person, company, organization, or place", "type": "object", "properties": { "fruits": { "type": "array", "items": { "type": "string" } }, "vegetables": { "type": "array", "items": { "$ref": "#/$defs/veggie" } } }, "$defs": { "veggie": { "type": "object", "required": [ "veggieName", "veggieLike" ], "properties": { "veggieName": { "type": "string", "description": "The name of the vegetable." }, "veggieLike": { "type": "boolean", "description": "Do I like this vegetable?" } } } } } )"; std::string data_str = R"( { "fruits": [ "apple", "orange", "pear" ], "vegetables": [ { "veggieName": "potato", "veggieLike": true }, { "veggieName": "broccoli", "veggieLike": "false" }, { "veggieName": "carrot", "veggieLike": false }, { "veggieName": "Swiss Chard" } ] } )"; ojson schema = ojson::parse(schema_str); jsonschema::json_schema compiled = jsonschema::make_json_schema(std::move(schema)); ojson data = ojson::parse(data_str); std::cout << "\n(1) Validate using exceptions\n"; try { compiled.validate(data); } catch (const std::exception& e) { std::cout << e.what() << "\n"; } std::cout << "\n(2) Validate using reporter callback\n"; auto reporter = [](const jsonschema::validation_message& msg) -> jsonschema::walk_result { std::cout << message.instance_location().string() << ": " << message.message() << "\n"; return walk_result::advance; }; compiled.validate(data, reporter); std::cout << "\n(3) Validate outputting to a json decoder\n"; jsoncons::json_decoder decoder; compiled.validate(data, decoder); ojson output = decoder.get_result(); std::cout << pretty_print(output) << "\n"; } ``` Output: ``` (1) Validate using exceptions /vegetables/1/veggieLike: Expected boolean, found string (2) Validate using reporter callback /vegetables/1/veggieLike: Expected boolean, found string /vegetables/3: Required property 'veggieLike' not found. (3) Validate outputting to a json decoder [ { "valid": false, "evaluationPath": "/properties/vegetables/items/$ref/properties/veggieLike/type", "schemaLocation": "https://example.com/arrays.schema.json#/$defs/veggie/properties/veggieLike", "instanceLocation": "/vegetables/1/veggieLike", "error": "Expected boolean, found string" }, { "valid": false, "evaluationPath": "/properties/vegetables/items/$ref/required", "schemaLocation": "https://example.com/arrays.schema.json#/$defs/veggie/required", "instanceLocation": "/vegetables/3", "error": "Required property 'veggieLike' not found." } ] ``` jsoncons-1.3.2/doc/ref/jsonschema/json_schema/walk.md000066400000000000000000000067761477700171100226220ustar00rootroot00000000000000### jsoncons::jsonschema::json_schema::walk ```cpp template void walk(const Json& instance, const WalkReporter& reporter) const; (since 0.175.0) ``` Walks through a JSON schema to collect information. #### Parameters
instance Input Json
reporter A function object with signature equivalent to
walk_result fun(const std::string& keyword,
    const Json& schema, const uri& schema_location,
    const Json& instance, const jsonpointer::json_pointer& instance_location)
that returns a walk_result to indicate whether to continue or stop.
#### Return value None #### Exceptions None ### Examples #### Construct a type tree based on a JSON Schema and an instance ```cpp #include #include #include #include using jsoncons::ojson; namespace jsonschema = jsoncons::jsonschema; int main() { std::string schema_str = R"( { "$id": "https://example.com/arrays.schema.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "description": "A representation of a person, company, organization, or place", "type": "object", "properties": { "fruits": { "type": "array", "items": { "type": "string" } }, "vegetables": { "type": "array", "items": { "$ref": "#/$defs/veggie" } } }, "$defs": { "veggie": { "type": "object", "required": [ "veggieName", "veggieLike" ], "properties": { "veggieName": { "type": "string", "description": "The name of the vegetable." }, "veggieLike": { "type": "boolean", "description": "Do I like this vegetable?" } } } } } )"; ojson schema = ojson::parse(schema_str); jsonschema::json_schema compiled = jsonschema::make_json_schema(std::move(schema)); std::string data_str = R"( { "fruits": [ "apple", "orange", "pear" ], "vegetables": [ { "veggieName": "potato", "veggieLike": true }, { "veggieName": "broccoli", "veggieLike": false } ] } )"; // Data ojson data = ojson::parse(data_str); auto reporter = [](const std::string& keyword, const ojson& schema, const jsoncons::uri& /*schema_location*/, const ojson& /*instance*/, const jsoncons::jsonpointer::json_pointer& instance_location) -> jsonschema::walk_result { if (keyword == "type") { assert(schema.is_object()); auto it = schema.find("type"); if (it != schema.object_range().end()) { std::cout << instance_location.string() << ": " << it->value() << "\n"; } } return jsonschema::walk_result::advance; }; compiled.walk(data, reporter); } ``` Output: ``` /fruits/0: "string" /fruits/1: "string" /fruits/2: "string" /fruits: "array" /vegetables/0/veggieName: "string" /vegetables/0/veggieLike: "boolean" /vegetables/0: "object" /vegetables/1/veggieName: "string" /vegetables/1/veggieLike: "boolean" /vegetables/1: "object" /vegetables: "array" : "object" ``` The type tree shows the allowable types for the data values as specifed in the schema. No validation of the data is performed during its construction. jsoncons-1.3.2/doc/ref/jsonschema/json_validator.md000066400000000000000000000030511477700171100223700ustar00rootroot00000000000000### jsoncons::jsonschema::json_validator: deprecated (since 0.174.0) ```cpp #include template class json_validator ``` #### Constructor json_validator(std::shared_ptr> schema); #### Member functions bool is_valid(const Json& instance) const; (1) Json validate(const Json& instance) const; (2) template Json validate(const Json& instance, const MsgReporter& reporter) const; (3) (1) Validates input JSON against a JSON Schema and returns false upon the first schema violation. (2) Validates input JSON against a JSON Schema with a default error reporter that throws upon the first schema violation. (3) Validates input JSON against a JSON Schema with a provided error reporter that is called for each schema violation. #### Parameters
instance Input Json
reporter A function object with signature equivalent to
           void fun(const validation_output& msg);
which accepts an argument of type validation_output.
#### Return value (1) `true` if the instance is valid, otherwise `false` (2) - (3) A JSONPatch document that may be applied to the input JSON to fill in missing properties that have "default" values in the schema. #### Exceptions (2) Throws a [validation_error](validation_error.md) for the first schema violation. (3) `reporter` is called for each schema violation jsoncons-1.3.2/doc/ref/jsonschema/jsonschema.md000066400000000000000000000556531477700171100215230ustar00rootroot00000000000000### jsonschema extension Since 0.174.0, the jsonschema extension implements Drafts 4, 6, 7, 2019-9 and 2020-12 of the [JSON Schema Specification](https://json-schema.org/specification). Previous versions supported Draft 7. The documentation below describes the new features for the jsonschema extension since 0.174.0. For earlier releases, please refer to [jsonschema (until 0.174.0)](https://github.com/danielaparker/jsoncons/tree/main). ### Classes
json_schema A json_schema represents the compiled form of a JSON Schema document.
evaluation_options Allows configuration of JSON Schema evaluation.
validation_message A message type for reporting errors generated by a keyword.
schema_version Supported JSON Schema dialects.
json_validator JSON Schema validator. Deprecated (since 0.174.0)
### Functions
make_json_schema Processes a JSON Schema document and returns the compiled form as a json_schema (since 0.174.0).
make_schema Loads a JSON Schema and returns a shared pointer to a json_schema. Deprecated since 0.174.0. Removed in 1.0.0.
### Compliance #### Keywords The jsoncons implementation passes all required tests in the [JSON Schema Test Suite](https://github.com/json-schema-org/JSON-Schema-Test-Suite/) for the keywords below. You can check the [Bowtie project](https://github.com/bowtie-json-schema/bowtie) to see how jsoncons [compares with other implementations](https://bowtie.report/). | Keyword | Draft 4 | Draft 6 | Draft 7 | Draft 2019-09 | Draft 2020-12 | |:--------------------------:|:---------:|:---------:|:---------:|:---------:|:---------:| | $anchor | | | | 🟢 | 🟢 | | $defs | | | | 🟢 | 🟢 | | $dynamicAnchor | | | | | 🟢 | | $dynamicRef | | | | | 🟢 | | $id | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | $recursiveAnchor | | | | 🟢 | | | $recursiveRef | | | | 🟢 | | | $ref | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | $vocabulary | | | | 🟢 | 🟢 | | additionalItems | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | additionalProperties | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | allOf | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | anyOf | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | const | | 🟢 | 🟢 | 🟢 | 🟢 | | contains | | 🟢 | 🟢 | 🟢 | 🟢 | | contentEncoding | | | 🟢 | 🟢 | 🟢 | | contentMediaType | | | 🟢 | 🟢 | 🟢 | | definitions | 🟢 | 🟢 | 🟢 | | | | dependencies | 🟢 | 🟢 | 🟢 | | | | dependentRequired | | | | 🟢 | 🟢 | | dependentSchemas | | | | 🟢 | 🟢 | | enum | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | exclusiveMaximum (boolean) | 🟢 | | | | | | exclusiveMaximum | | 🟢 | 🟢 | 🟢 | 🟢 | | exclusiveMinimum (boolean) | 🟢 | | | | | | exclusiveMinimum | | 🟢 | 🟢 | 🟢 | 🟢 | | if-then-else | | | 🟢 | 🟢 | 🟢 | | items | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | maxContains | | | | 🟢 | 🟢 | | minContains | | | | 🟢 | 🟢 | | maximum | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | maxItems | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | maxLength | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | maxProperties | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | minimum | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | minItems | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | minLength | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | minProperties | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | multipleOf | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | not | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | oneOf | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | pattern | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | patternProperties | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | prefixItems | | | | | 🟢 | | properties | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | propertyNames | | 🟢 | 🟢 | 🟢 | 🟢 | | required | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | type | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | unevaluatedItems | | | | 🟢 | 🟢 | | unevaluatedProperties | | | | 🟢 | 🟢 | | uniqueItems | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | #### Format The implementation understands the following [formats](https://json-schema.org/understanding-json-schema/reference/string.html#format): | Format | Draft 4 | Draft 6 | Draft 7 | Draft 2019-09 | Draft 2020-12 | |:-------------:|:---------:|:---------:|:---------:|:---------:|:---------:| | date | | 🟢 | 🟢 | 🟢 | 🟢 | | date-time | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | email | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | hostname | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | ipv4 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | ipv6 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | json-pointer | | 🟢 | 🟢 | 🟢 | 🟢 | | regex | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | time | | 🟢 | 🟢 | 🟢 | 🟢 | | uri (since 1.0.0)| 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | | uri-reference (since 1.0.0)| 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | Any other format type is ignored. Since Draft 2019-09, format is no longer an assertion by default. It can be configured to be an assertion by setting the evaluation option `require_format_validation` to `true` ### Schema dialect jsoncons supports Drafts 4, 6, 7, 2019-9 and 2020-12 of the [JSON Schema Specification](https://json-schema.org/specification). It needs to know the dialect of a schema resource in order to know how to process it. If a schema contains a **$schema** dialect identifier, it uses that. Otherwise, it falls back on a default version you can provide through [evaluation_options](./evaluation_options.md), e.g. ```cpp auto options = jsonschema::evaluation_options{} .default_version(jsonschema::schema_version::draft7()); auto compiled = jsonschema::make_json_schema(schema, options); ``` If no default is provided, the latest supported version is assumed. ### URI resolution jsoncons requires a user supplied schema resolver to resolve a URI reference to a schema resoure. A schema resolver is a function object with the signature of `resolver` being equivalent to

    Json fun(const jsoncons::uri& uri);
If unable to resolve the resource, it should return Json::null(). Here is an example of a schema resolver that resolves a URI to a physical pathname, ```cpp std::string root_dir = "./input/jsonschema"; auto resolver = [&](const jsoncons::uri& uri) -> json { std::string pathname = root_dir + uri.path(); std::fstream is(pathname.c_str()); if (!is) { return json::null(); } return json::parse(is); }; ``` ### Default values The JSON Schema Specification includes the ["default" keyword](https://json-schema.org/understanding-json-schema/reference/generic.html) for specifying a default value, but doesn't prescribe how implementations should use it during validation. Some implementations ignore the default keyword, others support updating the input JSON to fill in a default value for a missing key/value pair. This implementation outputs a JSONPatch document that may be further applied to the input JSON to add the missing key/value pairs. ### Custom error messages (since 1.2.0) jsoncons supports custom error messages via an opt-in `errorMessage` keyword. To enable this feature, refer to [custom error messages](./custom-error-messages.md). ### Examples The example schemas are from [JSON Schema Miscellaneous Examples](https://json-schema.org/learn/miscellaneous-examples.html), the [JSON Schema Test Suite](https://github.com/json-schema-org/JSON-Schema-Test-Suite), and user contributions. [Three ways of validating](#eg1) [Format validation](#eg2) [Resolving references to schemas defined in external files](#eg3) [Validate before decoding JSON into C++ class objects](#eg4) [Default values](#eg5)
#### Three ways of validating This example illustrates the use of three overloads of the `validate` function that throw, invoke a callback function, and write to a `json_visitor`. ```cpp #include #include #include using jsoncons::ojson; namespace jsonschema = jsoncons::jsonschema; int main() std::string schema_str = R"( { "$id": "https://example.com/arrays.schema.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "description": "A representation of a person, company, organization, or place", "type": "object", "properties": { "fruits": { "type": "array", "items": { "type": "string" } }, "vegetables": { "type": "array", "items": { "$ref": "#/$defs/veggie" } } }, "$defs": { "veggie": { "type": "object", "required": [ "veggieName", "veggieLike" ], "properties": { "veggieName": { "type": "string", "description": "The name of the vegetable." }, "veggieLike": { "type": "boolean", "description": "Do I like this vegetable?" } } } } } )"; std::string data_str = R"( { "fruits": [ "apple", "orange", "pear" ], "vegetables": [ { "veggieName": "potato", "veggieLike": true }, { "veggieName": "broccoli", "veggieLike": "false" }, { "veggieName": "carrot", "veggieLike": false }, { "veggieName": "Swiss Chard" } ] } )"; ojson schema = ojson::parse(schema_str); jsonschema::json_schema compiled = jsonschema::make_json_schema(std::move(schema)); ojson data = ojson::parse(data_str); std::cout << "\n(1) Validate using exceptions\n"; try { compiled.validate(data); } catch (const std::exception& e) { std::cout << e.what() << "\n"; } std::cout << "\n(2) Validate using reporter callback\n"; auto reporter = [](const jsonschema::validation_message& message) -> jsonschema::walk_result { std::cout << message.instance_location().string() << ": " << message.message() << "\n"; return jsonschema::walk_result::advance; }; compiled.validate(data, reporter); std::cout << "\n(3) Validate outputting to a json decoder\n"; jsoncons::json_decoder decoder; compiled.validate(data, decoder); ojson output = decoder.get_result(); std::cout << pretty_print(output) << "\n"; } ``` Output: ``` (1) Validate using exceptions /vegetables/1/veggieLike: Expected boolean, found string (2) Validate using reporter callback /vegetables/1/veggieLike: Expected boolean, found string /vegetables/3: Required property 'veggieLike' not found. (3) Validate outputting to a json decoder [ { "valid": false, "evaluationPath": "/properties/vegetables/items/$ref/properties/veggieLike/type", "schemaLocation": "https://example.com/arrays.schema.json#/$defs/veggie/properties/veggieLike", "instanceLocation": "/vegetables/1/veggieLike", "error": "Expected boolean, found string" }, { "valid": false, "evaluationPath": "/properties/vegetables/items/$ref/required", "schemaLocation": "https://example.com/arrays.schema.json#/$defs/veggie/required", "instanceLocation": "/vegetables/3", "error": "Required property 'veggieLike' not found." } ] ```
#### Format validation Since Draft 2019-09, format validation is disabled by default, but may be enabled by setting the evaluation option `require_format_validation` to `true`. ```cpp #include #include #include using jsoncons::json; using jsoncons::ojson; namespace jsonschema = jsoncons::jsonschema; int main() { json schema = json::parse(R"( { "$id": "/test_schema", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "Date": { "format": "date-time", "type": "string" } }, "required": [ "Date" ], "type": "object", "unevaluatedProperties": false } )"); auto compiled = jsoncons::jsonschema::make_json_schema(schema, jsonschema::evaluation_options{}.require_format_validation(true)); json data = json::parse(R"( { "Date" : "2024-03-19T26:34:56Z" } )"); jsoncons::json_decoder decoder; compiled.validate(data, decoder); ojson output = decoder.get_result(); std::cout << pretty_print(output) << "\n"; } ``` Output: ```json [ { "valid": false, "evaluationPath": "/properties/Date/format", "schemaLocation": "/test_schema#/properties/Date/format", "instanceLocation": "/Date", "error": "'2024-03-19T26:34:56Z' is not a RFC 3339 date-time string." }, { "valid": false, "evaluationPath": "/unevaluatedProperties/Date", "schemaLocation": "/test_schema", "instanceLocation": "/Date", "error": "Unevaluated property 'Date' but the schema does not allow unevaluated properties." } ] ```
#### Resolving references to schemas defined in external files In this example, the main schema is defined by ```cpp std::string main_schema = R"( { "$id" : "https://www.example.com/main", "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://localhost:1234/draft2020-12/object", "type": "object", "properties": { "name": {"$ref": "/name-defs.json#/$defs/orNull"} } } )"; ``` The main schema includes a reference using the `$ref` keyword to a second schema defined in an external file, `name-defs.json`, ```json { "$id" : "https://www.example.com/other", "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "orNull": { "anyOf": [ { "type": "null" }, { "$ref": "#" } ] } }, "type": "string" } ``` When building the main schema, the schema builder needs to resolve the URI 'https://www.example.com/name-defs.json#/$defs/orNull' via a URI resolver. The resolver does not need to supply that specific subschema, it is enough to supply the schema document '/name-defs.json'. The schema builder than processes that schema document and makes multiple entries into an internal validator registry, including an entry for 'https://www.example.com/name-defs.json#/$defs/orNull'. ```cpp int main() { json schema = json::parse(main_schema); // Data json data = json::parse(R"( { "name": { "name": null } } )"); try { // Throws schema_error if JSON Schema compilation fails jsonschema::json_schema compiled = jsonschema::make_json_schema(schema, resolver); std::string root_dir = "./input/jsonschema"; auto resolver = [&](const jsoncons::uri& uri) -> json { std::cout << "Requested URI: " << uri.string() << "\n"; std::cout << "base: " << uri.base().string() << ", path: " << uri.path() << "\n\n"; std::string pathname = root_dir + uri.path(); std::fstream is(pathname.c_str()); if (!is) { return json::null(); } return json::parse(is); }; // Will call the message handler function object for each schema violation compiled.validate(data, reporter); } catch (const std::exception& e) { std::cout << e.what() << '\n'; } } ``` Output: ``` Requested URI: https://www.example.com/name-defs.json#/$defs/orNull base: https://www.example.com/name-defs.json, path: /name-defs.json /name: Must be valid against at least one schema, but found no matching schemas Expected null, found object Expected string, found object ```
#### Validate before decoding JSON into C++ class objects This example illustrates decoding data that validates against "oneOf" into a `std::variant`. ```cpp // for brevity using jsoncons::json; namespace jsonschema = jsoncons::jsonschema; int main() { std::string schema_str = R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "job", "description": "job properties json schema", "$defs": { "os_properties": { "type": "object", "properties": { "command": { "description": "this is the OS command to run", "type": "string", "minLength": 1 } }, "required": [ "command" ], "additionalProperties": false }, "db_properties": { "type": "object", "properties": { "query": { "description": "this is db query to run", "type": "string", "minLength": 1 } }, "required": [ "query" ], "additionalProperties": false }, "api_properties": { "type": "object", "properties": { "target": { "description": "this is api target to run", "type": "string", "minLength": 1 } }, "required": [ "target" ], "additionalProperties": false } }, "type": "object", "properties": { "name": { "description": "name of the flow", "type": "string", "minLength": 1 }, "run": { "description": "job run properties", "type": "object", "oneOf": [ { "$ref": "#/$defs/os_properties" }, { "$ref": "#/$defs/db_properties" }, { "$ref": "#/$defs/api_properties" } ] } }, "required": [ "name", "run" ], "additionalProperties": false } )"; std::string data_str = R"( { "name": "testing flow", "run" : { "command": "some command" } } )"; try { json schema = json::parse(schema_str); json data = json::parse(data_str); // Throws schema_error if JSON Schema compilation fails jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); // Test that input is valid before attempting to decode if (compiled.is_valid(data)) { const ns::job_properties v = data.as(); // You don't need to reparse data_str std::string output; jsoncons::encode_json_pretty(v, output); std::cout << output << std::endl; // Verify that output is valid json test = json::parse(output); assert(compiled.is_valid(test)); } else { std::cout << "Invalid input\n"; } } catch (const std::exception& e) { std::cout << e.what() << '\n'; } } ``` Output: ``` { "name": "testing flow", "run": { "command": "some command" } } ```
#### Default values ```cpp #include #include #include #include // for brevity using jsoncons::json; namespace jsonschema = jsoncons::jsonschema; namespace jsonpatch = jsoncons::jsonpatch; int main() { json schema = json::parse(R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "bar": { "type": "string", "minLength": 4, "default": "bad" } } } )"); try { // Data json data = json::parse("{}"); // will throw schema_error if JSON Schema compilation fails jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); // will throw a validation_error when a schema violation happens json patch; compiled.validate(data, patch); std::cout << "Patch: " << patch << "\n"; std::cout << "Original data: " << data << "\n"; jsonpatch::apply_patch(data, patch); std::cout << "Patched data: " << data << "\n\n"; } catch (const std::exception& e) { std::cout << e.what() << "\n"; } } ``` Output: ``` Patch: [{"op":"add","path":"/bar","value":"bad"}] Original data: {} Patched data: {"bar":"bad"} ``` jsoncons-1.3.2/doc/ref/jsonschema/make_json_schema.md000066400000000000000000000202741477700171100226460ustar00rootroot00000000000000### jsoncons::jsonschema::make_json_schema ```cpp #include template json_schema make_json_schema(const Json& sch, (until 0.175.0) evaluation_options options = evaluation_options{}); (1) template json_schema make_json_schema(Json sch, (since 0.175.0) evaluation_options options = evaluation_options{}); template json_schema make_json_schema(const Json& sch, (until 0.175.0) const SchemaResolver& resolver, evaluation_options options = evaluation_options{}); (2) template json_schema make_json_schema(Json sch, (since 0.175.0) const SchemaResolver& resolver, evaluation_options options = evaluation_options{}); template json_schema make_json_schema(const Json& sch, (until 0.175.0) const std::string& retrieval_uri, evaluation_options options = evaluation_options{}); (3) template json_schema make_json_schema(Json sch, (since 0.175.0) const std::string& retrieval_uri, evaluation_options options = evaluation_options{}); template json_schema make_json_schema(const Json& sch, (until 0.175.0) const std::string& retrieval_uri, const SchemaResolver& resolver, evaluation_options options = evaluation_options{}); (4) template json_schema make_json_schema(Json sch, (since 0.175.0) const std::string& retrieval_uri, const SchemaResolver& resolver, evaluation_options options = evaluation_options{}); ``` Returns a [json_schema](json_schema.md) that represents a compiled JSON Schema document. #### Parameters
schema JSON Schema
resolver A function object with the signature of resolver being equivalent to
    Json fun(const jsoncons::uri& uri);
If unable to resolve the resource, it should return Json::null().
retrieval_uri Optional retrieval URI
options Evaluation options
#### Return value A [json_schema](json_schema.md) that represents a compiled JSON Schema document. #### Exceptions (1)-(4) Throws a [schema_error](schema_error.md) if JSON Schema compilation fails. ### Examples #### Draft 2020-12 example (from the JSON Schema Test Suite) ```cpp #include #include #include using jsoncons::json; namespace jsonschema = jsoncons::jsonschema; int main() { json schema = json::parse(R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://test.json-schema.org/typical-dynamic-resolution/root", "$ref": "list", "$defs": { "foo": { "$dynamicAnchor": "items", "type": "string" }, "list": { "$id": "list", "type": "array", "items": { "$dynamicRef": "#items" }, "$defs": { "items": { "$comment": "This is only needed to satisfy the bookending requirement", "$dynamicAnchor": "items" } } } } } )"); jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); json data = json::parse(R"(["foo", 42])"); jsoncons::json_decoder decoder; compiled.validate(data, decoder); ojson output = decoder.get_result(); std::cout << pretty_print(output) << "\n\n"; } ``` Output: ```json [ { "valid": false, "evaluationPath": "/$ref/items/$dynamicRef/type", "schemaLocation": "https://test.json-schema.org/typical-dynamic-resolution/root#items", "instanceLocation": "/1", "error": "Expected string, found integer" } ] ``` #### Draft 2019-09 example (from the JSON Schema Test Suite) ```cpp #include #include #include using jsoncons::json; namespace jsonschema = jsoncons::jsonschema; int main() { json schema = json::parse(R"( { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "properties": { "bar": { "type": "string" } } } ], "unevaluatedProperties": false } )"); jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); json data = json::parse(R"({"foo": "foo","bar": "bar","baz": "baz"})"); jsoncons::json_decoder decoder; compiled.validate(data, decoder); ojson output = decoder.get_result(); std::cout << pretty_print(output) << "\n\n"; } ``` Output: ```json [ { "valid": false, "evaluationPath": "/unevaluatedProperties/baz", "schemaLocation": "#", "instanceLocation": "/baz", "error": "Unevaluated property 'baz' but the schema does not allow unevaluated properties." } ] ``` #### Draft 07 example (from the JSON Schema Test Suite) ```cpp #include #include #include using jsoncons::json; namespace jsonschema = jsoncons::jsonschema; int main() { json schema = json::parse(R"( { "items": [{}], "additionalItems": {"type": "integer"} } )"); // Need to supply default version because schema does not have $schema keyword jsonschema::json_schema compiled = jsonschema::make_json_schema(schema, jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft7())); json data = json::parse(R"([ null, 2, 3, "foo" ])"); jsoncons::json_decoder decoder; compiled.validate(data, decoder); ojson output = decoder.get_result(); std::cout << pretty_print(output) << "\n\n"; } ``` Output: ```json [ { "valid": false, "evaluationPath": "/items/type", "schemaLocation": "#/additionalItems", "instanceLocation": "/3", "error": "Expected integer, found string" } ] ``` #### Cross draft example ```cpp #include #include #include using jsoncons::json; namespace jsonschema = jsoncons::jsonschema; int main() { json schema = json::parse(R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://example.com/schema", "$defs": { "foo": { "$schema": "http://json-schema.org/draft-07/schema#", "$id": "schema/foo", "definitions" : { "bar" : { "type" : "string" } } } }, "properties" : { "thing" : { "$ref" : "schema/foo#/definitions/bar" } } } )"); jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); json data = json::parse(R"({"thing" : 10})"); jsoncons::json_decoder decoder; compiled.validate(data, decoder); ojson output = decoder.get_result(); std::cout << pretty_print(output) << "\n\n"; } ``` Output: ```json [ { "valid": false, "evaluationPath": "/properties/thing/$ref/type", "schemaLocation": "https://example.com/schema/foo#/definitions/bar", "instanceLocation": "/thing", "error": "Expected string, found integer" } ] ``` jsoncons-1.3.2/doc/ref/jsonschema/make_schema.md000066400000000000000000000025531477700171100216150ustar00rootroot00000000000000### jsoncons::jsonschema::make_schema: (deprecated since 0.174.0) (removed in 1.0.0) ```cpp #include template std::shared_ptr> make_schema(const Json& schema); (1) template std::shared_ptr> make_schema(const Json& schema, const std::string& retrieval_uri); (2) (since 0.173.0) template std::shared_ptr> make_schema(const Json& schema, const std::string& retrieval_uri, const SchemaResolver& resolver); (3) (since 0.173.0) template std::shared_ptr> make_schema(const Json& schema, const SchemaResolver& resolver); (4) ``` Returns a `shared_ptr` to a `json_schema`. #### Parameters
schema JSON Schema
resolver A function object with the signature of resolver being equivalent to
    Json fun(const jsoncons::uri& uri);
#### Return value Returns a `shared_ptr` to a `json_schema`. #### Exceptions (1)-(2) Throws a [schema_error](schema_error.md) if JSON Schema compilation fails. jsoncons-1.3.2/doc/ref/jsonschema/schema_error.md000066400000000000000000000006471477700171100220330ustar00rootroot00000000000000### jsoncons::jsonschema::schema_error ```cpp #include ```
`jsoncons::jsonschema::schema_error` defines an exception type for reporting failures in jsonschema operations. ![schema_error](./diagrams/schema_error.png) #### Constructors schema_error(const std::string& message); #### Member functions const char* what() const noexcept Returns an error message jsoncons-1.3.2/doc/ref/jsonschema/schema_version.md000066400000000000000000000011141477700171100223550ustar00rootroot00000000000000### jsoncons::jsonschema::schema_version ```cpp #include struct schema_version; ``` Member functions static std::string draft4(); Returns "http://json-schema.org/draft-04/schema#". static std::string draft6(); Returns "http://json-schema.org/draft-06/schema#". static std::string draft7(); Returns "http://json-schema.org/draft-07/schema#". static std::string draft201909(); Returns "https://json-schema.org/draft/2019-09/schema". static std::string draft202012(); Returns "https://json-schema.org/draft/2020-12/schema". jsoncons-1.3.2/doc/ref/jsonschema/validation_error.md000066400000000000000000000006711477700171100227220ustar00rootroot00000000000000### jsoncons::jsonschema::validation_error ```cpp #include ```
`jsoncons::jsonschema::validation_error` defines an exception type for reporting violations of a JSON Schema. ![validation_error](./diagrams/validation_error.png) #### Constructors validation_error(const std::string& message); #### Member functions const char* what() const noexcept Returns an error message jsoncons-1.3.2/doc/ref/jsonschema/validation_message.md000066400000000000000000000017411477700171100232140ustar00rootroot00000000000000### jsoncons::jsonschema::validation_message ```cpp #include ```
`jsoncons::jsonschema::validation_message` defines a message type for reporting errors generated by a keyword. #### Member functions const jsonpointer::json_pointer& instance_location() const; The location of the JSON value within the instance being validated, expressed as a URI fragment-encoded JSON Pointer. const std::string& message() const; An error message that is produced by the validation. const jsonpointer::json_pointer& eval_path() const; The relative location of the validating keyword that follows the validation path, expressed as a JSONPointer. const jsoncons::uri& schema_path() const; The absolute, dereferenced location of the validating keyword, expressed as an absolute URI using the canonical URI of the relevant schema. const std::vector& details() const Returns a list of nested errors jsoncons-1.3.2/doc/ref/jsonschema/validation_output.md000066400000000000000000000014511477700171100231260ustar00rootroot00000000000000### jsoncons::jsonschema::validation_output ```cpp #include ```
`jsoncons::jsonschema::validation_output` defines a message type for reporting failures in jsonschema operations. #### Member functions const std::string& instance_location() const; The location of the JSON value within the instance being validated, expressed as a URI fragment-encoded JSON Pointer. const std::string& message() const; An error message that is produced by the validation. const std::string& schema_path() const; The absolute, dereferenced location of the validating keyword, expressed as an absolute URI using the canonical URI of the relevant schema. const std::vector& nested_errors() const Returns a list of nested errors jsoncons-1.3.2/doc/ref/jsonschema/walk_result.md000066400000000000000000000001451477700171100217070ustar00rootroot00000000000000### jsoncons::jsonschema::walk_result ```cpp enum class walk_result { advance, abort }; ``` jsoncons-1.3.2/doc/ref/mergepatch/000077500000000000000000000000001477700171100170165ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/mergepatch/apply_merge_patch.md000066400000000000000000000033671477700171100230340ustar00rootroot00000000000000### jsoncons::mergepatch::apply_merge_patch ```cpp #include template void apply_merge_patch(Json& target, const Json& patch); ``` Applies a merge patch to a `json` document. #### Return value None #### Exceptions None expected. ### Examples #### Apply a JSON Merge Patch This example is from [RFC 7386](https://datatracker.ietf.org/doc/html/rfc7386#section-3). ```cpp #include #include using jsoncons::json; namespace mergepatch = jsoncons::mergepatch; int main() { json doc = json::parse(R"( { "title": "Goodbye!", "author" : { "givenName" : "John", "familyName" : "Doe" }, "tags":[ "example", "sample" ], "content": "This will be unchanged" } )"); json doc2 = doc; json patch = json::parse(R"( { "title": "Hello!", "phoneNumber": "+01-123-456-7890", "author": { "familyName": null }, "tags": [ "example" ] } )"); mergepatch::apply_merge_patch(doc, patch); std::cout << "(1)\n" << pretty_print(doc) << '\n'; // Create a JSON Patch auto patch2 = mergepatch::from_diff(doc2,doc); std::cout << "(2)\n" << pretty_print(patch2) << '\n'; mergepatch::apply_merge_patch(doc2,patch2); std::cout << "(3)\n" << pretty_print(doc2) << '\n'; } ``` Output: ``` (1) { "author": { "familyName": null }, "phoneNumber": "+01-123-456-7890", "tags": ["example"], "title": "Hello!" } (2) { "author": { "givenName": "John" }, "content": "This will be unchanged", "phoneNumber": "+01-123-456-7890", "tags": ["example"], "title": "Hello!" } ``` jsoncons-1.3.2/doc/ref/mergepatch/from_diff.md000066400000000000000000000034551477700171100213020ustar00rootroot00000000000000### jsoncons::mergepatch::from_diff ```cpp #include template Json from_diff(const Json& source, const Json& target) ``` Create a JSON Merge Patch from a diff of two json documents. #### Return value Returns a JSON Merge Patch. ### Examples #### Create a JSON Merge Patch This example is from [RFC 7386](https://datatracker.ietf.org/doc/html/rfc7386#section-3). ```cpp #include #include using jsoncons::json; namespace mergepatch = jsoncons::mergepatch; int main() { json source = json::parse(R"( { "title": "Goodbye!", "author" : { "givenName" : "John", "familyName" : "Doe" }, "tags":[ "example", "sample" ], "content": "This will be unchanged" } )"); json target = json::parse(R"( { "title": "Hello!", "author": { "givenName": "John" }, "tags": [ "example" ], "content": "This will be unchanged", "phoneNumber": "\u002B01-123-456-7890" } )"); auto patch = mergepatch::from_diff(source, target); mergepatch::apply_merge_patch(source, patch); std::cout << "(1)\n" << pretty_print(patch) << '\n'; std::cout << "(2)\n" << pretty_print(source) << '\n'; } ``` Output: ``` (1) { "author": { "givenName": "John" }, "content": "This will be unchanged", "phoneNumber": "+01-123-456-7890", "tags": ["example"], "title": "Hello!" } (2) { "author": { "familyName": null }, "phoneNumber": "+01-123-456-7890", "tags": ["example"], "title": "Hello!" } (3) { "author": { "givenName": "John" }, "content": "This will be unchanged", "phoneNumber": "+01-123-456-7890", "tags": ["example"], "title": "Hello!" } ``` jsoncons-1.3.2/doc/ref/mergepatch/mergepatch.md000066400000000000000000000035671477700171100214720ustar00rootroot00000000000000### mergepatch extension The mergepatch extension implements the IETF standard [JSON Merge Patch](https://datatracker.ietf.org/doc/html/rfc7386)
apply_merge_patch Apply JSON Patch operations to a JSON document.
from_diff Create a JSON patch from a diff of two JSON documents.
### Examples This example is from [RFC 7386](https://datatracker.ietf.org/doc/html/rfc7386#section-3). ```cpp #include #include using jsoncons::json; namespace mergepatch = jsoncons::mergepatch; int main() { json doc = json::parse(R"( { "title": "Goodbye!", "author" : { "givenName" : "John", "familyName" : "Doe" }, "tags":[ "example", "sample" ], "content": "This will be unchanged" } )"); json doc2 = doc; json patch = json::parse(R"( { "title": "Hello!", "phoneNumber": "+01-123-456-7890", "author": { "familyName": null }, "tags": [ "example" ] } )"); mergepatch::apply_merge_patch(doc, patch); std::cout << "(1)\n" << pretty_print(doc) << '\n'; // Create a JSON Patch auto patch2 = mergepatch::from_diff(doc2,doc); std::cout << "(2)\n" << pretty_print(patch2) << '\n'; mergepatch::apply_merge_patch(doc2,patch2); std::cout << "(3)\n" << pretty_print(doc2) << '\n'; } ``` Output: ``` (1) { "author": { "familyName": null }, "phoneNumber": "+01-123-456-7890", "tags": ["example"], "title": "Hello!" } (2) { "author": { "givenName": "John" }, "content": "This will be unchanged", "phoneNumber": "+01-123-456-7890", "tags": ["example"], "title": "Hello!" } ``` jsoncons-1.3.2/doc/ref/msgpack/000077500000000000000000000000001477700171100163245ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/msgpack/basic_msgpack_cursor.md000066400000000000000000000103131477700171100230270ustar00rootroot00000000000000### jsoncons::msgpack::basic_msgpack_cursor ```cpp #include template< typename Source=jsoncons::binary_stream_source, typename Allocator=std::allocator> class basic_msgpack_cursor; ``` A pull parser for reporting MessagePack parse events. A typical application will repeatedly process the `current()` event and call the `next()` function to advance to the next event, until `done()` returns `true`. In addition, when positioned on a `begin_object` event, the `read_to` function can pull a complete object representing the events from `begin_object` to `end_object`, and when positioned on a `begin_array` event, a complete array representing the events from `begin_array` ro `end_array`. `basic_msgpack_cursor` is noncopyable and nonmoveable. Aliases for common sources are provided: Type |Definition --------------------|------------------------------ msgpack_stream_cursor |basic_msgpack_cursor msgpack_bytes_cursor |basic_msgpack_cursor ### Implemented interfaces [staj_cursor](staj_cursor.md) #### Constructors template basic_msgpack_cursor(Sourceable&& source, const msgpack_decode_options& options = msgpack_decode_options(), const Allocator& alloc = Allocator()); (1) template basic_msgpack_cursor(Sourceable&& source, std::error_code& ec); (2) template basic_msgpack_cursor(Sourceable&& source, const msgpack_decode_options& options, std::error_code& ec); (3) template basic_msgpack_cursor(std::allocator_arg_t, const Allocator& alloc, Sourceable&& source, const msgpack_decode_options& options, std::error_code& ec); (4) Constructor (1) reads from a buffer or stream source and throws a [ser_error](ser_error.md) if a parsing error is encountered while processing the initial event. Constructors (2)-(4) read from a buffer or stream source and set `ec` if a parsing error is encountered while processing the initial event. Note: It is the programmer's responsibility to ensure that `basic_msgpack_cursor` does not outlive any source passed in the constuctor, as `basic_msgpack_cursor` holds a pointer to but does not own this object. #### Parameters `source` - a value from which a `source_type` is constructible. #### Member functions bool done() const override; Checks if there are no more events. const staj_event& current() const override; Returns the current [staj_event](basic_staj_event.md). void read_to(json_visitor& visitor) override Feeds the current and succeeding [staj events](basic_staj_event.md) through the provided [visitor](basic_json_visitor.md), until the visitor indicates to stop. If a parsing error is encountered, throws a [ser_error](ser_error.md). void read_to(json_visitor& visitor, std::error_code& ec) override Feeds the current and succeeding [staj events](basic_staj_event.md) through the provided [visitor](basic_json_visitor.md), until the visitor indicates to stop. If a parsing error is encountered, sets `ec`. void next() override; Advances to the next event. If a parsing error is encountered, throws a [ser_error](ser_error.md). void next(std::error_code& ec) override; Advances to the next event. If a parsing error is encountered, sets `ec`. const ser_context& context() const override; Returns the current [context](ser_context.md) void reset(); Reset cursor to read another value from the same source template reset(Sourceable&& source) Reset cursor to read new value from a new sources #### Non-member functions template staj_filter_view operator|(basic_msgpack_cursor& cursor, std::function pred); ### See also [staj_event](../basic_staj_event.md) [staj_array_iterator](../staj_array_iterator.md) [staj_object_iterator](../staj_object_iterator.md) jsoncons-1.3.2/doc/ref/msgpack/basic_msgpack_encoder.md000066400000000000000000000270051477700171100231370ustar00rootroot00000000000000### jsoncons::msgpack::basic_msgpack_encoder ```cpp #include template< typename Sink> > class basic_msgpack_encoder : public jsoncons::json_visitor ``` `basic_msgpack_encoder` is noncopyable. ![basic_msgpack_encoder](./diagrams/basic_msgpack_encoder.png) Four specializations for common character types and result types are defined: Type |Definition ---------------------------|------------------------------ msgpack_stream_encoder |basic_msgpack_encoder bson_bytes_encoder |basic_msgpack_encoder>> #### Member types Type |Definition ---------------------------|------------------------------ char_type |char sink_type |Sink string_view_type | #### Constructors explicit basic_msgpack_encoder(Sink&& sink) Constructs a new encoder that writes to the specified destination. #### Destructor virtual ~basic_msgpack_encoder() noexcept #### Member functions void reset(); Reset encoder to write another value to the same sink void reset(Sink&& sink) Reset encoder to write a new value to a new sink #### Inherited from [jsoncons::basic_json_visitor](basic_json_visitor.md) void flush(); (1) bool begin_object(semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (2) bool begin_object(std::size_t length, semantic_tag tag=semantic_tag::none, const ser_context& context = ser_context()); (3) bool end_object(const ser_context& context = ser_context()); (4) bool begin_array(semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (5) bool begin_array(std::size_t length, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (6) bool end_array(const ser_context& context=ser_context()); (7) bool key(const string_view_type& name, const ser_context& context=ser_context()); (8) bool null_value(semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (9) bool bool_value(bool value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (10) bool string_value(const string_view_type& value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (11) bool byte_string_value(const byte_string_view& source, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (12) (until 0.152.0) template bool byte_string_value(const ByteStringLike& souce, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (12) (since 0.152.0) template bool byte_string_value(const ByteStringLike& souce, uint64_t ext_tag, const ser_context& context=ser_context()); (13) (since 0.152.0) bool uint64_value(uint64_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (14) bool int64_value(int64_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (15) bool half_value(uint16_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (16) bool double_value(double value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (17) bool begin_object(semantic_tag tag, const ser_context& context, std::error_code& ec); (18) bool begin_object(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec); (19) bool end_object(const ser_context& context, std::error_code& ec); (20) bool begin_array(semantic_tag tag, const ser_context& context, std::error_code& ec); (21) bool begin_array(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec); (22) bool end_array(const ser_context& context, std::error_code& ec); (23) bool key(const string_view_type& name, const ser_context& context, std::error_code& ec); (24) bool null_value(semantic_tag tag, const ser_context& context, std::error_code& ec); (25) bool bool_value(bool value, semantic_tag tag, const ser_context& context, std::error_code& ec); (26) bool string_value(const string_view_type& value, semantic_tag tag, const ser_context& context, std::error_code& ec); (27) bool byte_string_value(const byte_string_view& source, semantic_tag tag, const ser_context& context, std::error_code& ec); (28) (until 0.152.0) template bool byte_string_value(const ByteStringLike& source, semantic_tag tag, const ser_context& context, std::error_code& ec); (28) (since 0.152.0) template bool byte_string_value(const ByteStringLike& source, uint64_t ext_tag, const ser_context& context, std::error_code& ec); (29) (since 0.152.0) bool uint64_value(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (30) bool int64_value(int64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (31) bool half_value(uint16_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (32) bool double_value(double value, semantic_tag tag, const ser_context& context, std::error_code& ec); (33) template bool typed_array(const span& data, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (34) bool typed_array(half_arg_t, const span& s, semantic_tag tag = semantic_tag::none, const ser_context& context = ser_context()); (35) bool begin_multi_dim(const span& shape, semantic_tag tag, const ser_context& context); (36) bool end_multi_dim(const ser_context& context=ser_context()); (37) template bool typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (38) bool typed_array(half_arg_t, const span& s, semantic_tag tag, const ser_context& context, std::error_code& ec); (39) bool begin_multi_dim(const span& shape, semantic_tag tag, const ser_context& context, std::error_code& ec); (40) bool end_multi_dim(const ser_context& context, std::error_code& ec); (41) (1) Flushes whatever is buffered to the destination. (2) Indicates the begining of an object of indefinite length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (3) Indicates the begining of an object of known length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (4) Indicates the end of an object. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (5) Indicates the beginning of an indefinite length array. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (6) Indicates the beginning of an array of known length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (7) Indicates the end of an array. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (8) Writes the name part of an object name-value pair. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (9) Writes a null value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (10) Writes a boolean value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (11) Writes a text string value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (12) Writes a byte string value `source` with a generic tag. Type `ByteStringLike` must be a container that has member functions `data()` and `size()`, and member type `value_type` with size exactly 8 bits (since 0.152.0.) Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (13) Writes a byte string value `source` with a format specific tag, `ext_tag`. Type `ByteStringLike` must be a container that has member functions `data()` and `size()`, and member type `value_type` with size exactly 8 bits (since 0.152.0.) Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (14) Writes a non-negative integer value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (15) Writes a signed integer value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (16) Writes a half precision floating point value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (17) Writes a double precision floating point value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (18)-(33) Same as (2)-(17), except sets `ec` and returns `false` on parse errors. ### Examples ### See also [byte_string_view](../byte_string_view.md) jsoncons-1.3.2/doc/ref/msgpack/decode_msgpack.md000066400000000000000000000055711477700171100216060ustar00rootroot00000000000000### jsoncons::msgpack::decode_msgpack ```cpp #include template T decode_msgpack(const std::vector& source, const msgpack_decode_options& options = msgpack_decode_options()); (1) (until 0.152.0) template T decode_msgpack(const Source& source, const msgpack_decode_options& options = msgpack_decode_options()); (1) (since 0.152.0) template T decode_msgpack(std::istream& is, const msgpack_decode_options& options = msgpack_decode_options()); (2) template T decode_msgpack(InputIt first, InputIt last, const msgpack_decode_options& options = msgpack_decode_options()); (3) (since 0.153.0) template T decode_msgpack(const allocator_set& alloc_set, const Source& source, const msgpack_decode_options& options = msgpack_decode_options()); (4) (since 0.171.0) template T decode_msgpack(const allocator_set& alloc_set, std::istream& is, const msgpack_decode_options& options = msgpack_decode_options()); (5) (since 0.171.0) ``` Decodes a [MessagePack](http://msgpack.org/index.html) data format into a C++ data structure. (1) Reads MessagePack data from a contiguous byte sequence provided by `source` into a type T, using the specified (or defaulted) [options](msgpack_options.md). Type `Source` must be a container that has member functions `data()` and `size()`, and member type `value_type` with size exactly 8 bits (since 0.152.0.) Any of the values types `int8_t`, `uint8_t`, `char`, `unsigned char` and `std::byte` (since C++17) are allowed. Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). (2) Reads MessagePack data from a binary stream into a type T, using the specified (or defaulted) [options](msgpack_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). (3) Reads MessagePack data from the range [`first`,`last`) into a type T, using the specified (or defaulted) [options](msgpack_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). Functions (4)-(5) are identical to (1)-(2) except an [allocator_set](../allocator_set.md) is passed as an additional argument and provides allocators for result data and temporary allocations. #### Exceptions Throws a [ser_error](../ser_error.md) if parsing fails, and a [conv_error](conv_error.md) if type conversion fails. ### See also [encode_msgpack](encode_msgpack.md) encodes a json value to the [MessagePack](http://msgpack.org/index.html) data format. jsoncons-1.3.2/doc/ref/msgpack/diagrams/000077500000000000000000000000001477700171100201135ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/msgpack/diagrams/basic_msgpack_encoder.png000066400000000000000000000124231477700171100251100ustar00rootroot00000000000000PNG  IHDR_e#tEXtmxfile%3Cmxfile%20modified%3D%222020-03-31T16%3A42%3A10.008Z%22%20host%3D%22app.diagrams.net%22%20agent%3D%225.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F80.0.3987.149%20Safari%2F537.36%22%20etag%3D%22Iqb_YLSfIjF7yDT2yHuE%22%20version%3D%2212.9.6%22%20type%3D%22device%22%3E%3Cdiagram%20id%3D%22iK-0d-7Yl-5MlnfMu26I%22%20name%3D%22Page-1%22%3EzVZNc9owEP01PqZjLJLCMTE0bRkyTekM5MQo1sZWI0tUFmD66ythCVu2mSQzHJpLtG%2B1%2BnjvrUyA4ry8l3iTzQUBFkQhKQM0CaJoEKKR%2FmeQQ4UMxxZIJSV2Ug0s6F9wlRbdUgKFN1EJwRTd%2BGAiOIdEeRiWUuz9aS%2BC%2BbtucAodYJFg1kWXlKisQkfXYY1%2FBZpmbudBaDM5dpMtUGSYiH0DQtMAxVIIVY3yMgZmyHO8VHVfzmRPB5PA1XsKpg%2B%2FSj57XGRR%2FGemlvP8qfx%2BZVfZYba1F37GBU3WvwvB1ztaUCVkEN0wvcPdsxmlZmQvpA6OJSm2nIDZKNTpfUYVLDY4Mdm99oXGMpUzHQ1O1c2Du1OAVFA2IHuRexA5KHnQU2x2ZDm1pho4jve1RAMnUdaQZ2gxbF2RnlauidMDy90HePx8hse8SDUPr2vgiW6NXiovS%2B4LZSwWTKtmahEc%2FzReKCleoZFBN2iMyGXk%2BP%2F0GHX06NAKnNyaB0JHCcOFVstnEkqqVpZ0M34y40%2FXNpqUjdTk4AKuD79yC5igUWXCuuwYubqzGhRiKxN423gKyxTU240OxHvuuoo2FOsTzGESGFZ05z%2BSfSraHX4Iqm92MszQ90uEWj6orm2Lmm9aa51xy3ej1joVLZ11jpY6XfpdLkt38yyaPazwT0ivlo8z2M2gp%2Bu%2F8QwkVZhr0fRHj%2BJU4rxjPd1Wyjeb355ccGj1soUwoyk3jtVG0c8JujNNSvXn6tYmckqI2ab3nfBfkks0ftgSMuxpfNTjo%2Bjjja%2FD%2BmNZKVj%2F5EDTfw%3D%3D%3C%2Fdiagram%3E%3C%2Fmxfile%3E-IDATx^_MmǗЄW$IyK dLB J3BP&M ɟ1H n&w^{}:{Jwy^󣇈|@kњa7ON>Ke 7Ǘ/_x}*mG+K2)_Ln·LYoSo .iGe> ^ o) TmP8V[·F< }#'|[.1 8VuN=C/O}*v={H~5VQO[Nf͚%|MQ݌Bn+Gmj>Bݷs{WmV>}eĉJ۷pB+bڵr=*;wv<|Ç2o޼յBmȑr#G#;/TtSLl {>|5kDǡ"3f_^k9q >i}[ܼ S _'>y$4A _ {?Vx(xqmOvm~Ldj_5KD'L{6mL({͢iHVo!BGrUsV"^j8 9ŋT¶Vc`j5$3Z5SNfu2i*6C C[+TY ZW3oXV^Z',C߿rVZUMmsT|m ]*z*OovcQ֪|akd1޼ySN:%^z5|sǏ˖-[СCE[ӧO|6nܸzNmYⰺ_6l0={v}iր5GDeUOJjU6 +/CF͛=F"N] cZVz8G/]TyǨ*񈎞Nzو3VaOX ')o}ܱ0*^[-vg{+۶m _@wND+"ݛ}ېtݕ`[ (8TWQ=J0iu=m/qV*<kwgl߾]޽eC߾}>XvZ쮂pCA^*훴MՐu47lM%һw- _$ɓ̙3Q WFcܸqc c?+F 8.juX&յi}E%gF7n#F"!&~̜9R#q3uH|QQ?~|ƍݻw_7nhkT ??22P"T_B bŊ&L`.[,jf~Ҫ7oxi,Y ֪-|qB |Akc̗/_FPw @mё LI#Ɔʕ+1`2žJ̾=h:>|g-ZuW ވȀVnEo“k7AX տyڶh_@Lݴ~'0}b{S^r|GeN6bROJ=N/ voC =5Y/_mY "?5ǡ.g8h9sDklEň=Y¶C 2IbVd[ .H/ڸu,T'[o4hoN2l bT7ilk`q;6~Rk',E8l[۶C7gɞoo^[૽RG{/ _@ rX,sNJzxt|6@Zjǯmڣꫯ[/~me'C3z)7} _@Kw;] Xi]:KoR΀PC,Zo}zr)@+mm4LYS*^}  |=f>S*^}  |=f>S*^}  |=f>S*^}  |=f>S*^}  |=f>S*^}  |=f>S*^}  |=f>S*^}  |=f>S*^}  |=f>S*^}  |=f>S*^}  |=f>S*^}  |=f>S*^}  |=f>S*^}  |=f>S*^}  |=f>S*^}  |=f>S*^}  |=f>S*^}  |=f>S*^}  |=f>S*^}  |=f>S*^}  |=f>S*^}  |=f>C"EDW15">fiХ^"_DNȣv4iEd7'Q@—D@;kmgΌ)|ȧvWl$"DD+߿D䁈28sDD0P8>v?/23"29{xH9)"jL' zM|X}t ↿gulP+/oRw "r8'> "LD,B9vsc:^5|z&"wRIA}A[V6n<0)ŝ5_ͭ\.tQFૐA Tsc*~|>ت6lX_qM=0a}`?+|5νZb_N ,[!x>k[cVG|n .6 Ɗ؀V!|-G:LfQ\4 T-lQAW1*$f|q஧Y#|;#|;4OEVY 4}ϴ7.mm; vbZ ڮMon\E>-rv w( ŐIk*`WZ8 v5|'i=v.WԝE7-m;VH|[%|[.1 TJ* V_^ Ty hܓ,rT1ȿb82 Y$"`Pdנ`jYep#"OC+#@E@ @,rA& 6JU*^@>,rT1ȿb82 Y$"`Pdנ`jYep#"OC+#@E@ @,rA& 6JU*^@>,rT1ȿb82 Y$"`Pdנ`jYep#"OC+#@E@ @,rA& 6JU*^@>,rT1ȿb82 Y$"fxb3u\į^jveN:eFk,kmܸqf…Fl8q9x:th '+A .`q+E E9s\r-ʥH'";  I&#G[n'O?lݺ̚5UȴiӬݻg'/^4˖-3<0۷o)Skך'3gΘפh"g5 2\W\1b[[V\9h0ܾ},XsN[JV}z;ֲKjyIKw|ٷo_+.\h;Uɒ9o!1bSʘW:AYM<~M "8#"͛VHɢ:w\8O>̞=۬Z."D% lb/)D̛7˗[[w"d<v\YT3jwիWC1cX?GݲӟV~-U5ʎY={M6=oW&OlŧڔevRIv+G8udvq\1nn:3lذ=zd~򓟘7x#<@d5&8:{ 3fǏw%WF%Ն+*wJlmCU%Y7sLs5#Q)UCZDYM<~@RU;%}W~OT*z^/Ҽ_4~i bL&@d5!Xv}W!0qDl?4t81B 3u]!=[IEl=_4DVDg?mjOBd5>UWdC`Ca}&3pw%Mzng{]rÕ0&uDc'Ȋ=W:}WTJ $PGl ՞"!āwȪ*rۉ@"mNy=VX#_( Uje,VAZ@d2l]"YUEy;([d!:Ec!Ȋ%Q*2Y{ /!HB* "AB[U}54 ulhcX?BjNMls\"+/9+@>B* "A@(b_k=laDU#R '!"P"+EoaF]E>8[e~@d'VZZƇ}WѦ A ~2>r9C@dUɅ@F]S@;[E~@d7vX^ԇ}WѤ@te>J@dÈ,H"PshAGkE#jv@P[y?ׂ1=@dz%}Wy@ @Qb5"'DVqWIFcƌ1֭3BUB-^"/pDV8,護2o9ry7]!3@-DVxGkaG3gСC旿ٹstٶmYdI}x@[zƹhYo6۷o76#G,Sk{UVٹdKk͚5ffԩф ?O3?uV+yQ 8bi"ɓ'}[weƍg.\h^jN8a .}SXs@1[֭UIŸ?~` /`я~dD\B''"E[tpך]Oa=uvٺniEv+nr݈,zzK3 O"\vLU7n tJţJ+Tډ,/M~&$ *lDdpn/PoRE![|r?`eSOi_y{DG&,=Y<)թ'+Ȓ~ Ǐms2B$ЯӅ~nZ%˯ָI,vwwdMw,3Yz~e͕O޽{r0KOVzJYҶ;jde.}-?RIC6?zotM(֣)ϸJ?.YOi5?NU\?l Ni]'&*3~.tK>] !Nꩻ{)d?~ |0kU(|w}T?=]}b>Pdnijs|_OBo|52(hUtm78Q\PxvaF*Urhrb/scU)pm6!=]ck|7믿 DJ[qwI-*g8'TVg?O{FĖ/wOҹ M Mdͅ#Pz%;s]oВ 1 *YŦ##lVdrU֥KlUkɒ%@_W~E +|0ZQA4E+DViZ-.{YJ~o P&"̨olDVbE,CVtC(@ Uhj?"!E,AV P$~+DVQXǰ! ZO@O-Y=+Yх~)Z ,@/W^߳bZ;! ZK @WC[%Z @7BWncY ~S!Б@h 1dըplU"KiЯf^`U\![@KdUr * TL=tq劬*c2;)>X !kU]kPq5@hWqE2A'"' _+E$iPqլ[DVQŧBTٯ"WHqU,RmTZU/r$E Tf]#b*>NZU-rcZw!j&"+$nWV9" @qEN{ekk+֞@}@F >2^&(+W] q-@Ze-r;πQ(:WQ Ne [ @ZE/rY(qEN5"(_Epz?U#'3@de-@Z.rp ?yYdJ$_+"W+ I{n /wO@\5(9p+pq3pmf^{!qb__~ټO?mM*7Kol,@YYA&7sLGW_}\v  DVOxүzYfYx:ujիWͮ]̩Sȑ#69n8pB#68qYK ;}Z>]pR7vV%Kv2gĈO*cJ^%8asc=5}h,DVcC~-9~h.r,7o޴BJչsyffժUvQ$B.YxE% ,"3o޼k/_nncȓT߿#ۅre S'ewtl["Dϫ5j )Yw5W62cƌA}SYמ0GM<يOɝG*L*,Wʏ]9hsũ{@'kϞ=fӦM^6n7>mʓ"֭[g GOS6<@d5&8Z'nxHY*tMܹ*+>\U’{emŊViI7*3gNxwNmI+n5LEV~ULS*[siSmˤšͷ[j/}ovs k=" .rv"+$$k%˭ܸqcPJlϹ- EZ7YY*Y5id,O%ƫ]2ͧ AYM<~M "UdUnzGѭ3َ??~VDH3Raw^sֶ$KJ~vaR%+m~:{lboVtUlKɒ-S/,dI/jwW8JY򌎕'+vuo"@Y (ZdrOӅGׯ_tPOH/_ܜ?6埆Ofi,+i.26lYOEqt{P{\&*|Ĩ\*겾Ӳ_M%jj;hU-re d`ei/߱E@dI P~-r~uǭEƟޭe^FdBg!P? @_"(q1/4@Di D5(ظZ*DVxS (@d\AiI_@d!\>nnnt)segi&kԩSsc@ xY.3@*Urah"c+nܸaO%J%ωxIYNsjO{ɼ׿[o,SOBرÜ>}}a5)s_}U'.t0ʕ< FAu#Uf@Y3d@fvӪH!"5 @@ Y%@eH@ " @@ Y%@eH@ Q[ZIENDB`jsoncons-1.3.2/doc/ref/msgpack/encode_msgpack.md000066400000000000000000000106331477700171100216130ustar00rootroot00000000000000### jsoncons::msgpack::encode_msgpack Encodes a C++ data structure into the [MessagePack](http://msgpack.org/index.html) data format. ```cpp #include template void encode_msgpack(const T& jval, ByteContainer& cont, const msgpack_decode_options& options = msgpack_decode_options()); (1) template void encode_msgpack(const T& jval, std::ostream& os, const msgpack_decode_options& options = msgpack_decode_options()); (2) template void encode_msgpack(const allocator_set& alloc_set, const T& jval, ByteContainer& cont, const msgpack_decode_options& options = msgpack_decode_options()); (3) (since 0.171.0) template void encode_msgpack(const allocator_set& alloc_set, const T& jval, std::ostream& os, const msgpack_decode_options& options = msgpack_decode_options()); (4) (since 0.171.0) ``` (1) Writes a value of type T into a byte container in the MessagePack data format, using the specified (or defaulted) [options](msgpack_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). Type `ByteContainer` must be back insertable and have member type `value_type` with size exactly 8 bits (since 0.152.0.) Any of the values types `int8_t`, `uint8_t`, `char`, `unsigned char` and `std::byte` (since C++17) are allowed. (2) Writes a value of type T into a binary stream in the MessagePack data format, using the specified (or defaulted) [options](msgpack_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). Functions (3)-(4) are identical to (1)-(2) except an [allocator_set](../allocator_set.md) is passed as an additional argument. ### Examples #### MessagePack example ```cpp #include #include using namespace jsoncons; using namespace jsoncons::msgpack; int main() { ojson j1; j1["zero"] = 0; j1["one"] = 1; j1["two"] = 2; j1["null"] = null_type(); j1["true"] = true; j1["false"] = false; j1["max int64_t"] = (std::numeric_limits::max)(); j1["max uint64_t"] = (std::numeric_limits::max)(); j1["min int64_t"] = (std::numeric_limits::lowest)(); j1["max int32_t"] = (std::numeric_limits::max)(); j1["max uint32_t"] = (std::numeric_limits::max)(); j1["min int32_t"] = (std::numeric_limits::lowest)(); j1["max int16_t"] = (std::numeric_limits::max)(); j1["max uint16_t"] = (std::numeric_limits::max)(); j1["min int16_t"] = (std::numeric_limits::lowest)(); j1["max int8_t"] = (std::numeric_limits::max)(); j1["max uint8_t"] = (std::numeric_limits::max)(); j1["min int8_t"] = (std::numeric_limits::lowest)(); j1["max double"] = (std::numeric_limits::max)(); j1["min double"] = (std::numeric_limits::lowest)(); j1["max float"] = (std::numeric_limits::max)(); j1["zero float"] = 0.0; j1["min float"] = (std::numeric_limits::lowest)(); j1["Key too long for small string optimization"] = "String too long for small string optimization"; std::vector cont; encode_msgpack(j1, cont); ojson j2 = decode_msgpack(cont); std::cout << pretty_print(j2) << '\n'; } ``` Output: ```json { "zero": 0, "one": 1, "two": 2, "null": null, "true": true, "false": false, "max int64_t": 9223372036854775807, "max uint64_t": 18446744073709551615, "min int64_t": -9223372036854775808, "max int32_t": 2147483647, "max uint32_t": 4294967295, "min int32_t": -2147483648, "max int16_t": 32767, "max uint16_t": 65535, "min int16_t": -32768, "max int8_t": 127, "max uint8_t": 255, "min int8_t": -128, "max double": 1.79769313486232e+308, "min double": -1.79769313486232e+308, "max float": 3.40282346638529e+038, "zero float": 0.0, "min float": -3.40282346638529e+038, "Key too long for small string optimization": "String too long for small string optimization" } ``` ### See also [decode_msgpack](decode_msgpack) decodes a [MessagePack](http://msgpack.org/index.html) data format to a json value. jsoncons-1.3.2/doc/ref/msgpack/msgpack.md000066400000000000000000000107031477700171100202740ustar00rootroot00000000000000### msgpack extension The msgpack extension implements encode to and decode from the [MessagePack](http://msgpack.org/index.html) data format. You can either parse into or serialize from a variant-like data structure, [basic_json](../basic_json.md), or your own data structures, using [json_type_traits](../json_type_traits.md). [decode_msgpack](decode_msgpack.md) [basic_msgpack_cursor](basic_msgpack_cursor.md) [encode_msgpack](encode_msgpack.md) [basic_msgpack_encoder](basic_msgpack_encoder.md) [msgpack_options](msgpack_options.md) #### Mappings between MessagePack and jsoncons data items MessagePack data item |ext type | jsoncons data item|jsoncons tag -------------------------------------------------- |-----------------|---------------|------------------ nil | | null | true, false | | bool | negative fixnum, int 8, int 16, int 32, int 64 | | int64 | positive fixnum, uint 8, uint 16, uint 32, uint 64| | uint64 | float32, float64 | | double | fixstr, str 8, str 16, str 32 | | string | bin 8, bin 16, bin 32 | | byte_string | fixext1, fixext2, fixext4, fixext8, fixext16, ext8, ext16, ext32 |0-127| byte_string | 4 byte length |-1 (timestamp 32) |uint64| seconds 8 byte length |-1 (timestamp 64) |string| epoch_nanosecond 12 byte length |-1 (timestamp 96) |string| epoch_nanosecond array | | array | map | | object | ### Examples #### ext format code example ```cpp #include #include #include using namespace jsoncons; int main() { std::vector input = { 0x82, // map, length 2 0xa5, // string, length 5 'H','e','l','l','o', 0xa5, // string, length 5 'W','o','r','l','d', 0xa4, // string, length 4 'D','a','t','a', 0xc7, // ext8 format code 0x06, // length 6 0x07, // type 'f','o','o','b','a','r' }; ojson j = msgpack::decode_msgpack(input); std::cout << "(1)\n" << pretty_print(j) << "\n\n"; std::cout << "(2) " << j["Data"].tag() << "(" << j["Data"].ext_tag() << ")\n\n"; // Get ext value as a std::vector auto v = j["Data"].as>(); std::cout << "(3)\n"; std::cout << byte_string_view(v) << "\n\n"; std::vector output; msgpack::encode_msgpack(j,output); assert(output == input); } ``` Output: ``` (1) { "Hello": "World", "Data": "Zm9vYmFy" } (2) ext(7) (3) 66,6f,6f,62,61,72 ``` #### JSON to message pack Input JSON file `book.json` ```json [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 } ] ``` ```cpp #include #include using namespace jsoncons; int main() { std::ifstream is("input/book.json"); ojson j1; is >> j1; // Encode ojson to MessagePack std::vector v; msgpack::encode_msgpack(j1, v); // Decode MessagePack to ojson ojson j2 = msgpack::decode_msgpack(v); std::cout << pretty_print(j2) << '\n'; // or to json (now alphabetically sorted) json j3 = msgpack::decode_msgpack(v); // or to wjson (converts from utf8 to wide characters) wjson j4 = msgpack::decode_msgpack(v); } ``` Output: ```json [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 } ] ``` jsoncons-1.3.2/doc/ref/msgpack/msgpack_options.md000066400000000000000000000012011477700171100220400ustar00rootroot00000000000000### jsoncons::msgpack::msgpack_options ```cpp #include class msgpack_options; ```
![msgpack_options](./diagrams/msgpack_options.png) Specifies options for reading and writing CBOR. #### Constructors msgpack_options() Constructs a `msgpack_options` with default values. #### Modifiers void max_nesting_depth(int depth) The maximum nesting depth allowed when decoding and encoding MessagePack. Default is 1024. Parsing can have an arbitrarily large depth limited only by available memory. Serializing a [basic_json](../basic_json.md) to MessagePack is limited by stack size. jsoncons-1.3.2/doc/ref/ubjson/000077500000000000000000000000001477700171100161775ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/ubjson/basic_ubjson_cursor.md000066400000000000000000000102501477700171100225550ustar00rootroot00000000000000### jsoncons::ubjson::basic_ubjson_cursor ```cpp #include template< typename Source=jsoncons::binary_stream_source, typename Allocator=std::allocator> class basic_ubjson_cursor; ``` A pull parser for reporting UBJSON parse events. A typical application will repeatedly process the `current()` event and call the `next()` function to advance to the next event, until `done()` returns `true`. In addition, when positioned on a `begin_object` event, the `read_to` function can pull a complete object representing the events from `begin_object` to `end_object`, and when positioned on a `begin_array` event, a complete array representing the events from `begin_array` ro `end_array`. `basic_ubjson_cursor` is noncopyable and nonmoveable. Aliases for common sources are provided: Type |Definition --------------------|------------------------------ ubjson_stream_cursor |basic_ubjson_cursor ubjson_bytes_cursor |basic_ubjson_cursor ### Implemented interfaces [staj_cursor](staj_cursor.md) #### Constructors template basic_ubjson_cursor(Sourceable&& source, const ubjson_decode_options& options = ubjson_decode_options(), const Allocator& alloc = Allocator()); (1) template basic_ubjson_cursor(Sourceable&& source, std::error_code& ec); (2) template basic_ubjson_cursor(Sourceable&& source, const ubjson_decode_options& options, std::error_code& ec); (3) template basic_ubjson_cursor(std::allocator_arg_t, const Allocator& alloc, Sourceable&& source, const ubjson_decode_options& options, std::error_code& ec); (4) Constructor (1) reads from a buffer or stream source and throws a [ser_error](ser_error.md) if a parsing error is encountered while processing the initial event. Constructors (2)-(4) read from a buffer or stream source and set `ec` if a parsing error is encountered while processing the initial event. Note: It is the programmer's responsibility to ensure that `basic_ubjson_cursor` does not outlive any source passed in the constuctor, as `basic_ubjson_cursor` holds a pointer to but does not own this object. #### Parameters `source` - a value from which a `source_type` is constructible. #### Member functions bool done() const override; Checks if there are no more events. const staj_event& current() const override; Returns the current [staj_event](basic_staj_event.md). void read_to(json_visitor& visitor) override Feeds the current and succeeding [staj events](basic_staj_event.md) through the provided [visitor](basic_json_visitor.md), until the visitor indicates to stop. If a parsing error is encountered, throws a [ser_error](ser_error.md). void read_to(json_visitor& visitor, std::error_code& ec) override Feeds the current and succeeding [staj events](basic_staj_event.md) through the provided [visitor](basic_json_visitor.md), until the visitor indicates to stop. If a parsing error is encountered, sets `ec`. void next() override; Advances to the next event. If a parsing error is encountered, throws a [ser_error](ser_error.md). void next(std::error_code& ec) override; Advances to the next event. If a parsing error is encountered, sets `ec`. const ser_context& context() const override; Returns the current [context](ser_context.md) void reset(); Reset cursor to read another value from the same source template reset(Sourceable&& source) Reset cursor to read new value from a new sources #### Non-member functions template staj_filter_view operator|(basic_ubjson_cursor& cursor, std::function pred); ### See also [staj_event](../basic_staj_event.md) [staj_array_iterator](../staj_array_iterator.md) [staj_object_iterator](../staj_object_iterator.md) jsoncons-1.3.2/doc/ref/ubjson/basic_ubjson_encoder.md000066400000000000000000000270111477700171100226620ustar00rootroot00000000000000### jsoncons::ubjson::basic_ubjson_encoder ```cpp #include template< typename Sink> > class basic_ubjson_encoder : public jsoncons::json_visitor ``` `basic_ubjson_encoder` is noncopyable and nonmoveable. ![basic_ubjson_encoder](./diagrams/basic_ubjson_encoder.png) Four specializations for common character types and result types are defined: Type |Definition ---------------------------|------------------------------ ubjson_stream_encoder |basic_ubjson_encoder ubjson_bytes_encoder |basic_ubjson_encoder>> #### Member types Type |Definition ---------------------------|------------------------------ char_type |char sink_type |Sink string_view_type | #### Constructors explicit basic_ubjson_encoder(Sink&& sink) Constructs a new encoder that writes to the specified destination. #### Destructor virtual ~basic_ubjson_encoder() noexcept #### Member functions void reset(); Reset encoder to write another value to the same sink void reset(Sink&& sink) Reset encoder to write a new value to a new sink #### Inherited from [jsoncons::basic_json_visitor](basic_json_visitor.md) void flush(); (1) bool begin_object(semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (2) bool begin_object(std::size_t length, semantic_tag tag=semantic_tag::none, const ser_context& context = ser_context()); (3) bool end_object(const ser_context& context = ser_context()); (4) bool begin_array(semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (5) bool begin_array(std::size_t length, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (6) bool end_array(const ser_context& context=ser_context()); (7) bool key(const string_view_type& name, const ser_context& context=ser_context()); (8) bool null_value(semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (9) bool bool_value(bool value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (10) bool string_value(const string_view_type& value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (11) bool byte_string_value(const byte_string_view& source, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (12) (until 0.152.0) template bool byte_string_value(const ByteStringLike& souce, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (12) (since 0.152.0) template bool byte_string_value(const ByteStringLike& souce, uint64_t ext_tag, const ser_context& context=ser_context()); (13) (since 0.152.0) bool uint64_value(uint64_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (14) bool int64_value(int64_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (15) bool half_value(uint16_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (16) bool double_value(double value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()); (17) bool begin_object(semantic_tag tag, const ser_context& context, std::error_code& ec); (18) bool begin_object(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec); (19) bool end_object(const ser_context& context, std::error_code& ec); (20) bool begin_array(semantic_tag tag, const ser_context& context, std::error_code& ec); (21) bool begin_array(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec); (22) bool end_array(const ser_context& context, std::error_code& ec); (23) bool key(const string_view_type& name, const ser_context& context, std::error_code& ec); (24) bool null_value(semantic_tag tag, const ser_context& context, std::error_code& ec); (25) bool bool_value(bool value, semantic_tag tag, const ser_context& context, std::error_code& ec); (26) bool string_value(const string_view_type& value, semantic_tag tag, const ser_context& context, std::error_code& ec); (27) bool byte_string_value(const byte_string_view& source, semantic_tag tag, const ser_context& context, std::error_code& ec); (28) (until 0.152.0) template bool byte_string_value(const ByteStringLike& source, semantic_tag tag, const ser_context& context, std::error_code& ec); (28) (since 0.152.0) template bool byte_string_value(const ByteStringLike& source, uint64_t ext_tag, const ser_context& context, std::error_code& ec); (29) (since 0.152.0) bool uint64_value(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (30) bool int64_value(int64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (31) bool half_value(uint16_t value, semantic_tag tag, const ser_context& context, std::error_code& ec); (32) bool double_value(double value, semantic_tag tag, const ser_context& context, std::error_code& ec); (33) template bool typed_array(const span& data, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()); (34) bool typed_array(half_arg_t, const span& s, semantic_tag tag = semantic_tag::none, const ser_context& context = ser_context()); (35) bool begin_multi_dim(const span& shape, semantic_tag tag, const ser_context& context); (36) bool end_multi_dim(const ser_context& context=ser_context()); (37) template bool typed_array(const span& data, semantic_tag tag, const ser_context& context, std::error_code& ec); (38) bool typed_array(half_arg_t, const span& s, semantic_tag tag, const ser_context& context, std::error_code& ec); (39) bool begin_multi_dim(const span& shape, semantic_tag tag, const ser_context& context, std::error_code& ec); (40) bool end_multi_dim(const ser_context& context, std::error_code& ec); (41) (1) Flushes whatever is buffered to the destination. (2) Indicates the begining of an object of indefinite length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (3) Indicates the begining of an object of known length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (4) Indicates the end of an object. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (5) Indicates the beginning of an indefinite length array. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (6) Indicates the beginning of an array of known length. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (7) Indicates the end of an array. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (8) Writes the name part of an object name-value pair. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (9) Writes a null value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (10) Writes a boolean value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (11) Writes a text string value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (12) Writes a byte string value `source` with a generic tag. Type `ByteStringLike` must be a container that has member functions `data()` and `size()`, and member type `value_type` with size exactly 8 bits (since 0.152.0.) Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (13) Writes a byte string value `source` with a format specific tag, `ext_tag`. Type `ByteStringLike` must be a container that has member functions `data()` and `size()`, and member type `value_type` with size exactly 8 bits (since 0.152.0.) Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (14) Writes a non-negative integer value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (15) Writes a signed integer value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (16) Writes a half precision floating point value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (17) Writes a double precision floating point value. Returns `true` if the consumer wishes to receive more events, `false` otherwise. Throws a [ser_error](ser_error.md) on parse errors. (18)-(33) Same as (2)-(17), except sets `ec` and returns `false` on parse errors. ### Examples ### See also [byte_string_view](../byte_string_view.md) jsoncons-1.3.2/doc/ref/ubjson/decode_ubjson.md000066400000000000000000000055341477700171100213330ustar00rootroot00000000000000### jsoncons::ubjson::decode_ubjson Decodes a [Universal Binary JSON Specification (JSON)](http://ubjson.org/) data format into a C++ data structure. ```cpp #include template T decode_ubjson(const std::vector& source, const bson_decode_options& options = bson_decode_options()); (1) (until 0.152.0) template T decode_ubjson(const Source& source, const bson_decode_options& options = bson_decode_options()); (1) (since 0.152.0) template T decode_ubjson(std::istream>& is, const bson_decode_options& options = bson_decode_options()); (2) template T decode_ubjson(InputIt first, InputIt last, const bson_decode_options& options = bson_decode_options()); (3) template T decode_ubjson(const allocator_set& alloc_set, const Source& source, const ubjson_decode_options& options = ubjson_decode_options()); (4) (since 0.171.0) template T decode_ubjson(const allocator_set& alloc_set, std::istream& is, const ubjson_decode_options& options = ubjson_decode_options()); (5) (since 0.171.0) ``` (1) Reads UBJSON data from a contiguous byte sequence provided by `source` into a type T, using the specified (or defaulted) [options](ubjson_options.md). Type `Source` must be a container that has member functions `data()` and `size()`, and member type `value_type` with size exactly 8 bits (since 0.152.0.) Any of the values types `int8_t`, `uint8_t`, `char`, `unsigned char` and `std::byte` (since C++17) are allowed. Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). (2) Reads UBJSON data from a binary stream into a type T, using the specified (or defaulted) [options](ubjson_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). (3) Reads UBJSON data from the range [`first`,`last`) into a type T, using the specified (or defaulted) [options](ubjson_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). Functions (4)-(5) are identical to (1)-(2) except an [allocator_set](../allocator_set.md) is passed as an additional argument and provides allocators for result data and temporary allocations. #### Exceptions Throws a [ser_error](../ser_error.md) if parsing fails, and a [conv_error](conv_error.md) if type conversion fails. ### See also [encode_ubjson](encode_ubjson.md) encodes a json value to the [Universal Binary JSON Specification](http://ubjson.org/) data format. jsoncons-1.3.2/doc/ref/ubjson/diagrams/000077500000000000000000000000001477700171100177665ustar00rootroot00000000000000jsoncons-1.3.2/doc/ref/ubjson/diagrams/basic_ubjson_encoder.png000066400000000000000000000122471477700171100246420ustar00rootroot00000000000000PNG  IHDR_e#tEXtmxfile%3Cmxfile%20modified%3D%222020-03-31T16%3A44%3A30.543Z%22%20host%3D%22app.diagrams.net%22%20agent%3D%225.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F80.0.3987.149%20Safari%2F537.36%22%20etag%3D%22DC3ItBiPfwJzhwYe5KBw%22%20version%3D%2212.9.6%22%20type%3D%22device%22%3E%3Cdiagram%20id%3D%22iK-0d-7Yl-5MlnfMu26I%22%20name%3D%22Page-1%22%3EzVZNc9owEP01PqZjWySFYwIkbRkyTekM5JQR1sZWK0tUFmD66ythCVu2mSQzHJpLtG%2B1%2BnjvrUyAxnn5IPEmmwsCLIhDUgZoEsRxFKKh%2FmeQQ4UMRhZIJSV2Ug0s6F9wlRbdUgKFN1EJwRTd%2BGAiOIdEeRiWUuz9aa%2BC%2BbtucAodYJFg1kWXlKisQofXYY1%2FAZpmbucotJkcu8kWKDJMxL4BoWmAxlIIVY3ycgzMkOd4qeruz2RPB5PA1XsKpo8%2FSz57WmTx%2BM9MLef5c%2Fntyq6yw2xrL7zGBU1efhWCv%2BxoQZWQQXzD9A53azNKzcheSB0cS1JsOQGzUajT%2B4wqWGxwYrJ77QuNZSpnOopO1c2Du1OAVFA2IHuRBxA5KHnQU2x2aDm1poocx%2FtaoshJlDXkGVgMW1ekp5Vr4vTAcvcBHj%2Bf4XG7PjIJPNGd0cvkZbl9pYyNBdOimVoExz%2BNF0qK39DIoBs0QuQyavx%2Fcgw7cnRoBU5uzfugo4ThQovlMwklVStLuhk%2Fm%2FGnaxtNykZqcnAB14dfuQVM0KgyYV12jFzdWQ0KsZUJvO07hWUK6u0%2BB%2BK9dl1FG4r1CeYwCQwruvPfyD4V7Q7fBdU3Oxlm4PslRi0fVNe2Rc0nrbXOqOW7YWudipbOOkdLnS79Lpelu3kWzx5X%2BAekV8unGexm0NP0X3kGkirMtWj6m0dxKnHesZ5uK%2BWbzW9PLji0etlCmNGUG8dqo%2BjnBN2ZJqX6a3VrEzklxGzT%2B074L8kFGj9qCRCHPY2PenwUf7zxdVh%2FKysF618caPoP%3C%2Fdiagram%3E%3C%2Fmxfile%3EװTIDATx^]Ue/fH!(1 $pbh"A1AF@,1 @`!hgP IQi0uf>| ]Y{zj܄)&l"=V#yZe}Nqw,{obN KCS; 5LHߐi#Or8 ѽ HRKtYk* 7}\ o䍺gH Sw؂'Xۓ|/c׮]xWp뭷t|شi/_'[fv2dw;w[n(7+] V ~Iz]_|{=n曘={v>k֬>}'xx2eʄիXz5>9ͪk#Lmz+gc=vovK>,6n^^,.tqߏk׮Mb}m=әng4|[:[ʠ㫫gbݍyZ O=y ҼmXہ-i3ŋ3_1_Ƶɇ~c^x?|15axy[8?sٳ%czPK=_&񫯾/ꫯf_f~;֏-Yt]Kk #H *V/F9=0mڴ{ɭ; P<;sO!|ߩ]ۇ={6=^-[}B{%+Ѵgqʕ 3%'!hrۋz{@VԖbڴOi<8d'V yE%l*J x%kv;bc`^d ^O?—_Fݶ̦+M҇uf **_kst*Tsl<Ċ*H_v_ko3]>T]n޼>Tc(=u:{b==ϟǶm۰q֯_+Wb\ZucE1k,Xr_2?_vvOJZKqJ{Qy]~=MrOh)||R{l^hQϗqlE0Nz7mXE,Tk!|MscjC~t+/÷_ܨݱcGT@z/l_mOW繐d?lSbmxb|7-Ѧg;Nf=|olWC;8& .d\LwvM;uԬOd9r${p jq V*ofuZXަ(+novV9s"!&f—-[֨๥9{L<>ib/<>t.\}gq3|י_'OhT?N.G*a3ጔ C| cÆ ,-Z[n]h|rUsnݚmam~^vm3ت: OK.eP?s 6o޼3f4^E#msرcˈC_|E;wo;0=[ԯ;2Լ50 JQ+4~;[Bת§a| 1vN[fyBqXkzQBm|:_O{ A_x3fށU))046}~*O=裙V5kY18q텼Pd@"e/v䊮U ȷ@]P_6[igX -*߫:[!C<K__1ȕWV}+_G^*_ۡ~Q_"y ߷ZUC4!ekRzOw|}ݬwBv1z>*ROQrŨhRnU)[Wi8_ti t$߀n}7J0{CT)Pૻo }V@w 8!5 1A*J|+QF|u_H|u Awk0 x r&;8k7[+|;Kvۙ^:^ @|* ,a|#eKZwЊhż2`{.;XprW-/p2 +ݟ. ?8;d<~0KpST;ԂJ'qk$q_V\ ӿ>wd#|s9Dyw`paNm5wJҺO.>M؝Ɂ_ 2:q˃/ۍ7Ns?v}G*'E5HQV+s:t~g3{|/WiKOfo:q_,ԇgŝM3|Qbk>OƐ"|$-A'l-8`U>}6{NAYڣV@eNXQ[6!*'!!QF} 4=lYAצk*"R%۩|y k/1{ۉO>ߑOQeV_d_i.| YVKa[$?ݠX¬[|,>[;!7f޺ r D VEms45U-cU\f4)ڟ㸳r|Oۙo]Z|}B'vs5%S D? hړ~wSEQ̊|R`|> P HQT@Ŭ') ^_0K_oIENDB`jsoncons-1.3.2/doc/ref/ubjson/diagrams/ubjson_options.png000066400000000000000000000250301477700171100235470ustar00rootroot00000000000000PNG  IHDRYlutEXtmxfile%3Cmxfile%20host%3D%22app.diagrams.net%22%20modified%3D%222020-04-16T00%3A46%3A19.063Z%22%20agent%3D%225.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F80.0.3987.163%20Safari%2F537.36%22%20etag%3D%22DmrTjyxHPS4YZEI9ST57%22%20version%3D%2212.9.13%22%20type%3D%22device%22%3E%3Cdiagram%20id%3D%22yA7M8pUu49T19xTu_T4b%22%20name%3D%22Page-1%22%3EzZjLcpswFIafhmU7gAy2l7Gdulmk46ln2qSbjALHoFZIjJADztNXBGHu48u0tleWfklH4j%2BfhLCB5lG2FDgOH7kP1LBNPzPQwrBty0QT9ZMru0IZTbUQCOLrTpWwJu9QjtTqlviQNDpKzqkkcVP0OGPgyYaGheBps9uG0%2BasMQ6gI6w9TLvqT%2BLLsFAnjlnpX4EEYTmzZeqWCJedtZCE2OdpTUL3BpoLzmVRirI50Ny80pdi3JeB1v3CBDB5zIAxWoWPZOlEP34tHcCv8WzBP%2Bkob5hu9QNvX38nnL3wWBLOEr10uSv9EHzLfMhDmgaapSGRsI6xl7emigClhTKiqmapYneJ5XwgJGQ1SS95CTwCKXaqS1byou3T%2FFiurqdVNiyktbCWiZHWsAYg2IeuPFIFbdMJltlDlvngKfxvxjnbaTln9zjnXtI5NOQcsJt2zjav7dzowDZ98XgUcXZ9547YrBc1zukY1%2FEImH%2BXvyhUzaM4SYjXtAUyIp%2B0g3n5OS9%2FdnRtkdWaFruywtTin8oAeaU2Kq9Wwz5q5bjBFCR8Kzw4vLckFgHIwySB33jtdRNay5jTk7BSE0CxJG%2FNl2VfFvUMK07Uk%2B15sZq8IKvFQfHYelD93daK47Y2rNuKU9jSifOB1P6hz6fMvQ5l59Ni3xYFo9axgc7EwJq0Ak0uy8HkH3Bw5slxWX7Km%2Fih0%2Ba2OGvfJdG5nDktYO0Lcza9HmeDzBxkAd00C52j4lgW2oH%2BIwvf8fjZnn6bu6Flbabp%2BOHdWvV8wT2wEASRmKktrD68CQ4EjjqAqBudbCKRSMH%2FwJxTLpTCOFM9ZxtCaUvClAQs50ohAEqf5fdDoj6Z73RDRHw%2Fn6b3wtm8kg7idMKdczyQgPql0%2B4hyT790qmq1Qd7kcHqbw90%2Fxc%3D%3C%2Fdiagram%3E%3C%2Fmxfile%3E!jW IDATx^]U'!mP*Z)BPV0PThb> "_-~c(D~SCb_ " yQ&U(InYCav}3go{fu]񩑑E੧ '"yDdեȿYd$&`P:dס`W,xUƨfpd HM.t$CUY^29`ƍQ ,@d\AI_^ erT#&W!@5ÑY "  6!ȿW@dyFM7F5Ck#@E@ @lrC& 6z%!P\5nj Gf"@ JL":l\J/C6j D9 Du(ظ"+^&@5lrո1_3,r=~ج_,_̚5kn2;w42ǏӧO/1cxu\߿o֮]kO4)3ޜ.8+hA (ˆ剬8%~Z'KdM2%ܩ6̿`0x )!P@ܞ={ɓҥK+f̘a+(ȑ#ƍԩS>u=dӧg2ۭ:Vט8qbww6۶mfv盇J\bc.]Uߤ*$6?,Xhv?U3^{VZ5$E|?O8a=ګ(f-kHeQ3gΌ;&snh"XBK$#*MlrD֝;w01n:sAPgd)FZ$cN<+V K͚5kF PHCKtQիW[%vWᣏ>ܽ{׊2Ui&! R Nip*SŨk!DV Qćh|F?v2###'̙c7vޙ3g,w^+_U\nQX$M{"V\i8+icɞ2 HeI6Ǐ<.\0Ud%I-iNN뭫8Y7n4ƍKO>1w믿^w)C jËsD߶kܹ(ɷr7qرcmY~QJ,9t/9wc upڵQ EQGIU%Yzڝ[g֑iݼ/?b|+G?9w\ݥ / {ϊ+U;v0$4)t3YT(iHӅnFDzUTYy,H*Y z j%+k)ZrVd8WdUN6k{DdqAYdD@zD\]p+V,iJdi?RZ_,Jɞ,KU*+d=PäGZU#ƴGQWh['︰_OVߪ=Yi"K D1ҚYx=gJ_ " J~zM,(i=iOS{n%͛ZSzyOY2(?zӅ2:yɓtժիWK=]UrOƨNһe/lo6l` flda w%KҮ&DVC0*v4&!+*3W\U*"[EhrO }|o@ZUYrlٲ^5ǭ,%ϖUjw"?6/y|Cت] DVW"!w  @߻w7i~_ތ車6]p -|UrA%(~MwENAy[M%EcySoF]E8|׼`Y^2yuߌ*B{ 4V5DVqj/w5axEiU}-((S"6B&K}Wu3"Д*FD$Ȋ3CUڛѤIƍͯQw5TX -b 5opDV8 oa?#G_NIU*Yu1G 73C{nscbŊ!$PVl!3M[Edݺuܹ:tȌ?~͗/_6'O40cƌiڟs}w^?-7iӦ_ܹsw}v+~Su@ E EǏͬYFa۟C6ܿ߬]>OH6Һ 7,8,<7-[c~/DD Ud K\5eʔa1 ;+Rv*>_ya3}tsY#JٳQ ,0O/رcw.]j\s=gˋ@vN0,]Ԝ?ڵk.WUV٪\'Nh+/r1׶m{Iy%K̍7#տg̘a{d̩S|́أ|ǎkw8d*Ixʕ1{׾5ӟԲ۹ D Kl!'C{MRe_s ~*{#W}./.eEY.'N0GUܽr9s 푦7|7%'?/Z1"J "D|=rIEHk֬"M.wOܗwo4;޽;"t {VҤv="ʕ+YWRŋ'O63g,$h4a̙޵3>qY"?7}* *"y֭VrA@Rl߿ߌx5Ⱥs[eZnsKy׿ZQ&9o޽{eLEQ־f;Ҏ Nj9 Mۧd?Œ?^7WRox ЗmSH.K~, 8 I&տ@[|i8QŮȺy樞2AWSs>,ߒ?Z?yܩ"\ՈIާgu㐗"~o?o|[߲A@ t?Ƀ|-Hu&ܵ3EڹpT%-{٫O=^Rd\~o,BjQ8ѣGVӆAPDdE+"DkUNg*fg$|e˖X%٬?JyDڙu$xQnEOdQɪ2f, 0h!V}me֜LQUt""KQ!WP%z"w4&\5)FL{0yUAq[ͽL%+郮U%*uYZ'Ud%l,z|ԙA ,LriV޿IXI璜V\;V\},צȏ"KqꭷJJկ~e~ɋdUdikg՞vZ[HO+U_</=+/+*Yz!+AT?Trt'84F YC?%s|CҹxP>ٿϧ~ta)}} O>i"|Sj?W^-taV%mqF\(2r%iFU/3*C߽|? 4Cj[d.}/CS,UܮZnU ͭ&jSe7EB(%k](+BYZ)U_0 U3DV r*dfԬo=rGzۤ @EVӌ?V+Y.(ۻ_X%UJ_.f >C /683"keE/T,B… bŊ " :SVVY ޳-׊:UphZ\!POa|]׊#m%YmDox@d O)%׊6Mp -Y)IYфrxiRd)7>%Y>7s"7vXCd)I@%m+DV0E;mh1"K)Я5<h"3"+X'm,CЦC0A+DVPuFDV'm,@VuB qȪx xֶR0k M`(2 &Y$KE> D:NS P@ U:Q艬Ĺ A2ŕ+;S#!%"R֠+| ;-E\LH@dH_+M$Pqխ[DVQŧF _+ML2tK "5 C`PZHnT!w1zȊ185 @4Y q @[ZmorD.qEN{ Zmmr^0O(HUA IgMhB C\w]#Zq>|mr;τQh:WQ N *[ P@ZMorE(qENu"h_Mq瘰i @%P_&W^Kj!#&"# @~GWCo޽7?ϟ Prj)RZ;v0jDj d}楗^2/z ,@d[< @~-DVI7oy/l\bWJ\EU !P@~-"fff֬Yuٹs9t?~|yhӧŋ̘́1cZfڵI2Њ19esC+Νko6l`L8q>% 64;~Aؙ ZdM2%XܚYxa.3u=dӧg2mt! ݻ|={mժU$ؙ5Tϛ MR}n2#̟?Vgܵ;f׽tU4N]hG֐O8a=ګ(f-kHeQ3gΌ;&~~/'GӦM3<ڪߟ'@' :fگ%/2Ⱥs&"֭[g{b:h:w\ݥ / _˷Ț3gRA6sTrtś*t^(h,yl'"GDܛoinjS1KNĤ̫=X+=5w6Ǐ<.\0Udr{v|ZSAz潈7qƥN'}{g?Yݥ / +6 9)x*y7vX[]rD֦_Fd-[lTOŊ':Xsw̵kF5'E;fPRKV]%RI_]qEf& @ Y1D#&Vt3YT(iFdȭڈ^JV(WɒdV +YRJRf,oJVʫyQ4ug,b!Ȋ%&69)GiR'K֥y]G"=vqa|r&U6frħU%=KzQoLfrJ~ąd}iRi|d,?ӏnnȿ601@dE|@{yf$ i:͛'O=]XVdIܧt-=̚/i"Oʚ۷ͮ]l}BMOE*_j]zӅY4nM|Y݋ P"4@7Amr]0R_1,8k&T5a;s@ $- 699rUr+K1Xm}zQ循v#P^Mw|nH Bd )*@);IɰtBPq#j5+A06¨T$DV'Îӡ` =BqG_k"=֬ F?PY ;NNM.mw|=X `+= <@eN@du28:6#}_Ż cJ(LM0*n@);IɰtBPq#j5+A06¨T$DV'Îӡ` =BqG_k"=֬ F?PY ;NN@69. gmDAEq  B@ DVa @B# -"@@YQ' @"+` @Q@dEF @ 4"= DAEq  B@ DVa @B# -"@@YQ' @"+` @Q@dEF @ 4"= DAEq  B@ DVa @B# -"@@YQ' @"+` @Q@dEF @ 4"= DAEq  B@ DVa @B# -"@@YQ' @"+` @Q@dEF @ 4"= DAEq  B@ DVa @B# -"@@YQ' @"+` @Q@dEF @ 4"= DAEq  B@ DVa @B# -"@@YQ! RIDAT' @"+`Z&p}vZsN3eʔoݺe9t?~|%+?~l֯_o/_nNZhJ UtisEo[Z;g͚Uq6A]'z )\Em3@*8`ƌҬDHaPq ebgҤI4qD}v;ݻͶmیV^ya3}ts^fv̪Ud{?fczL0,]Ԝ?>u{/ץKz&kɒ%ƍuE ٓ&>gÇOTܹ0[lCƏ7lڴibTs>|ٳDzPebʽ@Ya+ 00i"Ktuf+1yf+D|Gwu֙W&B-P̙3-I[ѣGŦɓ'3g#6 453f̰H.Pğ"ǩn[E/f]Կ/=K*@dU C Mdp'TwN'K'!weΜ90=5ϧ~r #<YҘA"+Ȱ` 0lJ>l`/ P">Cf:J gZu4pY @@*SB D9@<@dyʔ @iL.i6IENDB`jsoncons-1.3.2/doc/ref/ubjson/encode_ubjson.md000066400000000000000000000040151477700171100213360ustar00rootroot00000000000000### jsoncons::ubjson::encode_ubjson Encodes a C++ data structure to the [Universal Binary JSON Specification (UBJSON)](http://ubjsonspec.org/) data format. ```cpp #include template void encode_ubjson(const T& jval, ByteContainer& cont, const ubjson_decode_options& options = ubjson_decode_options()); (1) template void encode_ubjson(const T& jval, std::ostream& os, const bson_decode_options& options = bson_decode_options()); (2) template void encode_ubjson(const allocator_set& alloc_set, const T& jval, ByteContainer& cont, const ubjson_decode_options& options = ubjson_decode_options()); (3) (since 0.171.0) template void encode_ubjson(const allocator_set& alloc_set, const T& jval, std::ostream& os, const bson_decode_options& options = bson_decode_options()); (4) (since 0.171.0) ``` (1) Writes a value of type T into a byte container in the UBJSON data format, using the specified (or defaulted) [options](ubjson_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). Type `ByteContainer` must be back insertable and have member type `value_type` with size exactly 8 bits (since 0.152.0.) Any of the values types `int8_t`, `uint8_t`, `char`, `unsigned char` and `std::byte` (since C++17) are allowed. (2) Writes a value of type T into a binary stream in the UBJSON data format, using the specified (or defaulted) [options](ubjson_options.md). Type 'T' must be an instantiation of [basic_json](../basic_json.md) or support [json_type_traits](../json_type_traits.md). Functions (3)-(4) are identical to (1)-(2) except an [allocator_set](../allocator_set.md) is passed as an additional argument. ### See also [decode_ubjson](decode_ubjson) decodes a [Binary JSON](http://ubjsonspec.org/) data format to a json value. jsoncons-1.3.2/doc/ref/ubjson/ubjson.md000066400000000000000000000273021477700171100200250ustar00rootroot00000000000000## ubjson extension The ubjson extension implements encode to and decode from the [Universal Binary JSON Specification](http://ubjson.org/) data format. You can either parse into or serialize from a variant-like data structure, [basic_json](../basic_json.md), or your own data structures, using [json_type_traits](../json_type_traits.md). [decode_ubjson](decode_ubjson.md) [basic_ubjson_cursor](basic_ubjson_cursor.md) [encode_ubjson](encode_ubjson.md) [basic_ubjson_encoder](basic_ubjson_encoder.md) [ubjson_options](ubjson_options.md) #### Mappings between UBJSON and jsoncons data items UBJSON data item | jsoncons data item|jsoncons tag ---------------------------|---------------|------------------ null | null | true or false | bool | uint8_t or integer | int64 | uint8_t or integer | uint64 | float 32 or float 64 | double | string | string | high precision number type| string | bigint high precision number type| string | bigdec array of uint8_t | byte_string | array | array | object | object | ## Examples ### Working with UBJSON data For the examples below you need to include some header files and initialize a buffer of UBJSON data: ```cpp #include #include #include #include #include using namespace jsoncons; // for convenience const std::vector data = {0x5b,0x23,0x55,0x05, // [ # i 5 0x44, // float64 0x40,0x3d,0xf8,0x51,0xeb,0x85,0x1e,0xb8, // 29.97 0x44, // float64 0x40,0x3f,0x21,0x47,0xae,0x14,0x7a,0xe1, // 31.13 0x64, // float32 0x42,0x86,0x00,0x00, // 67.0 0x44, // float64 0x40,0x00,0xe7,0x6c,0x8b,0x43,0x95,0x81, // 2.113 0x44, // float64 0x40,0x37,0xe3,0x8e,0xf3,0x4d,0x6a,0x16 // 23.8889 }; ``` jsoncons allows you to work with the UBJSON data similarly to JSON data: - As a variant-like data structure, [basic_json](doc/ref/corelib/basic_json.md) - As a strongly typed C++ data structure that implements [json_type_traits](../json_type_traits.md) - With [cursor-level access](doc/ref/ubjson/basic_ubjson_cursor.md) to a stream of parse events #### As a variant-like data structure ```cpp int main() { std::cout << std::dec; std::cout << std::setprecision(15); // Parse the UBJSON data into a json value json j = ubjson::decode_ubjson(data); // Pretty print std::cout << "(1)\n" << pretty_print(j) << "\n\n"; // Iterate over rows std::cout << "(2)\n"; for (const auto& item : j.array_range()) { std::cout << item.as() << " (" << item.tag() << ")\n"; } std::cout << "\n"; // Select all values less than 30 with JSONPath std::cout << "(3)\n"; json result = jsonpath::json_query(j,"$[?(@ < 30)]"); std::cout << pretty_print(result) << "\n"; } ``` Output: ``` (1) [ 29.97, 31.13, 67.0, 2.113, 23.8889 ] (2) 29.97 (n/a) 31.13 (n/a) 67 (n/a) 2.113 (n/a) 23.8889 (n/a) (3) [ 29.97, 2.113, 23.8889 ] ``` #### As a strongly typed C++ data structure ```cpp int main() { // Parse the UBJSON data into a std::vector value auto val = ubjson::decode_ubjson>(data); for (auto item : val) { std::cout << item << "\n"; } } ``` Output: ``` 29.97 31.13 67 2.113 23.8889 ``` #### With cursor-level access ```cpp int main() { ubjson::ubjson_bytes_cursor cursor(data); for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::end_array: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::begin_object: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::end_object: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::key: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::string_value: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::null_value: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::bool_value: std::cout << event.event_type() << ": " << std::boolalpha << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::int64_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::double_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; default: std::cout << "Unhandled event type " << event.event_type() << " " << "(" << event.tag() << ")\n"; break; } } } ``` Output: ``` begin_array (n/a) double_value: 29.97 (n/a) double_value: 31.13 (n/a) double_value: 67 (n/a) double_value: 2.113 (n/a) double_value: 23.8889 (n/a) end_array (n/a) ``` You can apply a filter to a cursor using the pipe syntax, for example, ```cpp int main() { auto filter = [&](const staj_event& ev, const ser_context&) -> bool { return (ev.event_type() == staj_event_type::double_value) && (ev.get() < 30.0); }; ubjson::ubjson_bytes_cursor cursor(data); auto filtered_c = cursor | filter; for (; !filtered_c.done(); filtered_c.next()) { const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::double_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; default: std::cout << "Unhandled event type " << event.event_type() << " " << "(" << event.tag() << ")\n"; break; } } } ``` Output: ``` double_value: 29.97 (n/a) double_value: 2.113 (n/a) double_value: 23.8889 (n/a) ``` ### encode/decode UBJSON from/to basic_json ```cpp #include #include #include using namespace jsoncons; int main() { ojson j1 = ojson::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 } ] } )"); // Encode a basic_json value to UBJSON std::vector data; ubjson::encode_ubjson(j1, data); // Decode UBJSON to a basic_json value ojson j2 = ubjson::decode_ubjson(data); std::cout << "(1)\n" << pretty_print(j2) << "\n\n"; // Accessing the data items const ojson& reputons = j2["reputons"]; std::cout << "(2)\n"; for (auto element : reputons.array_range()) { std::cout << element.at("rated").as() << ", "; std::cout << element.at("rating").as() << "\n"; } std::cout << '\n'; // Get a UBJSON value for a nested data item with jsonpointer std::error_code ec; const auto& rated = jsonpointer::get(j2, "/reputons/0/rated", ec); if (!ec) { std::cout << "(3) " << rated.as_string() << "\n"; } std::cout << '\n'; } ``` Output: ``` (1) { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.9 } ] } (2) Marilyn C, 0.9 (3) Marilyn C ``` ### encode/decode UBJSON from/to your own data structures ```cpp #include #include #include #include namespace ns { enum class hiking_experience {beginner,intermediate,advanced}; class hiking_reputon { std::string rater_; hiking_experience assertion_; std::string rated_; double rating_; public: hiking_reputon(const std::string& rater, hiking_experience assertion, const std::string& rated, double rating) : rater_(rater), assertion_(assertion), rated_(rated), rating_(rating) { } const std::string& rater() const {return rater_;} hiking_experience assertion() const {return assertion_;} const std::string& rated() const {return rated_;} double rating() const {return rating_;} friend bool operator==(const hiking_reputon& lhs, const hiking_reputon& rhs) { return lhs.rater_ == rhs.rater_ && lhs.assertion_ == rhs.assertion_ && lhs.rated_ == rhs.rated_ && lhs.rating_ == rhs.rating_; } friend bool operator!=(const hiking_reputon& lhs, const hiking_reputon& rhs) { return !(lhs == rhs); }; }; class hiking_reputation { std::string application_; std::vector reputons_; public: hiking_reputation(const std::string& application, const std::vector& reputons) : application_(application), reputons_(reputons) {} const std::string& application() const { return application_;} const std::vector& reputons() const { return reputons_;} friend bool operator==(const hiking_reputation& lhs, const hiking_reputation& rhs) { return (lhs.application_ == rhs.application_) && (lhs.reputons_ == rhs.reputons_); } friend bool operator!=(const hiking_reputation& lhs, const hiking_reputation& rhs) { return !(lhs == rhs); }; }; } // namespace ns // Declare the traits. Specify which data members need to be serialized. JSONCONS_ENUM_TRAITS(ns::hiking_experience, beginner, intermediate, advanced) JSONCONS_ALL_CTOR_GETTER_TRAITS(ns::hiking_reputon, rater, assertion, rated, rating) JSONCONS_ALL_CTOR_GETTER_TRAITS(ns::hiking_reputation, application, reputons) int main() { ns::hiking_reputation val("hiking", { ns::hiking_reputon{"HikingAsylum",ns::hiking_experience::advanced,"Marilyn C",0.90} }); // Encode a ns::hiking_reputation value to UBJSON std::vector data; ubjson::encode_ubjson(val, data); // Decode UBJSON to a ns::hiking_reputation value ns::hiking_reputation val2 = ubjson::decode_ubjson(data); assert(val2 == val); } ``` jsoncons-1.3.2/doc/ref/ubjson/ubjson_options.md000066400000000000000000000014061477700171100215750ustar00rootroot00000000000000### jsoncons::ubjson::ubjson_options ```cpp #include class ubjson_options; ```
![ubjson_options](./diagrams/ubjson_options.png) Specifies options for reading and writing CBOR. #### Constructors ubjson_options() Constructs a `ubjson_options` with default values. #### Modifiers void max_items(std::size_t value) While parsing, the maximum number of items allowed in a UBJSON object or array. Default is 16,777,216. void max_nesting_depth(int value) The maximum nesting depth allowed when decoding and encoding UBJSON. Default is 1024. Parsing can have an arbitrarily large depth limited only by available memory. Serializing a [basic_json](../basic_json.md) to UBJSON is limited by stack size. jsoncons-1.3.2/examples/000077500000000000000000000000001477700171100151745ustar00rootroot00000000000000jsoncons-1.3.2/examples/build/000077500000000000000000000000001477700171100162735ustar00rootroot00000000000000jsoncons-1.3.2/examples/build/cmake/000077500000000000000000000000001477700171100173535ustar00rootroot00000000000000jsoncons-1.3.2/examples/build/cmake/CMakeLists.txt000077500000000000000000000017051477700171100221210ustar00rootroot00000000000000 # # jsoncons examples CMake file # cmake_minimum_required (VERSION 2.8) # load global config include (../../build/cmake/Config.cmake) project (Examples CXX) # load per-platform configuration include (../../build/cmake/${CMAKE_SYSTEM_NAME}.cmake) include_directories (../../include ../../../include) file(GLOB_RECURSE Example_sources ../../src/*.cpp) # Loop through each example file and create an executable for each foreach(example_file ${Example_sources}) # Extract the filename without path and extension get_filename_component(example_name ${example_file} NAME_WE) # Create an executable with the example name and file add_executable(${example_name} ${example_file}) if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") # special link option on Linux because llvm stl rely on GNU stl target_link_libraries(${example_name} -Wl,-lstdc++) endif() endforeach() jsoncons-1.3.2/examples/build/cmake/README.txt000066400000000000000000000007451477700171100210570ustar00rootroot00000000000000To build the jsoncons examples with cmake: Windows To build the tests with vc140, build_vc140x64.cmd and to run them run_examples_vc140x64.cmd UNIX From the examples/build/cmake directory include Config.cmake and Linux.cmake as CMakeLists.txt expects it. mkdir -p debug cd debug cmake -DCMAKE_BUILD_TYPE=debug -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DARCHIVE_INSTALL_DIR=. -G "Unix Makefiles" .. make From the examples directory ./build/cmake/debug/jsoncons_examples jsoncons-1.3.2/examples/build/cmake/build_vc140x64.cmd000066400000000000000000000002741477700171100224210ustar00rootroot00000000000000call rmdir build_vc140x64 /S/Q call mkdir build_vc140x64 & pushd build_vc140x64 call cmake -G "Visual Studio 14 2015 Win64" .. call popd call cmake --build build_vc140x64 --config Debug jsoncons-1.3.2/examples/build/cmake/run_examples_vc140x64.cmd000066400000000000000000000001611477700171100240170ustar00rootroot00000000000000@echo off set DIR=%~dp0 cd %DIR%..\.. call "build/cmake/build_vc140x64/Debug/jsoncons_examples.exe" cd %DIR% jsoncons-1.3.2/examples/input/000077500000000000000000000000001477700171100163335ustar00rootroot00000000000000jsoncons-1.3.2/examples/input/address-book.json000066400000000000000000000004301477700171100216000ustar00rootroot00000000000000 { "address-book" : [ { "name":"Jane Roe", "email":"jane.roe@example.com" }, { "name":"John", "email" : "john.doe@example.com" } ] } jsoncons-1.3.2/examples/input/books.json000066400000000000000000000012411477700171100203410ustar00rootroot00000000000000{ "books": [ { "category": "fiction", "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "category": "fiction", "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "category": "fiction", "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "category": "memoir", "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } jsoncons-1.3.2/examples/input/countries.json000066400000000000000000000002471477700171100212440ustar00rootroot00000000000000[ ["country_code","name"], ["ABW","ARUBA"], ["ATF","FRENCH SOUTHERN TERRITORIES, D.R. OF"], ["VUT","VANUATU"], ["WLF","WALLIS & FUTUNA ISLANDS"] ] jsoncons-1.3.2/examples/input/employees.json000066400000000000000000000013041477700171100212260ustar00rootroot00000000000000[ { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" } ] jsoncons-1.3.2/examples/input/jsonschema/000077500000000000000000000000001477700171100204655ustar00rootroot00000000000000jsoncons-1.3.2/examples/input/jsonschema/name-defs.json000066400000000000000000000005521477700171100232210ustar00rootroot00000000000000{ "$id" : "https://www.example.com/other", "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "orNull": { "anyOf": [ { "type": "null" }, { "$ref": "#" } ] } }, "type": "string" } jsoncons-1.3.2/examples/input/multiple-json-objects.json000066400000000000000000000000741477700171100234600ustar00rootroot00000000000000{"a":1,"b":2,"c":3} {"a":4,"b":5,"c":6} {"a":7,"b":8,"c":9} jsoncons-1.3.2/examples/input/sales.csv000066400000000000000000000004141477700171100201560ustar00rootroot00000000000000customer_name,has_coupon,phone_number,zip_code,sales_tax_rate,total_amount "John Roe",true,0272561313,01001,0.05,431.65 "Jane Doe",false,416-272-2561,55416,0.15,480.70 "Joe Bloggs",false,"4162722561","55416",0.15,300.70 "John Smith",FALSE,NULL,22313-1450,0.15,300.70 jsoncons-1.3.2/examples/input/store.json000066400000000000000000000012121477700171100203560ustar00rootroot00000000000000{ "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ] } } jsoncons-1.3.2/examples/input/tasks.csv000066400000000000000000000003121477700171100201710ustar00rootroot00000000000000project_id, task_name, task_start, task_finish 4001,task1,01/01/2003,01/31/2003 4001,task2,02/01/2003,02/28/2003 4001,task3,03/01/2003,03/31/2003 4002,task1,04/01/2003,04/30/2003 4002,task2,05/01/2003, jsoncons-1.3.2/examples/output/000077500000000000000000000000001477700171100165345ustar00rootroot00000000000000jsoncons-1.3.2/examples/output/booklist.json000066400000000000000000000015661477700171100212650ustar00rootroot00000000000000[ { "author": "Haruki Murakami", "category": "Fiction", "date": "2006-01-03", "isbn": "1400079276", "price": 13.45, "title": "Kafka on the Shore" }, { "author": "Charles Bukowski", "category": "Fiction", "date": "2004-07-08", "isbn": "1852272007", "price": 22.48, "ratings": { "*****": 4 }, "title": "Pulp" }, { "author": "Haruki Murakami", "category": "Fiction", "date": "2002-04-09", "isbn": "037571894X", "price": 9.01, "title": "A Wild Sheep Chase: A Novel" }, { "author": "George Crile", "category": "History", "date": "2007-11-06", "isbn": "0802143415", "price": 10.5, "title": "Charlie Wilson's War" } ]jsoncons-1.3.2/examples/output/booklist2.json000066400000000000000000000015661477700171100213470ustar00rootroot00000000000000[ { "author": "Haruki Murakami", "category": "Fiction", "date": "2006-01-03", "isbn": "1400079276", "price": 13.45, "title": "Kafka on the Shore" }, { "author": "Charles Bukowski", "category": "Fiction", "date": "2004-07-08", "isbn": "1852272007", "price": 22.48, "ratings": { "*****": 4 }, "title": "Pulp" }, { "author": "Haruki Murakami", "category": "Fiction", "date": "2002-04-09", "isbn": "037571894X", "price": 9.01, "title": "A Wild Sheep Chase: A Novel" }, { "author": "George Crile", "category": "History", "date": "2007-11-06", "isbn": "0802143415", "price": 10.5, "title": "Charlie Wilson's War" } ]jsoncons-1.3.2/examples/output/export_settings.json000066400000000000000000000005201477700171100226650ustar00rootroot00000000000000{"File Format Options":{"Color Spaces":["sRGB","AdobeRGB","ProPhoto RGB"],"Image Formats":["JPEG","PSD","TIFF","DNG"]},"File Settings":{"Color Space":"sRGB","Image Format":"JPEG","Limit File Size":true,"Limit File Size To":10000},"Image Sizing":{"Dimension 1":9.84,"Resize To Fit":true,"Resize Unit":"pixels","Resize What":"long_edge"}}jsoncons-1.3.2/examples/output/new-address-book1.json000066400000000000000000000004101477700171100226470ustar00rootroot00000000000000{ "address-book": [ { "first-name": "Jane", "last-name": "Roe", "email": "jane.roe@example.com" }, { "first-name": "John", "email": "john.doe@example.com" } ] }jsoncons-1.3.2/examples/output/new-address-book2.json000066400000000000000000000004101477700171100226500ustar00rootroot00000000000000{ "address-book": [ { "email": "jane.roe@example.com", "first-name": "Jane", "last-name": "Roe" }, { "email": "john.doe@example.com", "first-name": "John" } ] }jsoncons-1.3.2/examples/output/tasks.csv000066400000000000000000000002521477700171100203750ustar00rootroot00000000000000(1) project_id,task_name,task_start,task_finish 4001,task2,02/01/2003,02/28/2003 4001,task3,03/01/2003,03/31/2003 4002,task1,04/01/2003,04/30/2003 4002,task2,05/01/2003, jsoncons-1.3.2/examples/output/tasks.json000066400000000000000000000012561477700171100205600ustar00rootroot00000000000000(1) [ { "project_id": 4001, "task_name": "task1", "task_start": "01/01/2003", "task_finish": "01/31/2003" }, { "project_id": 4001, "task_name": "task2", "task_start": "02/01/2003", "task_finish": "02/28/2003" }, { "project_id": 4001, "task_name": "task3", "task_start": "03/01/2003", "task_finish": "03/31/2003" }, { "project_id": 4002, "task_name": "task1", "task_start": "04/01/2003", "task_finish": "04/30/2003" }, { "project_id": 4002, "task_name": "task2", "task_start": "05/01/2003" } ] jsoncons-1.3.2/examples/output/xxx.txt000066400000000000000000000000351477700171100201220ustar00rootroot00000000000000[ "\u007F\u07FF\u0800" ] jsoncons-1.3.2/examples/src/000077500000000000000000000000001477700171100157635ustar00rootroot00000000000000jsoncons-1.3.2/examples/src/array_examples.cpp000066400000000000000000000134251477700171100215100ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include using namespace jsoncons; void array_example1() { { std::vector v = {1,2,3,4}; json a(v); std::cout << a << '\n'; } { json j(json_array_arg, {1,true,"last"}); auto d = j.as>(); for (auto x : d) { std::cout << x << '\n'; } } { std::map m = {{"one",1},{"two",2},{"three",3}}; json j(m); std::cout << j << '\n'; } { json j; j["one"] = 1; j["two"] = 2; j["three"] = 3; auto um = j.as>(); for (const auto& x : um) { std::cout << x.first << "=" << x.second << '\n'; } } } void accessing_a_json_value_as_a_vector() { std::string s = "{\"my-array\" : [1,2,3,4]}"; json val = json::parse(s); std::vector v = val["my-array"].as>(); for (std::size_t i = 0; i < v.size(); ++i) { if (i > 0) { std::cout << ","; } std::cout << v[i]; } std::cout << '\n'; } void construct_json_from_vector() { json root; std::vector addresses; json address1; address1["city"] = "San Francisco"; address1["state"] = "CA"; address1["zip"] = "94107"; address1["country"] = "USA"; addresses.push_back(address1); json address2; address2["city"] = "Sunnyvale"; address2["state"] = "CA"; address2["zip"] = "94085"; address2["country"] = "USA"; addresses.push_back(address2); root["addresses"] = addresses; std::cout << pretty_print(root) << '\n'; std::cout << "size=" << root["addresses"].size() << '\n'; for (std::size_t i = 0; i < root["addresses"].size(); ++i) { std::cout << root["addresses"][i] << '\n'; } } void add_element_to_array() { json cities(json_array_arg); // an empty array std::cout << cities << '\n'; // output is "[]" cities.push_back("Toronto"); cities.push_back("Vancouver"); cities.insert(cities.array_range().begin(),"Montreal"); // inserts "Montreal" at beginning of array std::cout << cities << '\n'; } void reverse_array_iterator() { json j(json_array_arg); j.push_back("Montreal"); j.push_back("Toronto"); j.push_back("Vancouver"); for (auto it = j.array_range().rbegin(); it != j.array_range().rend(); ++it) { std::cout << it->as() << '\n'; } } void reserve_array_capacity() { json cities(json_array_arg); cities.reserve(10); // storage is allocated std::cout << "capacity=" << cities.capacity() << ", size=" << cities.size() << '\n'; cities.push_back("Toronto"); cities.push_back("Vancouver"); cities.insert(cities.array_range().begin(),"Montreal"); std::cout << "capacity=" << cities.capacity() << ", size=" << cities.size() << '\n'; std::cout << cities << '\n'; } void make_empty_array() { std::cout << "empty array" <<'\n'; json a(json_array_arg); std::cout << pretty_print(a) << '\n'; } void array_range_based_for_loop() { json book1; book1["category"] = "Fiction"; book1["title"] = "A Wild Sheep Chase: A Novel"; book1["author"] = "Haruki Murakami"; json book2; book2["category"] = "History"; book2["title"] = "Charlie Wilson's War"; book2["author"] = "George Crile"; json book3; book3["category"] = "Fiction"; book3["title"] = "Kafka on the Shore"; book3["author"] = "Haruki Murakami"; // Constructing a json array with an initializer-list json booklist(json_array_arg, {book1, book2, book3}); for (const auto& book: booklist.array_range()) { std::cout << book["title"].as() << '\n'; } } void make_1_dimensional_array_1() { std::cout << "1 dimensional array 1" <<'\n'; json a = json::make_array(10); a[1] = 1; a[2] = 2; std::cout << pretty_print(a) << '\n'; } void make_1_dimensional_array_2() { std::cout << "1 dimensional array 2" <<'\n'; json a = json::make_array(10,0); a[1] = 1; a[2] = 2; a[3] = json(json_array_arg); std::cout << pretty_print(a) << '\n'; } void make_2_dimensional_array() { std::cout << "2 dimensional array" <<'\n'; json a = json::make_array<2>(3,4,0); a[0][0] = "Tenor"; a[0][1] = "ATM vol"; a[0][2] = "25-d-MS"; a[0][3] = "25-d-RR"; a[1][0] = "1Y"; a[1][1] = 0.20; a[1][2] = 0.009; a[1][3] = -0.006; a[2][0] = "2Y"; a[2][1] = 0.18; a[2][2] = 0.009; a[2][3] = -0.005; std::cout << pretty_print(a) << '\n'; } void make_3_dimensional_array() { std::cout << "3 dimensional array" <<'\n'; json a = json::make_array<3>(4,3,2,0); double val = 1.0; for (std::size_t i = 0; i < a.size(); ++i) { for (std::size_t j = 0; j < a[i].size(); ++j) { for (std::size_t k = 0; k < a[i][j].size(); ++k) { a[i][j][k] = val; val += 1.0; } } } std::cout << pretty_print(a) << '\n'; } int main() { std::cout << "\nArray examples\n\n"; try { array_example1(); construct_json_from_vector(); add_element_to_array(); reserve_array_capacity(); accessing_a_json_value_as_a_vector(); make_empty_array(); array_range_based_for_loop(); make_1_dimensional_array_1(); make_1_dimensional_array_2(); make_2_dimensional_array(); make_3_dimensional_array(); reverse_array_iterator(); } catch (const std::exception& e) { std::cout << e.what() << '\n'; } } jsoncons-1.3.2/examples/src/basics_examples.cpp000066400000000000000000000116311477700171100216330ustar00rootroot00000000000000// jsoncons_test.cpp : Defines the entry point for the console application. // #include #include #include using namespace jsoncons; using namespace jsoncons::jsonpath; void basics_json_example1() { // Construct a book object json book1; book1["category"] = "Fiction"; book1["title"] = "A Wild Sheep Chase: A Novel"; book1["author"] = "Haruki Murakami"; book1["date"] = "2002-04-09"; book1["price"] = 9.01; book1["isbn"] = "037571894X"; // Construct another using the member function insert_or_assign json book2; book2.insert_or_assign("category", "History"); book2.insert_or_assign("title", "Charlie Wilson's War"); book2.insert_or_assign("author", "George Crile"); book2.insert_or_assign("date", "2007-11-06"); book2.insert_or_assign("price", 10.50); book2.insert_or_assign("isbn", "0802143415"); // Use insert_or_assign again, but more efficiently json book3; // Reserve memory, to avoid reallocations book3.reserve(6); // Insert in name alphabetical order // Give insert_or_assign a hint where to insert the next member auto hint = book3.insert_or_assign(book3.object_range().begin(),"author", "Haruki Murakami"); hint = book3.insert_or_assign(hint, "category", "Fiction"); hint = book3.insert_or_assign(hint, "date", "2006-01-03"); hint = book3.insert_or_assign(hint, "isbn", "1400079276"); hint = book3.insert_or_assign(hint, "price", 13.45); hint = book3.insert_or_assign(hint, "title", "Kafka on the Shore"); // Construct a fourth from a string json book4 = json::parse(R"( { "category" : "Fiction", "title" : "Pulp", "author" : "Charles Bukowski", "date" : "2004-07-08", "price" : 22.48, "isbn" : "1852272007" } )"); // Construct a booklist array json booklist(json_array_arg); // For efficiency, reserve memory, to avoid reallocations booklist.reserve(4); // For efficency, tell jsoncons to move the contents // of the four book objects into the array booklist.push_back(std::move(book1)); booklist.push_back(std::move(book2)); // Add the third one to the front auto where = booklist.insert(booklist.array_range().begin(),std::move(book3)); // Add the last one immediately after booklist.insert(where+1,std::move(book4)); // See what's left of book1, 2, 3 and 4 (expect nulls) std::cout << book1 << "," << book2 << "," << book3 << "," << book4 << '\n'; //Loop through the booklist elements using a range-based for loop for (auto book : booklist.array_range()) { std::cout << book["title"].as() << "," << book["price"].as() << '\n'; } // The second book json& book = booklist[1]; //Loop through the book members using a range-based for loop for (auto member : book.object_range()) { std::cout << member.key() << "," << member.value() << '\n'; } auto it = book.find("author"); if (it != book.object_range().end()) { // member "author" found } if (book.contains("author")) { // book has member "author" } std::string s = book.get_value_or("author", "author unknown"); // Returns author if found, otherwise "author unknown" try { book["ratings"].as(); } catch (const std::out_of_range&) { // member "ratings" not found } // Add ratings book["ratings"]["*****"] = 4; book["ratings"]["*"] = 1; // Delete one-star ratings book["ratings"].erase("*"); // Serialize the booklist to a file std::ofstream os("./output/store.json"); os << pretty_print(booklist); } void basics_json_example2() { // Deserialize the booklist std::ifstream is("./output/store.json"); json booklist; is >> booklist; // Use a JSONPath expression to find // (1) The authors of books that cost less than $12 json result = json_query(booklist, "$[*][?(@.price < 12)].author"); std::cout << "(1) " << result << '\n'; // (2) The number of books result = json_query(booklist, "$.length"); std::cout << "(2) " << result << '\n'; // (3) The third book result = json_query(booklist, "$[2]"); std::cout << "(3) " << '\n' << pretty_print(result) << '\n'; // (4) The authors of books that were published in 2004 result = json_query(booklist, "$[*][?(@.date =~ /2004.*?/)].author"); std::cout << "(4) " << result << '\n'; // (5) The titles of all books that have ratings result = json_query(booklist, "$[*][?(@.ratings)].title"); std::cout << "(5) " << result << '\n'; } int main() { std::cout << "\nBasics\n\n"; basics_json_example1(); basics_json_example2(); std::cout << '\n'; } jsoncons-1.3.2/examples/src/basics_wexamples.cpp000066400000000000000000000120061477700171100220170ustar00rootroot00000000000000// jsoncons_test.cpp : Defines the entry point for the console application. // #include #include #include using namespace jsoncons; void basics_wjson_example1() { // Construct a book object wjson book1; book1[L"category"] = L"Fiction"; book1[L"title"] = L"A Wild Sheep Chase: A Novel"; book1[L"author"] = L"Haruki Murakami"; book1[L"date"] = L"2002-04-09"; book1[L"price"] = 9.01; book1[L"isbn"] = L"037571894X"; // Construct another using the member function insert_or_assign wjson book2; book2.insert_or_assign(L"category", L"History"); book2.insert_or_assign(L"title", L"Charlie Wilson's War"); book2.insert_or_assign(L"author", L"George Crile"); book2.insert_or_assign(L"date", L"2007-11-06"); book2.insert_or_assign(L"price", 10.50); book2.insert_or_assign(L"isbn", L"0802143415"); // Use insert_or_assign again, but more efficiently wjson book3; // Reserve memory, to avoid reallocations book3.reserve(6); // Insert in name alphabetical order // Give insert_or_assign a hint where to insert the next member auto hint = book3.insert_or_assign(book3.object_range().begin(), L"author", L"Haruki Murakami"); hint = book3.insert_or_assign(hint, L"category", L"Fiction"); hint = book3.insert_or_assign(hint, L"date", L"2006-01-03"); hint = book3.insert_or_assign(hint, L"isbn", L"1400079276"); hint = book3.insert_or_assign(hint, L"price", 13.45); hint = book3.insert_or_assign(hint, L"title", L"Kafka on the Shore"); // Construct a fourth from a string wjson book4 = wjson::parse(LR"( { "category" : "Fiction", "title" : "Pulp", "author" : "Charles Bukowski", "date" : "2004-07-08", "price" : 22.48, "isbn" : "1852272007" } )"); // Construct a booklist array wjson booklist(json_array_arg); // For efficiency, reserve memory, to avoid reallocations booklist.reserve(4); // For efficency, tell jsoncons to move the contents // of the four book objects into the array booklist.push_back(std::move(book1)); booklist.push_back(std::move(book2)); // Add the third one to the front auto where = booklist.insert(booklist.array_range().begin(),std::move(book3)); // Add the last one immediately after booklist.insert(where+1,std::move(book4)); // See what's left of book1, 2, 3 and 4 (expect nulls) std::wcout << book1 << L"," << book2 << L"," << book3 << L"," << book4 << '\n'; //Loop through the booklist elements using a range-based for loop for (const auto& book : booklist.array_range()) { std::wcout << book[L"title"].as() << L"," << book[L"price"].as() << '\n'; } // The second book wjson& book = booklist[1]; //Loop through the book members using a range-based for loop for (const auto& member : book.object_range()) { std::wcout << member.key() << L"," << member.value() << '\n'; } auto it = book.find(L"author"); if (it != book.object_range().end()) { // book has member "author" } if (book.contains(L"author")) { // book has member "author" } auto s = book.get_value_or(L"author", L"author unknown"); // Returns author if found, otherwise "author unknown" try { book[L"ratings"].as(); } catch (const std::out_of_range&) { // member "ratings" not found } // Add ratings book[L"ratings"][L"*****"] = 4; book[L"ratings"][L"*"] = 2; // Delete one-star ratings book[L"ratings"].erase(L"*"); // Serialize the booklist to a file std::wofstream os("./output/booklist2.json"); os << pretty_print(booklist); } void basics_wjson_example2() { // Deserialize the booklist std::wifstream is("./output/booklist2.json"); wjson booklist; is >> booklist; // Use a JSONPath expression to find // // (1) The authors of books that cost less than $12 wjson result = jsonpath::json_query(booklist, L"$[*][?(@.price < 12)].author"); std::wcout << L"(1) " << result << '\n'; // (2) The number of books result = jsonpath::json_query(booklist, L"$.length"); std::wcout << L"(2) " << result << '\n'; // (3) The third book result = jsonpath::json_query(booklist, L"$[2]"); std::wcout << L"(3) " << '\n' << pretty_print(result) << '\n'; // (4) The authors of books that were published in 2004 result = jsonpath::json_query(booklist, L"$[*][?(@.date =~ /2004.*?/)].author"); std::wcout << L"(4) " << result << '\n'; // (5) The titles of all books that have ratings result = jsonpath::json_query(booklist, L"$[*][?(@.ratings)].title"); std::wcout << L"(5) " << result << '\n'; } int main() { std::cout << "\nBasics\n\n"; basics_wjson_example1(); basics_wjson_example2(); std::cout << '\n'; } jsoncons-1.3.2/examples/src/bson_examples.cpp000066400000000000000000000234301477700171100213300ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include using jsoncons::json; using jsoncons::ojson; namespace bson = jsoncons::bson; // for brevity void encode_to_bson() { std::vector buffer; bson::bson_bytes_encoder encoder(buffer); encoder.begin_array(); // The total number of bytes comprising // the bson document will be calculated encoder.string_value("cat"); std::vector purr = {'p','u','r','r'}; encoder.byte_string_value(purr); // default subtype is user defined // or encoder.byte_string_value(purr, 0x80); encoder.int64_value(1431027667, jsoncons::semantic_tag::epoch_second); encoder.end_array(); encoder.flush(); std::cout << jsoncons::byte_string_view(buffer) << "\n\n"; /* 23000000 -- Total number of bytes comprising the document (35 bytes) 02 -- UTF-8 string 3000 -- "0" 04000000 -- number bytes in the string (including trailing byte) 636174 -- "cat" 00 -- trailing byte 05 -- binary 3100 -- "1" 04000000 -- number of bytes 80 -- subtype 70757272 -- 'P','u','r','r' 09 -- datetime 3200 -- "2" d3bf4b55 -- 1431027667 00 */ } void subtype_example() { // Create some bson std::vector buffer; bson::bson_bytes_encoder encoder(buffer); encoder.begin_object(); // The total number of bytes comprising // the bson document will be calculated encoder.key("Hello"); encoder.string_value("World"); encoder.key("Data"); std::vector bstr = {'f','o','o','b','a','r'}; encoder.byte_string_value(bstr); // default subtype is user defined // or encoder.byte_string_value(bstr, 0x80); encoder.end_object(); encoder.flush(); std::cout << "(1)\n" << jsoncons::byte_string_view(buffer) << "\n"; /* 0x27,0x00,0x00,0x00, // Total number of bytes comprising the document (40 bytes) 0x02, // URF-8 string 0x48,0x65,0x6c,0x6c,0x6f, // Hello 0x00, // trailing byte 0x06,0x00,0x00,0x00, // Number bytes in string (including trailing byte) 0x57,0x6f,0x72,0x6c,0x64, // World 0x00, // trailing byte 0x05, // binary 0x44,0x61,0x74,0x61, // Data 0x00, // trailing byte 0x06,0x00,0x00,0x00, // number of bytes 0x80, // subtype 0x66,0x6f,0x6f,0x62,0x61,0x72, 0x00 */ ojson j = bson::decode_bson(buffer); std::cout << "(2)\n" << pretty_print(j) << "\n\n"; std::cout << "(3) " << j["Data"].tag() << "(" << j["Data"].ext_tag() << ")\n\n"; // Get binary value as a std::vector auto bstr2 = j["Data"].as>(); assert(bstr2 == bstr); std::vector buffer2; bson::encode_bson(j, buffer2); assert(buffer2 == buffer); } void int32_example() { ojson j(jsoncons::json_object_arg); j.try_emplace("a", -123); // int32 j.try_emplace("c", 0); // int32 j.try_emplace("b", 123); // int32 std::vector buffer; bson::encode_bson(j, buffer); std::cout << jsoncons::byte_string_view(buffer) << "\n\n"; } void int64_example() { std::map m{ {"a", 100000000000000ULL} }; std::vector buffer; bson::encode_bson(m, buffer); std::cout << jsoncons::byte_string_view(buffer) << "\n\n"; } void double_example() { std::map m{ {"a", 123.4567} }; std::vector buffer; bson::encode_bson(m, buffer); std::cout << jsoncons::byte_string_view(buffer) << "\n\n"; } void bool_example() { std::map m{ {"a", true} }; std::vector buffer; bson::encode_bson(m, buffer); std::cout << jsoncons::byte_string_view(buffer) << "\n\n"; } void array_example() { json a(jsoncons::json_array_arg); a.push_back("hello"); a.push_back("world"); json j(jsoncons::json_object_arg); j["array"] = std::move(a); std::vector buffer; bson::encode_bson(j, buffer); std::cout << jsoncons::byte_string_view(buffer) << "\n\n"; } void utf8_string_example() { json j; j.try_emplace("hello", "world"); std::vector buffer; bson::encode_bson(j, buffer); std::cout << jsoncons::byte_string_view(buffer) << "\n\n"; } void null_example() { json j; j.try_emplace("hello", json::null()); std::vector buffer; bson::encode_bson(j, buffer); std::cout << jsoncons::byte_string_view(buffer) << "\n\n"; } void duration_example1() { auto duration = std::chrono::system_clock::now().time_since_epoch(); auto time = std::chrono::duration_cast(duration); json j; j.try_emplace("time", time); auto milliseconds = j["time"].as(); std::cout << "Time since epoch (milliseconds): " << milliseconds.count() << "\n\n"; auto seconds = j["time"].as(); std::cout << "Time since epoch (seconds): " << seconds.count() << "\n\n"; std::vector data; bson::encode_bson(j, data); std::cout << "BSON bytes:\n" << jsoncons::byte_string_view(data) << "\n\n"; /* 13,00,00,00, // document has 19 bytes 09, // UTC datetime 74,69,6d,65,00, // "time" ea,14,7f,96,73,01,00,00, // 1595957777642 00 // terminating null */ } void binary_example1() { json j; std::vector bstr = { '1', '2', '3', '4' }; j.try_emplace("binary", jsoncons::byte_string_arg, bstr); // default subtype is user defined // or j.try_emplace("binary", byte_string_arg, bstr, 0x80); std::vector buffer; bson::encode_bson(j, buffer); std::cout << jsoncons::byte_string_view(buffer) << "\n\n"; } void binary_example2() { std::vector input = { 0x13,0x00,0x00,0x00, // Document has 19 bytes 0x05, // Binary data 0x70,0x44,0x00, // "pD" 0x05,0x00,0x00,0x00, // Length is 5 0x80, // Subtype is 128 0x48,0x65,0x6c,0x6c,0x6f, // 'H','e','l','l','o' 0x00 // terminating null }; json j = bson::decode_bson(input); std::cout << "JSON:\n" << pretty_print(j) << "\n\n"; std::cout << "tag: " << j["pD"].tag() << "\n"; std::cout << "ext_tag: " << j["pD"].ext_tag() << "\n"; auto bytes = j["pD"].as>(); std::cout << "binary data: " << jsoncons::byte_string_view{ bytes } << "\n"; } void decode_decimal128() { std::vector input = { 0x18,0x00,0x00,0x00, // Document has 24 bytes 0x13, // 128-bit decimal floating point 0x61,0x00, // "a" 0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, // 1E-6176 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00 // terminating null }; json j = bson::decode_bson(input); std::cout << "(1) " << j << "\n\n"; std::cout << "(2) " << j.at("a").tag() << "\n\n"; std::vector output; bson::encode_bson(j, output); assert(output == input); } void encode_decimal128() { json j; j.try_emplace("a", "1E-6176", jsoncons::semantic_tag::float128); // or j["a"] = json("1E-6176", jsoncons::semantic_tag::float128); std::cout << "(1) " << j << "\n\n"; std::cout << "(2) " << j.at("a").tag() << "\n\n"; std::vector output; bson::encode_bson(j, output); std::cout << "(3) " << jsoncons::byte_string_view(output) << "\n\n"; /* 18,00,00,00, // document has 24 bytes 13, // 128-bit decimal floating point 13,00, // "a" 01,00,00,00, 00,00,00,00, // 1E-6176 00,00,00,00, 00,00,00,00, 00 // terminating null */ } void regex_example() { std::vector input = { 0x16,0x00,0x00,0x00, // Document has 22 bytes 0x0B, // Regular expression 0x72,0x65,0x67,0x65,0x78,0x00, // "regex" 0x5E,0x61,0x62,0x63,0x64,0x00, // "^abcd" 0x69,0x6C,0x78,0x00, // "ilx" 0x00 // terminating null }; json j = bson::decode_bson(input); std::cout << "(1) " << j << "\n\n"; std::cout << "(2) " << j.at("regex").tag() << "\n\n"; std::vector output; bson::encode_bson(j, output); assert(output == input); } void oid_example() { std::vector input = { 0x16,0x00,0x00,0x00, // Document has 22 bytes 0x07, // ObjectId 0x6F,0x69,0x64,0x00, // "oid" 0x12,0x34,0x56,0x78,0x90,0xAB, 0xCD,0xEF,0x12,0x34,0xAB,0xCD, // (byte*12) 0x00 // terminating null }; json j = bson::decode_bson(input); std::cout << "(1) " << j << "\n\n"; std::cout << "(2) " << j.at("oid").tag() << "\n\n"; std::vector output; bson::encode_bson(j, output); assert(output == input); } int main() { std::cout << "\nbson examples\n\n"; encode_to_bson(); subtype_example(); null_example(); bool_example(); int32_example(); int64_example(); double_example(); utf8_string_example(); array_example(); duration_example1(); binary_example1(); binary_example2(); decode_decimal128(); encode_decimal128(); regex_example(); oid_example(); std::cout << '\n'; } jsoncons-1.3.2/examples/src/byte_string_examples.cpp000066400000000000000000000050251477700171100227200ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include using namespace jsoncons; // For brevity void construct_json_byte_string() { std::vector bytes = {'H','e','l','l','o'}; // default suggested encoding (base64url) json j1(byte_string_arg, bytes); std::cout << "(1) "<< j1 << "\n\n"; // base64 suggested encoding json j2(byte_string_arg, bytes, semantic_tag::base64); std::cout << "(2) "<< j2 << "\n\n"; // base16 suggested encoding json j3(byte_string_arg, bytes, semantic_tag::base16); std::cout << "(3) "<< j3 << "\n\n"; } void retrieve_json_value_as_byte_string() { json j; j["ByteString"] = json(byte_string_arg, std::vector{ 'H','e','l','l','o' }); j["EncodedByteString"] = json("SGVsbG8=", semantic_tag::base64); std::cout << "(1)\n"; std::cout << pretty_print(j) << "\n\n"; // Retrieve a byte string as a std::vector std::vector v = j["ByteString"].as>(); // Retrieve a byte string from a text string containing base64 character values byte_string bytes2 = j["EncodedByteString"].as(); std::cout << "(2) " << bytes2 << "\n\n"; // Retrieve a byte string view to access the memory that's holding the byte string byte_string_view bsv3 = j["ByteString"].as(); std::cout << "(3) " << bsv3 << "\n\n"; // Can't retrieve a byte string view of a text string try { byte_string_view bsv4 = j["EncodedByteString"].as(); } catch (const std::exception& e) { std::cout << "(4) "<< e.what() << "\n\n"; } } void serialize_json_byte_string() { std::vector bytes = {'H','e','l','l','o'}; json j(byte_string_arg, bytes); // default std::cout << "(1) "<< j << "\n\n"; // base16 auto options2 = json_options{} .byte_string_format(byte_string_chars_format::base16); std::cout << "(2) "<< print(j, options2) << "\n\n"; // base64 auto options3 = json_options{} .byte_string_format(byte_string_chars_format::base64); std::cout << "(3) "<< print(j, options3) << "\n\n"; // base64url auto options4 = json_options{} .byte_string_format(byte_string_chars_format::base64url); std::cout << "(4) "<< print(j, options4) << "\n\n"; } int main() { std::cout << "byte_string examples" << "\n\n"; construct_json_byte_string(); serialize_json_byte_string(); retrieve_json_value_as_byte_string(); } jsoncons-1.3.2/examples/src/cbor_examples.cpp000066400000000000000000000451001477700171100213120ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include "sample_types.hpp" #include #include #include using namespace jsoncons; void encode_to_cbor_buffer() { std::vector buffer; cbor::cbor_bytes_encoder encoder(buffer); encoder.begin_array(); // Indefinite length array encoder.string_value("cat"); std::vector purr = {'p','u','r','r'}; encoder.byte_string_value(purr); std::vector hiss = {'h','i','s','s'}; encoder.byte_string_value(hiss, semantic_tag::base64); // suggested conversion to base64 encoder.int64_value(1431027667, semantic_tag::epoch_second); encoder.end_array(); encoder.flush(); std::cout << byte_string_view(buffer) << "\n\n"; /* 9f -- Start indefinte length array 63 -- String value of length 3 636174 -- "cat" 44 -- Byte string value of length 4 70757272 -- 'p''u''r''r' d6 - Expected conversion to base64 44 68697373 -- 'h''i''s''s' c1 -- Tag value 1 (seconds relative to 1970-01-01T00:00Z in UTC time) 1a -- 32 bit unsigned integer 554bbfd3 -- 1431027667 ff -- "break" */ } void encode_to_cbor_stream() { std::ostringstream os; cbor::cbor_stream_encoder encoder(os); encoder.begin_array(3); // array of length 3 encoder.string_value("-18446744073709551617", semantic_tag::bigint); encoder.string_value("184467440737095516.16", semantic_tag::bigdec); encoder.int64_value(1431027667, semantic_tag::epoch_second); encoder.end_array(); encoder.flush(); std::cout << byte_string_view(os.str()) << "\n\n"; /* 83 -- array of length 3 c3 -- Tag 3 (negative bignum) 49 -- Byte string value of length 9 010000000000000000 -- Bytes content c4 -- Tag 4 (decimal fraction) 82 -- Array of length 2 21 -- -2 (exponent) c2 Tag 2 (positive bignum) 49 -- Byte string value of length 9 010000000000000000 c1 -- Tag 1 (seconds relative to 1970-01-01T00:00Z in UTC time) 1a -- 32 bit unsigned integer 554bbfd3 -- 1431027667 */ } void cbor_reputon_example() { ojson j1 = ojson::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90, "generated": 1514862245 } ] } )"); // Encode a basic_json value to a CBOR value std::vector data; cbor::encode_cbor(j1, data); // Decode a CBOR value to a basic_json value ojson j2 = cbor::decode_cbor(data); std::cout << "(1)\n" << pretty_print(j2) << "\n\n"; // Accessing the data items const ojson& reputons = j2["reputons"]; std::cout << "(2)\n"; for (auto element : reputons.array_range()) { std::cout << element.at("rated").as() << ", "; std::cout << element.at("rating").as() << "\n"; } std::cout << '\n'; // Get a CBOR value for a nested data item with jsonpointer std::error_code ec; auto const& rated = jsonpointer::get(j2, "/reputons/0/rated", ec); if (!ec) { std::cout << "(3) " << rated.as_string() << "\n"; } std::cout << '\n'; } void decode_cbor_byte_string() { // byte string of length 5 std::vector buf = {0x45,'H','e','l','l','o'}; json j = cbor::decode_cbor(buf); auto bytes = j.as(); // byte_string to ostream displays as hex std::cout << "(1) "<< bytes << "\n\n"; // byte string value to JSON text becomes base64url std::cout << "(2) " << j << '\n'; } void decode_byte_string_with_encoding_hint() { // semantic tag indicating expected conversion to base64 // followed by byte string of length 5 std::vector buf = {0xd6,0x45,'H','e','l','l','o'}; json j = cbor::decode_cbor(buf); auto bytes = j.as(); // byte_string to ostream displays as hex std::cout << "(1) "<< bytes << "\n\n"; // byte string value to JSON text becomes base64 std::cout << "(2) " << j << '\n'; } void encode_cbor_byte_string() { // construct byte string value json j(byte_string{'H','e','l','l','o'}); std::vector buf; cbor::encode_cbor(j, buf); std::cout << byte_string_view(buf) << "\n\n"; json j2 = cbor::decode_cbor(buf); std::cout << "(2) " << j2 << '\n'; } void encode_byte_string_with_encoding_hint() { // construct byte string value json j1(byte_string_arg, byte_string{'H','e','l','l','o'}, semantic_tag::base64); std::vector buf; cbor::encode_cbor(j1, buf); std::cout << byte_string_view(buf) << "\n\n"; json j2 = cbor::decode_cbor(buf); std::cout << "(2) " << j2 << '\n'; } void query_cbor() { // Construct a json array of numbers json j(json_array_arg); j.emplace_back(5.0); j.emplace_back(0.000071); j.emplace_back("-18446744073709551617",semantic_tag::bigint); j.emplace_back("1.23456789012345678901234567890", semantic_tag::bigdec); j.emplace_back("0x3p-1", semantic_tag::bigfloat); // Encode to JSON std::cout << "(1)\n"; std::cout << pretty_print(j); std::cout << "\n\n"; // as() and as() std::cout << "(2)\n"; std::cout << std::dec << std::setprecision(15); for (const auto& item : j.array_range()) { std::cout << item.as() << ", " << item.as() << "\n"; } std::cout << "\n"; // Encode to CBOR std::vector v; cbor::encode_cbor(j,v); std::cout << "(3)\n" << byte_string_view(v) << "\n\n"; /* 85 -- Array of length 5 fa -- float 40a00000 -- 5.0 fb -- double 3f129cbab649d389 -- 0.000071 c3 -- Tag 3 (negative bignum) 49 -- Byte string value of length 9 010000000000000000 c4 -- Tag 4 (decimal fraction) 82 -- Array of length 2 38 -- Negative integer of length 1 1c -- -29 c2 -- Tag 2 (positive bignum) 4d -- Byte string value of length 13 018ee90ff6c373e0ee4e3f0ad2 c5 -- Tag 5 (bigfloat) 82 -- Array of length 2 20 -- -1 03 -- 3 */ // Decode back to json json other = cbor::decode_cbor(v); assert(other == j); // Query with JSONPath std::cout << "(4)\n"; json result = jsonpath::json_query(other,"$[?(@ < 1.5)]"); std::cout << pretty_print(result) << "\n\n"; } void encode_cbor_with_packed_strings() { ojson j = ojson::parse(R"( [ { "name" : "Cocktail", "count" : 417, "rank" : 4 }, { "rank" : 4, "count" : 312, "name" : "Bath" }, { "count" : 691, "name" : "Food", "rank" : 4 } ] )"); auto options = cbor::cbor_options{} .pack_strings(true); std::vector buf; cbor::encode_cbor(j, buf, options); std::cout << byte_string_view(buf)<< "\n\n"; /* d90100 -- tag (256) 83 -- array(3) a3 -- map(3) 64 -- text string (4) 6e616d65 -- "name" 68 -- text string (8) 436f636b7461696c -- "Cocktail" 65 -- text string (5) 636f756e74 -- "count" 1901a1 -- unsigned(417) 64 -- text string (4) 72616e6b -- "rank" 04 -- unsigned(4) a3 -- map(3) d819 -- tag(25) 03 -- unsigned(3) 04 -- unsigned(4) d819 -- tag(25) 02 -- unsigned(2) 190138 -- unsigned(312) d819 -- tag(25) 00 -- unsigned(0) 64 -- text string(4) 42617468 -- "Bath" a3 -- map(3) d819 -- tag(25) 02 -- unsigned(2) 1902b3 -- unsigned(691) d819 -- tag(25) 00 -- unsigned(0) 64 - text string(4) 466f6f64 -- "Food" d819 -- tag(25) 03 -- unsigned(3) 04 -- unsigned(4) */ ojson j2 = cbor::decode_cbor(buf); assert(j2 == j); } void decode_cbor_with_packed_strings() { std::vector v = {0xd9,0x01,0x00, // tag(256) 0x85, // array(5) 0x63, // text(3) 0x61,0x61,0x61, // "aaa" 0xd8, 0x19, // tag(25) 0x00, // unsigned(0) 0xd9, 0x01,0x00, // tag(256) 0x83, // array(3) 0x63, // text(3) 0x62,0x62,0x62, // "bbb" 0x63, // text(3) 0x61,0x61,0x61, // "aaa" 0xd8, 0x19, // tag(25) 0x01, // unsigned(1) 0xd9, 0x01,0x00, // tag(256) 0x82, // array(2) 0x63, // text(3) 0x63,0x63,0x63, // "ccc" 0xd8, 0x19, // tag(25) 0x00, // unsigned(0) 0xd8, 0x19, // tag(25) 0x00 // unsigned(0) }; ojson j = cbor::decode_cbor(v); std::cout << pretty_print(j) << "\n"; } const std::vector data = { 0x9f, // Start indefinte length array 0x83, // Array of length 3 0x63, // String value of length 3 0x66,0x6f,0x6f, // "foo" 0x44, // Byte string value of length 4 0x50,0x75,0x73,0x73, // 'P''u''s''s' 0xc5, // Tag 5 (bigfloat) 0x82, // Array of length 2 0x20, // -1 0x03, // 3 0x83, // Another array of length 3 0x63, // String value of length 3 0x62,0x61,0x72, // "bar" 0xd6, // Expected conversion to base64 0x44, // Byte string value of length 4 0x50,0x75,0x73,0x73, // 'P''u''s''s' 0xc4, // Tag 4 (decimal fraction) 0x82, // Array of length 2 0x38, // Negative integer of length 1 0x1c, // -29 0xc2, // Tag 2 (positive bignum) 0x4d, // Byte string value of length 13 0x01,0x8e,0xe9,0x0f,0xf6,0xc3,0x73,0xe0,0xee,0x4e,0x3f,0x0a,0xd2, 0xff // "break" }; void working_with_cbor1() { // Parse the CBOR data into a json value json j = cbor::decode_cbor(data); // Pretty print std::cout << "(1)\n" << pretty_print(j) << "\n\n"; // Iterate over rows std::cout << "(2)\n"; for (const auto& row : j.array_range()) { std::cout << row[1].as() << " (" << row[1].tag() << ")\n"; } std::cout << "\n"; // Select the third column with JSONPath std::cout << "(3)\n"; json result = jsonpath::json_query(j,"$[*][2]"); std::cout << pretty_print(result) << "\n\n"; // Serialize back to CBOR std::vector buffer; cbor::encode_cbor(j, buffer); std::cout << "(4)\n" << byte_string_view(buffer) << "\n\n"; } void working_with_cbor2() { // Parse the string of data into a std::vector> value auto val = cbor::decode_cbor>>(data); std::cout << "(1)\n"; for (const auto& row : val) { std::cout << std::get<0>(row) << ", " << std::get<1>(row) << ", " << std::get<2>(row) << "\n"; } std::cout << "\n"; // Serialize back to CBOR std::vector buffer; cbor::encode_cbor(val, buffer); std::cout << "(2)\n" << byte_string_view(buffer) << "\n\n"; } void working_with_cbor3() { cbor::cbor_bytes_cursor cursor(data); for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::end_array: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::begin_object: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::end_object: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::key: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::string_value: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::byte_string_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::null_value: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::bool_value: std::cout << event.event_type() << ": " << std::boolalpha << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::int64_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::half_value: case staj_event_type::double_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; default: std::cout << "Unhandled event type " << event.event_type() << " " << "(" << event.tag() << ")\n"; break; } } } void working_with_cbor4() { auto filter = [&](const staj_event& ev, const ser_context&) -> bool { return (ev.tag() == semantic_tag::bigdec) || (ev.tag() == semantic_tag::bigfloat); }; cbor::cbor_bytes_cursor cursor(data); auto filtered_c = cursor | filter; for (; !filtered_c.done(); filtered_c.next()) { const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::string_value: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; default: std::cout << "Unhandled event type " << event.event_type() << " " << "(" << event.tag() << ")\n"; break; } } } void ext_type_example() { // Create some CBOR std::vector buffer; cbor::cbor_bytes_encoder encoder(buffer); std::vector bstr = {'f','o','o','b','a','r'}; encoder.byte_string_value(bstr, 274); // byte string with tag 274 encoder.flush(); std::cout << "(1)\n" << byte_string_view(buffer) << "\n\n"; /* d9, // tag 01,12, // 274 46, // byte string, length 6 66,6f,6f,62,61,72 // 'f','o','o','b','a','r' */ json j = cbor::decode_cbor(buffer); std::cout << "(2)\n" << pretty_print(j) << "\n\n"; std::cout << "(3) " << j.tag() << "(" << j.ext_tag() << ")\n\n"; // Get byte string as a std::vector auto bstr2 = j.as>(); std::vector buffer2; cbor::encode_cbor(j, buffer2); std::cout << "(4)\n" << byte_string_view(buffer2.data(),buffer2.size()) << "\n"; } void duration_example1() { auto duration = std::chrono::system_clock::now().time_since_epoch(); auto time = std::chrono::duration_cast(duration); std::vector data; cbor::encode_cbor(time, data); /* c1, // Tag 1 (epoch time) 1a, // 32 bit unsigned integer 5f,23,29,18 // 1596139800 */ std::cout << "CBOR bytes:\n" << jsoncons::byte_string_view(data) << "\n\n"; auto seconds = cbor::decode_cbor(data); std::cout << "Time since epoch (seconds): " << seconds.count() << "\n"; } void duration_example2() { auto duration = std::chrono::system_clock::now().time_since_epoch(); auto time = std::chrono::duration_cast>(duration); std::vector data; cbor::encode_cbor(time, data); /* c1, // Tag 1 (epoch time) fb, // Double 41,d7,c8,ca,46,1c,0f,87 // 1596139800.43845 */ std::cout << "CBOR bytes:\n" << jsoncons::byte_string_view(data) << "\n\n"; auto seconds = cbor::decode_cbor>(data); std::cout << "Time since epoch (seconds): " << seconds.count() << "\n"; auto milliseconds = cbor::decode_cbor(data); std::cout << "Time since epoch (milliseconds): " << milliseconds.count() << "\n"; } void encode_with_raw_cbor_tags() // (since 1.2.0) { std::vector data; cbor::cbor_bytes_encoder encoder(data); encoder.begin_array(1); encoder.uint64_value_with_tag(10, 0xC1); encoder.end_array(); encoder.flush(); cbor::cbor_bytes_cursor cursor(data); assert(cursor.current().event_type() == jsoncons::staj_event_type::begin_array); cursor.next(); assert(cursor.raw_tag() == 0xC1); assert(cursor.current().get() == 10); } int main() { std::cout << "\ncbor examples\n\n"; encode_byte_string_with_encoding_hint(); encode_cbor_byte_string(); encode_to_cbor_stream(); cbor_reputon_example(); encode_cbor_with_packed_strings(); decode_cbor_with_packed_strings(); decode_cbor_byte_string(); decode_byte_string_with_encoding_hint(); working_with_cbor3(); std::cout << "\n"; working_with_cbor4(); std::cout << "\n"; working_with_cbor1(); std::cout << "\n"; working_with_cbor2(); std::cout << '\n'; encode_to_cbor_buffer(); query_cbor(); ext_type_example(); duration_example1(); duration_example2(); encode_with_raw_cbor_tags(); } jsoncons-1.3.2/examples/src/cbor_typed_array_examples.cpp000066400000000000000000000227111477700171100237200ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include "sample_types.hpp" #include #include #include using namespace jsoncons; void decode_float64_big_endian_array() { const std::vector input = { 0xd8,0x52, // Tag 82 (float64 big endian Typed Array) 0x50, // Byte string value of length 16 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; auto j = cbor::decode_cbor(input); std::cout << "(1)\n" << pretty_print(j) << "\n\n"; auto v = cbor::decode_cbor>(input); std::cout << "(2)\n"; for (auto item : v) { std::cout << std::defaultfloat << item << "\n"; } std::cout << "\n"; std::vector output1; cbor::encode_cbor(v, output1); // output1 contains a classical CBOR array std::cout << "(3)\n" << byte_string_view(output1) << "\n\n"; std::vector output2; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(v, output2, options); // output2 contains a float64, native endian, Typed Array std::cout << "(4)\n" << byte_string_view(output2) << "\n\n"; } void decode_mult_dim_row_major() { const std::vector input = { 0xd8,0x28, // Tag 40 (multi-dimensional row major array) 0x82, // array(2) 0x82, // array(2) 0x02, // unsigned(2) 1st Dimension 0x03, // unsigned(3) 2nd Dimension 0xd8,0x41, // Tag 65 (uint16 big endian Typed Array) 0x4c, // byte string(12) 0x00,0x02, // unsigned(2) 0x00,0x04, // unsigned(4) 0x00,0x08, // unsigned(8) 0x00,0x04, // unsigned(4) 0x00,0x10, // unsigned(16) 0x01,0x00 // unsigned(256) }; json j = cbor::decode_cbor(input); std::cout << j.tag() << "\n"; std::cout << pretty_print(j) << "\n"; } void encode_decode_large_typed_array() { std::ios_base::fmtflags f( std::cout.flags() ); std::vector x(15000000); for (std::size_t i = 0; i < x.size(); ++i) { x[i] = static_cast(i); } auto options = cbor::cbor_options{} .use_typed_arrays(true); std::vector buf; cbor::encode_cbor(x, buf, options); std::cout << "first 19 bytes:\n\n"; std::cout << byte_string_view(buf).substr(0, 19) << "\n\n"; /* 0xd8,0x55 -- Tag 85 (float32 little endian Typed Array) 0x5a - byte string (four-byte uint32_t for n, and then n bytes follow) 03 93 87 00 -- 60000000 00 00 00 00 -- 0.0f 00 00 80 3f -- 1.0f 00 00 00 40 -- 2.0f */ auto y = cbor::decode_cbor>(buf); assert(y == x); std::cout.flags( f ); } void encode_mult_dim_array() { std::vector v; cbor::cbor_bytes_encoder encoder(v); std::vector shape = { 2,3 }; encoder.begin_multi_dim(shape, semantic_tag::multi_dim_column_major); encoder.begin_array(6); encoder.uint64_value(2); encoder.uint64_value(4); encoder.uint64_value(8); encoder.uint64_value(4); encoder.uint64_value(16); encoder.uint64_value(256); encoder.end_array(); encoder.end_multi_dim(); std::cout << "(1)\n" << byte_string_view(v) << "\n\n"; auto j = cbor::decode_cbor(v); std::cout << "(2) " << j.tag() << "\n"; std::cout << pretty_print(j) << "\n\n"; } void encode_half_array() { std::ios_base::fmtflags f( std::cout.flags() ); std::vector buffer; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::cbor_bytes_encoder encoder(buffer, options); std::vector values = {0x3bff,0x3c00,0x3c01,0x3555}; encoder.typed_array(half_arg, values); // buffer contains a half precision floating-point, native endian, Typed Array std::cout << "(1)\n" << byte_string_view(buffer) << "\n\n"; auto j = cbor::decode_cbor(buffer); std::cout << "(2)\n"; for (auto item : j.array_range()) { std::cout << std::boolalpha << item.is_half() << " " << std::hex << (int)item.as() << " " << std::defaultfloat << item.as() << "\n"; } std::cout << "\n"; std::cout << "(3)\n" << pretty_print(j) << "\n\n"; std::cout.flags( f ); } void cursor_example_multi_dim_row_major_typed_array() { const std::vector input = { 0xd8,0x28, // Tag 40 (multi-dimensional row major array) 0x82, // array(2) 0x82, // array(2) 0x02, // unsigned(2) 1st Dimension 0x03, // unsigned(3) 2nd Dimension 0xd8,0x41, // Tag 65 (uint16 big endian Typed Array) 0x4c, // byte string(12) 0x00,0x02, // unsigned(2) 0x00,0x04, // unsigned(4) 0x00,0x08, // unsigned(8) 0x00,0x04, // unsigned(4) 0x00,0x10, // unsigned(16) 0x01,0x00 // unsigned(256) }; cbor::cbor_bytes_cursor cursor(input); for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::end_array: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; default: std::cout << "Unhandled event type " << event.event_type() << " " << "(" << event.tag() << ")\n"; break; } } } void cursor_example_multi_dim_column_major_classical_cbor_array() { const std::vector input = { 0xd9,0x04,0x10, // Tag 1040 (multi-dimensional column major array) 0x82, // array(2) 0x82, // array(2) 0x02, // unsigned(2) 1st Dimension 0x03, // unsigned(3) 2nd Dimension 0x86, // array(6) 0x02, // unsigned(2) 0x04, // unsigned(4) 0x08, // unsigned(8) 0x04, // unsigned(4) 0x10, // unsigned(16) 0x19,0x01,0x00 // unsigned(256) }; cbor::cbor_bytes_cursor cursor(input); for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::end_array: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; default: std::cout << "Unhandled event type " << event.event_type() << " " << "(" << event.tag() << ")\n"; break; } } } struct my_cbor_visitor : public default_json_visitor { std::vector v; private: bool visit_typed_array(const span& data, semantic_tag, const ser_context&, std::error_code&) override { v = std::vector(data.begin(),data.end()); return false; } }; void read_to_cbor_visitor() { std::vector v{10.0,20.0,30.0,40.0}; std::vector buffer; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(v, buffer, options); std::cout << "(1)\n"; std::cout << byte_string_view(buffer) << "\n\n"; /* 0xd8, // Tag 0x56, // Tag 86, float64, little endian, Typed Array 0x58,0x20, // Byte string value of length 32 0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x40, 0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x40, 0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x40, 0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x40 */ cbor::cbor_bytes_cursor cursor(buffer); assert(cursor.current().event_type() == staj_event_type::begin_array); assert(cursor.is_typed_array()); my_cbor_visitor visitor; cursor.read_to(visitor); std::cout << "(2)\n"; for (auto item : visitor.v) { std::cout << item << "\n"; } std::cout << "\n"; } int main() { std::cout << "\ncbor typed array examples\n\n"; decode_float64_big_endian_array(); decode_mult_dim_row_major(); encode_mult_dim_array(); encode_half_array(); cursor_example_multi_dim_row_major_typed_array(); cursor_example_multi_dim_column_major_classical_cbor_array(); read_to_cbor_visitor(); encode_decode_large_typed_array(); std::cout << "\n\n"; } jsoncons-1.3.2/examples/src/container_examples.cpp000066400000000000000000000055701477700171100223560ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace jsoncons; void container_example1() { std::cout << "Convert from and to standard library containers\n" << '\n'; { std::vector v{1, 2, 3, 4}; json j(v); std::cout << "(1) "<< j << '\n'; std::deque d = j.as>(); } std::vector vec2{1ul, 2ul, 3ul, 4ul}; json j_vec2(vec2); std::cout << j_vec2 << '\n'; std::deque deque1{1.123, 2.234, 3.456, 4.567}; json j_deque1(deque1); std::cout << j_deque1 << '\n'; std::list list1{true, true, false, true}; json j_list1(list1); std::cout << j_list1 << '\n'; std::forward_listflist1 {12345678909876, 23456789098765, 34567890987654, 45678909876543}; json j_flist1(flist1); std::cout << j_flist1 << '\n'; std::array array1 {{1, 2, 3, 4}}; json j_array1(array1); std::set set1{"one", "two", "three", "four"}; json j_set1(set1); std::cout << j_set1 << '\n'; // ["four", "one", "three", "two"] std::unordered_set uset1{"one", "two", "three", "four"}; json j_uset1(uset1); std::cout << j_uset1 << '\n'; // maybe ["two", "three", "four", "one"] std::multiset mset1{"one", "two", "one", "four"}; json j_mset1(mset1); // only one entry for "one" is used std::cout << j_mset1 << '\n'; // maybe ["one", "two", "four"] std::unordered_multiset umset1 {"one", "two", "one", "four"}; json j_umset1(umset1); // both entries for "one" are used // maybe ["one", "two", "one", "four"] { std::map m{{"one",1},{"two",2},{"three",3}}; json j(m); std::cout << "(1) " << j << '\n'; std::unordered_map um = j.as>(); } std::unordered_map umap1{ {"one", 1.2}, {"two", 2.3}, {"three", 3.4} }; json j_umap1(umap1); std::cout << j_umap1 << '\n'; std::cout << "\n\n"; } void map_with_integer_key_example() { std::map m{ {1,"foo",},{2,"baz"} }; json j{m}; std::cout << "(1)\n"; std::cout << pretty_print(j) << "\n\n"; auto other = j.as>(); std::cout << "(2)\n"; for (const auto& item : other) { std::cout << item.first << " | " << item.second << "\n"; } std::cout << "\n\n"; } int main() { std::cout << "\nContainer examples\n\n"; container_example1(); map_with_integer_key_example(); std::cout << '\n'; } jsoncons-1.3.2/examples/src/csv_examples.cpp000066400000000000000000000544421477700171100211710ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include "sample_types.hpp" namespace csv = jsoncons::csv; void encode_n_objects() { const std::string jtext = R"( [ { "customer_name": "John Roe", "has_coupon": true, "phone_number": "0272561313", "zip_code": "01001", "sales_tax_rate": 0.05, "total_amount": 431.65 }, { "customer_name": "Jane Doe", "has_coupon": false, "phone_number": "416-272-2561", "zip_code": "55416", "sales_tax_rate": 0.15, "total_amount": 480.7 }, { "customer_name": "Joe Bloggs", "has_coupon": false, "phone_number": "4162722561", "zip_code": "55416", "sales_tax_rate": 0.15, "total_amount": 300.7 }, { "customer_name": "John Smith", "has_coupon": false, "phone_number": null, "zip_code": "22313-1450", "sales_tax_rate": 0.15, "total_amount": 300.7 } ] )"; auto j = jsoncons::ojson::parse(jtext); std::string output; auto ioptions = csv::csv_options{} .quote_style(csv::quote_style_kind::nonnumeric); csv::encode_csv(j, output, ioptions); std::cout << output << "\n\n"; auto ooptions = csv::csv_options{} .assume_header(true); auto other = csv::decode_csv(output, ooptions); assert(other == j); } void encode_n_rows() { const std::string jtext = R"( [ ["customer_name","has_coupon","phone_number","zip_code","sales_tax_rate","total_amount"], ["John Roe",true,"0272561313","01001",0.05,431.65], ["Jane Doe",false,"416-272-2561","55416",0.15,480.7], ["Joe Bloggs",false,"4162722561","55416",0.15,300.7], ["John Smith",false,null,"22313-1450",0.15,300.7] ] )"; auto j = jsoncons::json::parse(jtext); std::string output; auto ioptions = csv::csv_options{} .quote_style(csv::quote_style_kind::nonnumeric); csv::encode_csv(j, output, ioptions); std::cout << output << "\n\n"; auto other = csv::decode_csv(output); assert(other == j); } void encode_m_columns() { const std::string jtext = R"( { "customer_name": ["John Roe","Jane Doe","Joe Bloggs","John Smith"], "has_coupon": [true,false,false,false], "phone_number": ["0272561313","416-272-2561","4162722561",null], "zip_code": ["01001","55416","55416","22313-1450"], "sales_tax_rate": [0.05,0.15,0.15,0.15], "total_amount": [431.65,480.7,300.7,300.7] } )"; auto j = jsoncons::ojson::parse(jtext); std::string output; auto ioptions = csv::csv_options{} .quote_style(csv::quote_style_kind::nonnumeric); csv::encode_csv(j, output, ioptions); std::cout << output << "\n\n"; auto ooptions = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::m_columns); auto other = csv::decode_csv(output, ooptions); assert(other == j); } void csv_source_to_json_value() { const std::string s = R"(Date,1Y,2Y,3Y,5Y 2017-01-09,0.0062,0.0075,0.0083,0.011 2017-01-08,0.0063,0.0076,0.0084,0.0112 2017-01-08,0.0063,0.0076,0.0084,0.0112 )"; auto options = csv::csv_options{} .assume_header(true) .column_types("string,float,float,float,float"); // csv_mapping_kind::n_objects options.mapping_kind(csv::csv_mapping_kind::n_objects); auto j1 = csv::decode_csv(s,options); std::cout << "\n(1)\n"<< pretty_print(j1) << "\n"; // csv_mapping_kind::n_rows options.mapping_kind(csv::csv_mapping_kind::n_rows); auto j2 = csv::decode_csv(s,options); std::cout << "\n(2)\n"<< pretty_print(j2) << "\n"; // csv_mapping_kind::m_columns options.mapping_kind(csv::csv_mapping_kind::m_columns); auto j3 = csv::decode_csv(s,options); std::cout << "\n(3)\n" << pretty_print(j3) << "\n"; } void csv_source_to_cpp_object() { const std::string data = R"(Date,1Y,2Y,3Y,5Y 2017-01-09,0.0062,0.0075,0.0083,0.011 2017-01-08,0.0063,0.0076,0.0084,0.0112 2017-01-08,0.0063,0.0076,0.0084,0.0112 )"; auto ioptions = csv::csv_options{} .header_lines(1) .mapping_kind(csv::csv_mapping_kind::n_rows); using table_type = std::vector>; table_type table = csv::decode_csv(data,ioptions); std::cout << "(1)\n"; for (const auto& row : table) { std::cout << std::get<0>(row) << "," << std::get<1>(row) << "," << std::get<2>(row) << "," << std::get<3>(row) << "," << std::get<4>(row) << "\n"; } std::cout << "\n"; std::string output; auto ooptions = csv::csv_options{} .column_names("Date,1Y,2Y,3Y,5Y"); csv::encode_csv(table, output, ooptions); std::cout << "(2)\n"; std::cout << output << "\n"; } void csv_decode_without_type_inference() { std::string s = R"(employee-no,employee-name,dept,salary 00000001,"Smith,Matthew",sales,150000.00 00000002,"Brown,Sarah",sales,89000.00 )"; auto options = csv::csv_options{} .assume_header(true) .infer_types(false); auto j = csv::decode_csv(s,options); std::cout << pretty_print(j) << '\n'; } void read_write_csv_tasks() { std::ifstream is("./input/tasks.csv"); jsoncons::json_decoder decoder; auto options = csv::csv_options{} .assume_header(true) .trim(true) .ignore_empty_values(true) .column_types("integer,string,string,string"); csv::csv_stream_reader reader(is,decoder,options); reader.read(); auto tasks = decoder.get_result(); std::cout << "(1)\n"; std::cout << pretty_print(tasks) << "\n\n"; std::cout << "(2)\n"; csv::csv_stream_encoder encoder(std::cout); tasks.dump(encoder); } void serialize_array_of_arrays_to_comma_delimited() { std::string in_file = "./input/countries.json"; std::ifstream is(in_file); jsoncons::json countries; is >> countries; csv::csv_stream_encoder encoder(std::cout); countries.dump(encoder); } void encode_to_tab_delimited_file() { std::string in_file = "./input/employees.json"; std::ifstream is(in_file); jsoncons::json employees; is >> employees; auto options = csv::csv_options{} .field_delimiter('\t'); csv::csv_stream_encoder encoder(std::cout,options); employees.dump(encoder); } void serialize_books_to_csv_file() { auto books = jsoncons::json::parse(R"( [ { "title" : "Kafka on the Shore", "author" : "Haruki Murakami", "price" : 25.17 }, { "title" : "Women: A Novel", "author" : "Charles Bukowski", "price" : 12.00 }, { "title" : "Cutter's Way", "author" : "Ivan Passer" } ] )"); csv::csv_stream_encoder encoder(std::cout); books.dump(encoder); } void serialize_books_to_csv_file_with_reorder() { auto books = jsoncons::json::parse(R"( [ { "title" : "Kafka on the Shore", "author" : "Haruki Murakami", "price" : 25.17 }, { "title" : "Women: A Novel", "author" : "Charles Bukowski", "price" : 12.00 }, { "title" : "Cutter's Way", "author" : "Ivan Passer" } ] )"); auto options = csv::csv_options{} .column_names("author,title,price"); csv::csv_stream_encoder encoder(std::cout, options); books.dump(encoder); } void last_column_repeats() { const std::string bond_yields = R"(Date,Yield 2017-01-09,0.0062,0.0075,0.0083,0.011,0.012 2017-01-08,0.0063,0.0076,0.0084,0.0112,0.013 2017-01-08,0.0063,0.0076,0.0084,0.0112,0.014 )"; jsoncons::json_decoder decoder1; auto options1 = csv::csv_options{} .header_lines(1) .column_types("string,float*"); std::istringstream is1(bond_yields); csv::csv_stream_reader reader1(is1, decoder1, options1); reader1.read(); auto val1 = decoder1.get_result(); std::cout << "\n(1)\n" << pretty_print(val1) << "\n"; jsoncons::json_decoder decoder2; auto options2 = csv::csv_options{} .assume_header(true) .column_types("string,[float*]"); std::istringstream is2(bond_yields); csv::csv_stream_reader reader2(is2, decoder2, options2); reader2.read(); auto val2 = decoder2.get_result(); std::cout << "\n(2)\n" << pretty_print(val2) << "\n"; } void last_two_columns_repeat() { const std::string holidays = R"(1,CAD,2,UK,3,EUR,4,US 38719,2-Jan-2006,40179,1-Jan-2010,38719,2-Jan-2006,39448,1-Jan-2008 38733,16-Jan-2006,40270,2-Apr-2010,38733,16-Jan-2006,39468,21-Jan-2008 )"; // array of arrays jsoncons::json_decoder decoder1; auto options1 = csv::csv_options{} .column_types("[integer,string]*"); std::istringstream is1(holidays); csv::csv_stream_reader reader1(is1, decoder1, options1); reader1.read(); auto val1 = decoder1.get_result(); std::cout << "(1)\n" << pretty_print(val1) << "\n"; // array of objects jsoncons::json_decoder decoder2; auto options2 = csv::csv_options{} .header_lines(1) .column_names("CAD,UK,EUR,US") .column_types("[integer,string]*"); std::istringstream is2(holidays); csv::csv_stream_reader reader2(is2, decoder2, options2); reader2.read(); auto val2 = decoder2.get_result(); std::cout << "(2)\n" << pretty_print(val2) << "\n"; } void decode_csv_string() { std::string s = R"(employee-no,employee-name,dept,salary 00000001,\"Smith,Matthew\",sales,150000.00 00000002,\"Brown,Sarah\",sales,89000.00 )"; auto options = csv::csv_options{} .assume_header(true) .column_types("string,string,string,float"); auto j = csv::decode_csv(s,options); std::cout << pretty_print(j) << '\n'; } void decode_csv_stream() { const std::string bond_yields = R"(Date,1Y,2Y,3Y,5Y 2017-01-09,0.0062,0.0075,0.0083,0.011 2017-01-08,0.0063,0.0076,0.0084,0.0112 2017-01-07,0.0063,0.0076,0.0084,0.0112 )"; auto options = csv::csv_options{} .assume_header(true) .column_types("string,float,float,float,float"); std::istringstream is(bond_yields); auto j = csv::decode_csv(is,options); std::cout << pretty_print(j) << '\n'; } void encode_csv_file_from_books() { auto books = jsoncons::json::parse(R"( [ { "title" : "Kafka on the Shore", "author" : "Haruki Murakami", "price" : 25.17 }, { "title" : "Women: A Novel", "author" : "Charles Bukowski", "price" : 12.00 }, { "title" : "Cutter's Way", "author" : "Ivan Passer" } ] )"); csv::encode_csv(books, std::cout); } void decode_encode_csv_tasks() { std::ifstream is("./input/tasks.csv"); auto options = csv::csv_options{} .assume_header(true) .trim(true) .ignore_empty_values(true) .column_types("integer,string,string,string"); auto tasks = csv::decode_csv(is, options); std::cout << "(1)\n" << pretty_print(tasks) << "\n\n"; std::cout << "(2)\n"; csv::encode_csv(tasks, std::cout); } void csv_parser_type_inference() { auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_objects); std::ifstream is1("input/sales.csv"); auto j1 = csv::decode_csv(is1,options); std::cout << "\n(1)\n"<< pretty_print(j1) << "\n"; options.mapping_kind(csv::csv_mapping_kind::n_rows); std::ifstream is2("input/sales.csv"); auto j2 = csv::decode_csv(is2,options); std::cout << "\n(2)\n"<< pretty_print(j2) << "\n"; options.mapping_kind(csv::csv_mapping_kind::m_columns); std::ifstream is3("input/sales.csv"); auto j3 = csv::decode_csv(is3,options); std::cout << "\n(3)\n"<< pretty_print(j3) << "\n"; } // Examples with subfields void decode_csv_with_subfields() { const std::string s = R"(calculationPeriodCenters,paymentCenters,resetCenters NY;LON,TOR,LON NY,LON,TOR;LON "NY";"LON","TOR","LON" "NY","LON","TOR";"LON" )"; auto options1 = csv::csv_options{} .assume_header(true) .subfield_delimiter(';'); auto j1 = csv::decode_csv(s,options1); auto print_options = jsoncons::json_options{} .array_array_line_splits(jsoncons::line_split_kind::same_line) .float_format(jsoncons::float_chars_format::fixed); std::cout << "(1)\n" << pretty_print(j1,print_options) << "\n\n"; auto options2 = csv::csv_options{} .mapping_kind(csv::csv_mapping_kind::n_rows) .subfield_delimiter(';'); auto j2 = csv::decode_csv(s,options2); std::cout << "(2)\n" << pretty_print(j2,print_options) << "\n\n"; auto options3 = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::m_columns) .subfield_delimiter(';'); auto j3 = csv::decode_csv(s,options3); std::cout << "(3)\n" << pretty_print(j3,print_options) << "\n\n"; } void encode_json_with_subfields() { std::string jtext = R"( [ { "calculationPeriodCenters": ["NY","LON"], "paymentCenters": "TOR", "resetCenters": "LON" }, { "calculationPeriodCenters": "NY", "paymentCenters": "LON", "resetCenters": ["TOR","LON"] }, { "calculationPeriodCenters": ["NY","LON"], "paymentCenters": "TOR", "resetCenters": "LON" }, { "calculationPeriodCenters": "NY", "paymentCenters": "LON", "resetCenters": ["TOR","LON"] } ] )"; auto j = jsoncons::ojson::parse(jtext); auto options = csv::csv_options{} .subfield_delimiter(';'); std::string buf; csv::encode_csv(j, buf, options); std::cout << buf << "\n"; } const std::string data = R"(index_id,observation_date,rate EUR_LIBOR_06M,2015-10-23,0.0000214 EUR_LIBOR_06M,2015-10-26,0.0000143 EUR_LIBOR_06M,2015-10-27,0.0000001 )"; void as_a_variant_like_structure() { auto options = csv::csv_options{} .assume_header(true); // Parse the CSV data into an ojson value auto j = csv::decode_csv(data, options); // Pretty print auto print_options = jsoncons::json_options{} .float_format(jsoncons::float_chars_format::fixed); std::cout << "(1)\n" << pretty_print(j, print_options) << "\n\n"; // Iterate over the rows std::cout << std::fixed << std::setprecision(7); std::cout << "(2)\n"; for (const auto& row : j.array_range()) { // Access rated as string and rating as double std::cout << row["index_id"].as() << ", " << row["observation_date"].as() << ", " << row["rate"].as() << "\n"; } } void as_a_strongly_typed_cpp_structure() { auto options = csv::csv_options{} .assume_header(true) .float_format(jsoncons::float_chars_format::fixed); // Decode the CSV data into a c++ structure std::vector v = csv::decode_csv>(data, options); // Iterate over values std::cout << std::fixed << std::setprecision(7); std::cout << "(1)\n"; for (const auto& item : v) { std::cout << item.index_id() << ", " << item.observation_date() << ", " << item.rate() << "\n"; } // Encode the c++ structure into CSV data std::string s; csv::encode_csv(v, s, options); std::cout << "(2)\n"; std::cout << s << "\n"; } void as_a_stream_of_json_events() { auto options = csv::csv_options{} .assume_header(true); csv::csv_string_cursor cursor(data, options); for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case jsoncons::staj_event_type::begin_array: std::cout << event.event_type() << " " << "\n"; break; case jsoncons::staj_event_type::end_array: std::cout << event.event_type() << " " << "\n"; break; case jsoncons::staj_event_type::begin_object: std::cout << event.event_type() << " " << "\n"; break; case jsoncons::staj_event_type::end_object: std::cout << event.event_type() << " " << "\n"; break; case jsoncons::staj_event_type::key: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case jsoncons::staj_event_type::string_value: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case jsoncons::staj_event_type::null_value: std::cout << event.event_type() << "\n"; break; case jsoncons::staj_event_type::bool_value: std::cout << event.event_type() << ": " << std::boolalpha << event.get() << "\n"; break; case jsoncons::staj_event_type::int64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case jsoncons::staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case jsoncons::staj_event_type::double_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; default: std::cout << "Unhandled event type: " << event.event_type() << " " << "\n"; break; } } } void grouped_into_basic_json_records() { auto options = csv::csv_options{} .assume_header(true); csv::csv_string_cursor cursor(data, options); auto view = staj_array(cursor); auto it = view.begin(); auto end = view.end(); auto print_options = jsoncons::json_options{} .float_format(jsoncons::float_chars_format::fixed); while (it != end) { std::cout << pretty_print(*it, print_options) << "\n"; ++it; } } void grouped_into_strongly_typed_records() { using record_type = std::tuple; auto options = csv::csv_options{} .assume_header(true); csv::csv_string_cursor cursor(data, options); auto view = staj_array(cursor); std::cout << std::fixed << std::setprecision(7); for (const auto& record : view) { std::cout << std::get<0>(record) << ", " << std::get<1>(record) << ", " << std::get<2>(record) << "\n"; } } void encode_nested_json_to_csv() // (since 1.2.0) { std::string jtext = R"( [ { "text": "Chicago Reader", "float": 1.0, "datetime": "1971-01-01T04:14:00", "boolean": true, "nested": { "time": "04:14:00", "nested": { "date": "1971-01-01", "integer": 40 } } }, { "text": "Chicago Sun-Times", "float": 1.27, "datetime": "1948-01-01T14:57:13", "boolean": true, "nested": { "time": "14:57:13", "nested": { "date": "1948-01-01", "integer": 63 } } } ] )"; auto j = jsoncons::ojson::parse(jtext); auto options = csv::csv_options{} .flat(false); std::string buf; csv::encode_csv(j, buf, options); std::cout << buf << "\n"; } void encode_nested_json_to_csv_with_column_mapping() // (since 1.2.0) { std::string jtext = R"( [ { "text": "Chicago Reader", "float": 1.0, "datetime": "1971-01-01T04:14:00", "boolean": true, "nested": { "time": "04:14:00", "nested": { "date": "1971-01-01", "integer": 40 } } }, { "text": "Chicago Sun-Times", "float": 1.27, "datetime": "1948-01-01T14:57:13", "boolean": true, "nested": { "time": "14:57:13", "nested": { "date": "1948-01-01", "integer": 63 } } } ] )"; auto j = jsoncons::ojson::parse(jtext); auto options = csv::csv_options{} .flat(false) .column_mapping({ {"/datetime","Timestamp"}, {"/text", "Newspaper"}, {"/nested/nested/integer","Count"} }); std::string buf; csv::encode_csv(j, buf, options); std::cout << buf << "\n"; } int main() { std::cout << "\nCSV examples\n\n"; read_write_csv_tasks(); encode_to_tab_delimited_file(); serialize_array_of_arrays_to_comma_delimited(); serialize_books_to_csv_file(); serialize_books_to_csv_file_with_reorder(); last_column_repeats(); last_two_columns_repeat(); decode_csv_string(); decode_csv_stream(); encode_csv_file_from_books(); decode_encode_csv_tasks(); csv_decode_without_type_inference(); csv_parser_type_inference(); decode_csv_with_subfields(); encode_json_with_subfields(); csv_source_to_json_value(); std::cout << "\n"; as_a_variant_like_structure(); std::cout << "\n"; as_a_strongly_typed_cpp_structure(); std::cout << "\n"; as_a_stream_of_json_events(); std::cout << "\n"; grouped_into_basic_json_records(); std::cout << "\n"; grouped_into_strongly_typed_records(); std::cout << "\n"; encode_n_objects(); std::cout << "\n"; encode_n_rows(); std::cout << "\n"; encode_m_columns(); std::cout << "\n"; csv_source_to_cpp_object(); std::cout << "\n"; encode_nested_json_to_csv_with_column_mapping(); std::cout << "\n"; encode_nested_json_to_csv(); std::cout << '\n'; } jsoncons-1.3.2/examples/src/data_model_examples.cpp000066400000000000000000000062531477700171100224640ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include using namespace jsoncons; void data_model_example1() { json j(json_array_arg); j.emplace_back("foo"); std::vector bstr = {'b','a','r'}; j.emplace_back(byte_string_arg, bstr); j.emplace_back("-18446744073709551617", semantic_tag::bigint); j.emplace_back("273.15", semantic_tag::bigdec); j.emplace_back("2018-10-19 12:41:07-07:00", semantic_tag::datetime); j.emplace_back(1431027667, semantic_tag::epoch_second); j.emplace_back(-1431027667, semantic_tag::epoch_second); j.emplace_back(1431027667.5, semantic_tag::epoch_second); std::cout << "(1)\n" << pretty_print(j) << "\n\n"; std::vector bytes; cbor::encode_cbor(j, bytes); std::cout << "(2)\n" << byte_string_view(bytes) << "\n\n"; /* 88 -- Array of length 8 63 -- String value of length 3 666f6f -- "foo" 43 -- Byte string value of length 3 626172 -- 'b''a''r' c3 -- Tag 3 (negative bignum) 49 Byte string value of length 9 010000000000000000 -- Bytes content c4 - Tag 4 (decimal fraction) 82 -- Array of length 2 21 -- -2 19 6ab3 -- 27315 c0 -- Tag 0 (date-time) 78 19 -- Length (25) 323031382d31302d31392031323a34313a30372d30373a3030 -- "2018-10-19 12:41:07-07:00" c1 -- Tag 1 (epoch time) 1a -- uint32_t 554bbfd3 -- 1431027667 c1 3a 554bbfd2 c1 fb 41d552eff4e00000 */ } void data_model_example2() { std::vector bytes; cbor::cbor_bytes_encoder encoder(bytes); encoder.begin_array(); // indefinite length outer array encoder.string_value("foo"); encoder.byte_string_value(byte_string{'b','a','r'}); encoder.string_value("-18446744073709551617", semantic_tag::bigint); encoder.string_value("273.15", semantic_tag::bigdec); encoder.string_value("2018-10-19 12:41:07-07:00", semantic_tag::datetime) ; encoder.int64_value(1431027667, semantic_tag::epoch_second); encoder.int64_value(-1431027667, semantic_tag::epoch_second); encoder.double_value(1431027667.5, semantic_tag::epoch_second); encoder.end_array(); encoder.flush(); std::cout << "(1)\n" << byte_string_view(bytes) << "\n\n"; /* 9f -- Start indefinite length array 63 -- String value of length 3 666f6f -- "foo" 43 -- Byte string value of length 3 626172 -- 'b''a''r' c3 -- Tag 3 (negative bignum) 49 Byte string value of length 9 010000000000000000 -- Bytes content c4 - Tag 4 (decimal fraction) 82 -- Array of length 2 21 -- -2 19 6ab3 -- 27315 c0 -- Tag 0 (date-time) 78 19 -- Length (25) 323031382d31302d31392031323a34313a30372d30373a3030 -- "2018-10-19 12:41:07-07:00" c1 -- Tag 1 (epoch time) 1a -- uint32_t 554bbfd3 -- 1431027667 c1 3a 554bbfd2 c1 fb 41d552eff4e00000 ff -- "break" */ json j = cbor::decode_cbor(bytes); std::cout << "(2)\n" << pretty_print(j) << "\n\n"; } int main() { std::cout << "\ndata model examples\n\n"; data_model_example2(); data_model_example1(); std::cout << '\n'; } jsoncons-1.3.2/examples/src/erase_examples.cpp000066400000000000000000000051131477700171100214640ustar00rootroot00000000000000// jsoncons_test.cpp : Defines the entry point for the console application. // #include #include #include #include #include // For brevity using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; namespace jsonpath = jsoncons::jsonpath; std::string input = R"( [ { "address": "ashdod", "email": "ron10@gmail.com", "first name": "ron", "id": "756746783", "last name": "cohen", "phone": "0526732996", "salary": 3000, "type": "manager" }, { "address": "ashdod", "email": "nirlevy120@gmail.com", "first name": "nir", "id": "11884398", "last name": "levy", "phone": "0578198932", "salary": 4500, "type": "manager" } ] )"; void erase1() { try { // Read from input std::istringstream is(input); json instance = json::parse(is); // Locate the item to be erased auto it = std::find_if(instance.array_range().begin(), instance.array_range().end(), [](const json& item){return item.at("id") == std::string("756746783");}); // If found, erase it if (it != instance.array_range().end()) { instance.erase(it); } // Write to output file std::ostringstream os; instance.dump_pretty(os); std::cout << os.str() << "\n\n"; } catch (const std::exception& e) { std::cout << e.what() << '\n'; } } void erase2() { // Read from input file std::istringstream is(input); json instance = json::parse(is); // Select all records except ones with id '756746783' auto result = jsonpath::json_query(instance, "$.*[?(@.id != '756746783')]"); // Write to output file std::ostringstream os; result.dump_pretty(os); std::cout << os.str() << "\n\n"; } void erase3() { try { // Read from input file std::istringstream is(input); json instance = json::parse(is); // Remove first record identified by JSONPointer jsonpointer::remove(instance, "/0"); // Write to output file std::ostringstream os; instance.dump_pretty(os); std::cout << os.str() << "\n\n"; } catch (const std::exception& e) { std::cout << e.what() << '\n'; } } int main() { std::cout << "\nErase\n\n"; erase1(); erase2(); erase3(); std::cout << '\n'; } jsoncons-1.3.2/examples/src/examples.cpp000066400000000000000000000157431477700171100203170ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include using namespace jsoncons; void first_example_a() { std::string path = "./input/books.json"; std::fstream is(path); if (!is) { std::cout << "Cannot open " << path << '\n'; return; } json books = json::parse(is); for (const auto& book : books.at("books").array_range()) { try { std::string author = book["author"].as(); std::string title = book["title"].as(); double price = book["price"].as(); std::cout << author << ", " << title << ", " << price << '\n'; } catch (const std::exception& e) { std::cerr << e.what() << '\n'; } } } void first_example_b() { std::string path = "./input/books.json"; std::fstream is(path); if (!is) { std::cout << "Cannot open " << path << '\n'; return; } json books = json::parse(is); for (const auto& book : books.at("books").array_range()) { try { std::string author = book["author"].as(); std::string title = book["title"].as(); std::string price = book.get_value_or("price", "N/A"); std::cout << author << ", " << title << ", " << price << '\n'; } catch (const std::exception& e) { std::cerr << e.what() << '\n'; } } } void first_example_c() { const json books = json::parse(R"( [ { "title" : "Kafka on the Shore", "author" : "Haruki Murakami", "price" : 25.17 }, { "title" : "Women: A Novel", "author" : "Charles Bukowski", "price" : 12.00 }, { "title" : "Cutter's Way", "author" : "Ivan Passer" } ] )"); auto options = json_options{}; for (const auto& book : books.array_range()) { try { std::string author = book["author"].as(); std::string title = book["title"].as(); std::string price; book.get_value_or("price", "N/A").dump(price,options); std::cout << author << ", " << title << ", " << price << '\n'; } catch (const ser_error& e) { std::cerr << e.what() << '\n'; } } } void first_example_d() { std::string path = "./input/books.json"; std::fstream is(path); if (!is) { std::cout << "Cannot open " << path << '\n'; return; } json books = json::parse(is); auto options = json_options{} .precision(2); for (const auto& book : books.at("books").array_range()) { try { std::string author = book["author"].as(); std::string title = book["title"].as(); if (book.contains("price") && book["price"].is_number()) { double price = book["price"].as(); std::cout << author << ", " << title << ", " << price << '\n'; } else { std::cout << author << ", " << title << ", " << "n/a" << '\n'; } } catch (const std::exception& e) { std::cerr << e.what() << '\n'; } } } void second_example_a() { try { json books(json_array_arg); { json book; book["title"] = "Kafka on the Shore"; book["author"] = "Haruki Murakami"; book["price"] = 25.17; books.push_back(std::move(book)); } { json book; book["title"] = "Women: A Novel"; book["author"] = "Charles Bukowski"; book["price"] = 12.00; books.push_back(std::move(book)); } { json book; book["title"] = "Cutter's Way"; book["author"] = "Ivan Passer"; books.push_back(std::move(book)); } std::cout << pretty_print(books) << '\n'; } catch (const std::exception& e) { std::cerr << e.what() << '\n'; } } void object_range_based_for_loop() { json j = json::parse(R"( { "category" : "Fiction", "title" : "Pulp", "author" : "Charles Bukowski", "date" : "2004-07-08", "price" : 22.48, "isbn" : "1852272007" } )"); for (const auto& member : j.object_range()) { std::cout << member.key() << " => " << member.value().as() << '\n'; } #if defined(JSONCONS_HAS_2017) // or, since 0.176.0, using C++ 17 structured binding for (const auto& [key, value] : j.object_range()) { std::cout << key << " => " << value << '\n'; } #endif } void validation_example() { std::string s = R"( { "StartDate" : "2017-03-01", "MaturityDate" "2020-12-30" } )"; std::stringstream is(s); json_stream_reader reader(is); std::error_code ec; reader.read(ec); if (ec) { std::cout << ec.message() << " on line " << reader.line() << " and column " << reader.column() << '\n'; } } void get_example() { json j = json::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 } ] } )"); // Using index or `at` accessors std::string result1 = j["reputons"][0]["rated"].as(); std::cout << "(1) " << result1 << '\n'; std::string result2 = j.at("reputons").at(0).at("rated").as(); std::cout << "(2) " << result2 << '\n'; // Using JSON Pointer std::string result3 = jsonpointer::get(j, "/reputons/0/rated").as(); std::cout << "(3) " << result3 << '\n'; // Using JSONPath json result4 = jsonpath::json_query(j, "$.reputons.0.rated"); if (result4.size() > 0) { std::cout << "(4) " << result4[0].as() << '\n'; } json result5 = jsonpath::json_query(j, "$..0.rated"); if (result5.size() > 0) { std::cout << "(5) " << result5[0].as() << '\n'; } } int main() { try { std::cout << "jsoncons version: " << version() << '\n'; first_example_a(); first_example_b(); first_example_c(); first_example_d(); second_example_a(); object_range_based_for_loop(); validation_example(); get_example(); } catch (const std::exception& e) { std::cout << e.what() << '\n'; } return 0; } jsoncons-1.3.2/examples/src/free_list_allocator.hpp000066400000000000000000000064271477700171100225210ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #ifndef FREE_LIST_ALLOCATOR_HPP #define FREE_LIST_ALLOCATOR_HPP #include #include #include #include #include #include // From http://coliru.stacked-crooked.com/a/cfd0c5c5021596ad template class free_list_allocator { union node { node* next; alignas(alignof(T)) unsigned char storage[sizeof(T)]; }; node* list = nullptr; void clear() noexcept { auto p = list; while (p) { auto tmp = p; p = p->next; delete tmp; } list = nullptr; } int id_; public: using value_type = T; using size_type = std::size_t; using propagate_on_container_move_assignment = std::true_type; using propagate_on_container_swap = std::true_type; free_list_allocator(int id) noexcept : id_(id) {} free_list_allocator(const free_list_allocator& other) noexcept : id_(other.id_) {} template free_list_allocator(const free_list_allocator& other) noexcept : id_(other.id()) {} free_list_allocator(free_list_allocator&& other) noexcept : id_(other.id_), list(other.list) { other.id_ = -1; other.list = nullptr; } free_list_allocator& operator = (const free_list_allocator& other) = delete; free_list_allocator& operator = (free_list_allocator&& other) noexcept { clear(); id_ = other.id_; list = other.list; other.id_ = -1; other.list = nullptr; return *this; } ~free_list_allocator() noexcept { clear(); } int id() const noexcept { return id_; } friend bool operator==(const free_list_allocator& lhs, const free_list_allocator& rhs) noexcept { return lhs.id_ == rhs.id_; } friend bool operator!=(const free_list_allocator& lhs, const free_list_allocator& rhs) noexcept { return !(lhs == rhs); } T* allocate(size_type n) { //std::cout << "Allocate(" << n << ") from "; if (n == 1) { auto ptr = list; if (ptr) { //std::cout << "freelist\n"; list = list->next; } else { //std::cout << "new node\n"; ptr = new node; } return reinterpret_cast(ptr); } //std::cout << "::operator new\n"; return static_cast(::operator new(n * sizeof(T))); } void deallocate(T* ptr, size_type n) noexcept { //std::cout << "Deallocate(" << static_cast(ptr) << ", " << n << ") to "; if (n == 1) { //std::cout << "freelist\n"; auto node_ptr = reinterpret_cast(ptr); node_ptr->next = list; list = node_ptr; } else { //std::cout << "::operator delete\n"; ::operator delete(ptr); } } template struct rebind { using other = free_list_allocator; }; using pointer = T*; using const_pointer = const T*; using reference = T&; using const_reference = const T&; using difference_type = std::ptrdiff_t; }; #endif jsoncons-1.3.2/examples/src/jmespath_custom_function_examples.cpp000066400000000000000000000145621477700171100255070ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include namespace jmespath = jsoncons::jmespath; // When adding custom functions, they are generally placed in their own project's source code and namespace. namespace myspace { template class my_custom_functions : public jmespath::custom_functions { using reference = const Json&; using pointer = const Json*; static thread_local size_t current_index; public: my_custom_functions() { this->register_function("current_date_time", // function name 0, // number of arguments [](const jsoncons::span> params, jmespath::eval_context& context, std::error_code& ec) -> Json { auto now = std::chrono::system_clock::now(); auto milliseconds = std::chrono::duration_cast(now.time_since_epoch()); return Json{milliseconds.count()}; } ); this->register_function("current_index", // function name 0, // number of arguments [](const jsoncons::span> params, jmespath::eval_context& context, std::error_code& ec) -> Json { return Json{current_index}; } ); this->register_function("generate_array", // function name 4, // number of arguments [](const jsoncons::span> params, jmespath::eval_context& context, std::error_code& ec) -> Json { JSONCONS_ASSERT(4 == params.size()); if (!(params[0].is_value() && params[2].is_expression())) { ec = jmespath::jmespath_errc::invalid_argument; return context.null_value(); } reference ctx = params[0].value(); reference countValue = get_value(ctx, context, params[1]); const auto& expr = params[2].expression(); const auto& argDefault = params[3]; if (!countValue.is_number()) { ec = jmespath::jmespath_errc::invalid_argument; return context.null_value(); } Json result{jsoncons::json_array_arg}; int count = countValue.template as(); for (size_t i = 0; i < count; i++) { current_index = i; std::error_code ec2; reference ele = expr.evaluate(ctx, context, ec2); if (ele.is_null()) { auto defaultVal = get_value(ctx, context, argDefault); result.emplace_back(std::move(defaultVal)); } else { result.emplace_back(ele); } } current_index = 0; return result; } ); this->register_function("add", // function name 2, // number of arguments [](jsoncons::span> params, jmespath::eval_context& context, std::error_code& ec) -> Json { JSONCONS_ASSERT(2 == params.size()); if (!(params[0].is_value() && params[1].is_value())) { ec = jmespath::jmespath_errc::invalid_argument; return context.null_value(); } reference arg0 = params[0].value(); reference arg1 = params[1].value(); if (!(arg0.is_number() && arg1.is_number())) { ec = jmespath::jmespath_errc::invalid_argument; return context.null_value(); } if (arg0.is() && arg1.is()) { int64_t v = arg0.template as() + arg1.template as(); return Json(v); } else { double v = arg0.template as() + arg1.template as(); return Json(v); } } ); } static reference get_value(reference ctx, jmespath::eval_context& context, const jmespath::parameter& param) { if (param.is_expression()) { const auto& expr = param.expression(); std::error_code ec; return expr.evaluate(ctx, context, ec); } else { return param.value(); } } }; template thread_local size_t my_custom_functions::current_index = 0; } // namespace myspace using json = jsoncons::json; void jmespath_custom_function_example() { std::string jtext = R"( { "devices": [ { "position": 1, "id": "id-xxx", "state": 1 }, { "position": 5, "id": "id-yyy", "state": 1 }, { "position": 9, "id": "id-mmm", "state": 2 } ] } )"; auto expr = jmespath::make_expression("generate_array(devices, `16`, &[?position==add(current_index(), `1`)] | [0], &{id: '', state: `0`, position: add(current_index(), `1`)})", myspace::my_custom_functions{}); auto doc = json::parse(jtext); auto result = expr.evaluate(doc); auto options = jsoncons::json_options{} .array_object_line_splits(jsoncons::line_split_kind::same_line); std::cout << pretty_print(result, options) << "\n\n"; } int main() { std::cout << "\nJMESPath customer functions examples\n\n"; jmespath_custom_function_example(); std::cout << "\n"; } jsoncons-1.3.2/examples/src/jmespath_examples.cpp000066400000000000000000000104441477700171100222030ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include // for brevity using jsoncons::json; namespace jmespath = jsoncons::jmespath; void search_example() { std::string jtext = R"( { "locations": [ {"name": "Seattle", "state": "WA"}, {"name": "New York", "state": "NY"}, {"name": "Bellevue", "state": "WA"}, {"name": "Olympia", "state": "WA"} ] } )"; std::string expr = "locations[?state == 'WA'].name | sort(@) | {WashingtonCities: join(', ', @)}"; json doc = json::parse(jtext); json result = jmespath::search(doc, expr); std::cout << pretty_print(result) << "\n\n"; } void jmespath_expression_example() { std::string jtext = R"( { "people": [ { "age": 20, "other": "foo", "name": "Bob" }, { "age": 25, "other": "bar", "name": "Fred" }, { "age": 30, "other": "baz", "name": "George" } ] } )"; auto expr = jmespath::make_expression("people[?age > `20`].[name, age]"); json doc = json::parse(jtext); json result = expr.evaluate(doc); std::cout << pretty_print(result) << "\n\n"; } void let_example() { auto doc = json::parse(R"( [ {"home_state": "WA", "states": [ {"name": "WA", "cities": ["Seattle", "Bellevue", "Olympia"]}, {"name": "CA", "cities": ["Los Angeles", "San Francisco"]}, {"name": "NY", "cities": ["New York City", "Albany"]} ] }, {"home_state": "NY", "states": [ {"name": "WA", "cities": ["Seattle", "Bellevue", "Olympia"]}, {"name": "CA", "cities": ["Los Angeles", "San Francisco"]}, {"name": "NY", "cities": ["New York City", "Albany"]} ] } ] )"); std::string query = R"([*].[let $home_state = home_state in states[? name == $home_state].cities[]][])"; auto expr = jmespath::make_expression(query); json result = expr.evaluate(doc); auto options = jsoncons::json_options{} .array_array_line_splits(jsoncons::line_split_kind::same_line); std::cout << pretty_print(result, options) << "\n"; } void expression_with_params_example() // since 1.3.0 { auto doc = json::parse(R"( { "results": [ { "name": "test1", "uuid": "33bb9554-c616-42e6-a9c6-88d3bba4221c" }, { "name": "test2", "uuid": "acde070d-8c4c-4f0d-9d8a-162843c10333" } ] } )"); auto expr = jmespath::make_expression("results[*].[name, uuid, $hostname]"); std::map params = {{"hostname", "localhost"}}; auto result = expr.evaluate(doc, params); auto options = jsoncons::json_options{} .array_array_line_splits(jsoncons::line_split_kind::same_line); std::cout << pretty_print(result) << "\n"; } #if defined(_MSC_VER) #include #include // microsoft PPL library void query_json_lines_in_parallel() { std::vector lines = { { R"({"name": "Seattle", "state" : "WA"})", R"({ "name": "New York", "state" : "NY" })", R"({ "name": "Bellevue", "state" : "WA" })", R"({ "name": "Olympia", "state" : "WA" })" } }; auto expr = jsoncons::jmespath::make_expression( R"([@][?state=='WA'].name)"); concurrency::concurrent_vector result; auto f = [&](const std::string& line) { const auto j = jsoncons::json::parse(line); const auto r = expr.evaluate(j); if (!r.empty()) result.push_back(r.at(0).as()); }; std::for_each(std::execution::par, lines.begin(), lines.end(), f); for (const auto& s : result) { std::cout << s << "\n"; } } #endif int main() { std::cout << "\nJMESPath examples\n\n"; search_example(); jmespath_expression_example(); let_example(); expression_with_params_example(); #if defined(_MSC_VER) query_json_lines_in_parallel(); #endif std::cout << "\n"; } jsoncons-1.3.2/examples/src/json_accessor_examples.cpp000066400000000000000000000124071477700171100232240ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include using namespace jsoncons; void is_as_examples() { json j = json::parse(R"( { "k1" : 2147483647, "k2" : 2147483648, "k3" : -10, "k4" : 10.5, "k5" : true, "k6" : "10.5" } )"); std::cout << std::boolalpha << "(1) " << j["k1"].is() << '\n'; std::cout << std::boolalpha << "(2) " << j["k2"].is() << '\n'; std::cout << std::boolalpha << "(3) " << j["k2"].is() << '\n'; std::cout << std::boolalpha << "(4) " << j["k3"].is() << '\n'; std::cout << std::boolalpha << "(5) " << j["k3"].is() << '\n'; std::cout << std::boolalpha << "(6) " << j["k4"].is() << '\n'; std::cout << std::boolalpha << "(7) " << j["k4"].is() << '\n'; std::cout << std::boolalpha << "(8) " << j["k5"].is() << '\n'; std::cout << std::boolalpha << "(9) " << j["k5"].is() << '\n'; std::cout << std::boolalpha << "(10) " << j["k6"].is() << '\n'; std::cout << '\n'; std::cout << "(1) " << j["k1"].as() << '\n'; std::cout << "(2) " << j["k2"].as() << '\n'; std::cout << "(3) " << j["k2"].as() << '\n'; std::cout << "(4) " << j["k3"].as() << '\n'; std::cout << "(5) " << j["k3"].as() << '\n'; std::cout << "(6) " << j["k4"].as() << '\n'; std::cout << "(7) " << j["k4"].as() << '\n'; std::cout << std::boolalpha << "(8) " << j["k5"].as() << '\n'; std::cout << std::boolalpha << "(9) " << j["k5"].as() << '\n'; std::cout << "(10) " << j["k6"].as() << '\n'; } void byte_string_from_initializer_list() { json j(byte_string{'H','e','l','l','o'}); byte_string bytes = j.as(); std::cout << "(1) "<< bytes << "\n\n"; std::cout << "(2) "; for (auto b : bytes) { std::cout << (char)b; } std::cout << "\n\n"; std::cout << "(3) " << j << '\n'; } void byte_string_from_char_array() { std::vector u = {'H','e','l','l','o'}; json j(byte_string_arg, u, semantic_tag::base64); auto bytes = j.as>(); std::cout << "(1) "; for (auto b : bytes) { std::cout << (char)b; } std::cout << "\n\n"; std::string s; encode_json(j, s); // tag information is lost std::cout << "(2) " << s << "\n\n"; auto sj = decode_json(s); // provide hint auto v = sj.as>(byte_string_arg, semantic_tag::base64); assert(v == u); } void introspection_example() { std::string path = "./input/books.json"; std::fstream is(path); if (!is) { std::cout << "Cannot open " << path << '\n'; return; } json val = json::parse(is); std::cout << std::boolalpha; std::cout << "Is this an object? " << val.is_object() << ", or an array? " << val.is_array() << '\n'; if (val.at("books").is_array()) { std::size_t index = 0; for (const auto& book : val.at("books").array_range()) { std::cout << "Is element " << index++ << " an object? " << book.is_object() << '\n'; if (book.is_object()) { for (auto it = book.object_range().begin(); it != book.object_range().end(); ++it){ std::cout << "Is member " << it->key() << " a string? " << it->value().is() << ", or a double? " << it->value().is() << ", or perhaps an int? " << it->value().is() << '\n'; } } } } } void operator_at_examples() { json image_formats(json_array_arg, {"JPEG","PSD","TIFF","DNG"}); json color_spaces(json_array_arg); color_spaces.push_back("sRGB"); color_spaces.push_back("AdobeRGB"); color_spaces.push_back("ProPhoto RGB"); json export_settings; export_settings["File Format Options"]["Color Spaces"] = std::move(color_spaces); export_settings["File Format Options"]["Image Formats"] = std::move(image_formats); std::cout << pretty_print(export_settings) << "\n\n"; } void return_value_null_or_default_example() { json j(json_object_arg, {{"author","Evelyn Waugh"},{"title","Sword of Honour"}}); std::cout << "(1) " << j.at_or_null("author").as() << "\n"; std::cout << "(2) " << j.at_or_null("title").as() << "\n"; std::cout << "(3) " << j.at_or_null("category").as() << "\n"; std::cout << "(4) " << j.get_value_or("category","fiction") << "\n"; } void reverse_object_iterator() { ojson j; j["city"] = "Toronto"; j["province"] = "Ontario"; j["country"] = "Canada"; for (auto it = j.object_range().crbegin(); it != j.object_range().crend(); ++it) { std::cout << it->key() << " => " << it->value().as() << '\n'; } std::cout << "\n"; } int main() { is_as_examples(); introspection_example(); byte_string_from_initializer_list(); operator_at_examples(); return_value_null_or_default_example(); byte_string_from_char_array(); reverse_object_iterator(); } jsoncons-1.3.2/examples/src/json_constructor_examples.cpp000066400000000000000000000063301477700171100240050ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include using namespace jsoncons; void constructor_examples() { json j1; // An empty object std::cout << "(1) " << j1 << "\n"; json j2(json_object_arg, {{"baz", "qux"}, {"foo", "bar"}}); // An object std::cout << "(2) " << j2 << "\n"; json j3(json_array_arg, {"bar", "baz"}); // An array std::cout << "(3) " << j3 << "\n"; json j4(json::null()); // A null value std::cout << "(4) " << j4 << "\n"; json j5(true); // A boolean value std::cout << "(5) " << j5 << "\n"; double x = 1.0/7.0; json j6(x); // A double value std::cout << "(6) " << j6 << "\n"; json j8("Hello"); // A text string std::cout << "(8) " << j8 << "\n"; std::vector v = {10,20,30}; json j9 = v; // From a sequence container std::cout << "(9) " << j9 << "\n"; std::map m{ {"one", 1}, {"two", 2}, {"three", 3} }; json j10 = m; // From an associative container std::cout << "(10) " << j10 << "\n"; std::vector bytes = {'H','e','l','l','o'}; json j11(byte_string_arg, bytes); // A byte string std::cout << "(11) " << j11 << "\n"; json j12(half_arg, 0x3bff); std::cout << "(12) " << j12.as_double() << "\n"; // An object value with four members json obj; obj["first_name"] = "Jane"; obj["last_name"] = "Roe"; obj["events_attended"] = 10; obj["accept_waiver_of_liability"] = true; std::string first_name = obj["first_name"].as(); std::string last_name = obj.at("last_name").as(); int events_attended = obj["events_attended"].as(); bool accept_waiver_of_liability = obj["accept_waiver_of_liability"].as(); // An array value with four elements json arr(json_array_arg); arr.push_back(j1); arr.push_back(j2); arr.push_back(j3); arr.push_back(j4); std::cout << pretty_print(arr) << "\n\n"; } void json_const_pointer_arg_example() { std::string input = R"( { "machines": [ {"id": 1, "state": "running"}, {"id": 2, "state": "stopped"}, {"id": 3, "state": "running"} ] } )"; json j = json::parse(input); json j_v(json_array_arg); for (const auto& item : j.at("machines").array_range()) { if (item.at("state").as() == "running") { j_v.emplace_back(json_const_pointer_arg, &item); } } std::cout << "\n(1)\n" << pretty_print(j_v) << "\n\n"; for (const auto& item : j_v.array_range()) { std::cout << "json type: " << item.type() << ", storage kind: " << item.storage_kind() << "\n"; } json j2 = deep_copy(j_v); std::cout << "\n(2)\n" << pretty_print(j2) << "\n\n"; for (const auto& item : j2.array_range()) { std::cout << "json type: " << item.type() << ", storage kind: " << item.storage_kind() << "\n"; } } int main() { constructor_examples(); json_const_pointer_arg_example(); } jsoncons-1.3.2/examples/src/json_cursor_examples.cpp000066400000000000000000000156221477700171100227410ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include // json_decoder and json #include #include #include using namespace jsoncons; namespace { namespace ns { struct book { std::string author; std::string title; double price; }; } // namespace ns } // namespace JSONCONS_ALL_MEMBER_TRAITS(ns::book,author,title,price) // Create some JSON (push) void create_some_json() { std::ofstream os("./output/book_catalog.json", std::ios_base::out | std::ios_base::trunc); assert(os); compact_json_stream_encoder encoder(os); // no indent encoder.begin_array(); encoder.begin_object(); encoder.key("author"); encoder.string_value("Haruki Murakami"); encoder.key("title"); encoder.string_value("Hard-Boiled Wonderland and the End of the World"); encoder.key("price"); encoder.double_value(18.9); encoder.end_object(); encoder.begin_object(); encoder.key("author"); encoder.string_value("Graham Greene"); encoder.key("title"); encoder.string_value("The Comedians"); encoder.key("price"); encoder.double_value(15.74); encoder.end_object(); encoder.end_array(); encoder.flush(); os.close(); // Read the JSON and write it prettified to std::cout json_stream_encoder writer(std::cout); // indent std::ifstream is("./output/book_catalog.json"); assert(is); json_stream_reader reader(is, writer); reader.read(); std::cout << "\n\n"; } // Read some JSON (pull) // In the example, the application pulls the next event in the // JSON input stream by calling next(). void read_json_parse_events() { std::ifstream is("./output/book_catalog.json"); assert(is); json_stream_cursor cursor(is); for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::end_array: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::begin_object: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::end_object: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::key: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::string_value: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::null_value: std::cout << event.event_type() << "\n"; break; case staj_event_type::bool_value: std::cout << event.event_type() << ": " << std::boolalpha << event.get() << "\n"; break; case staj_event_type::int64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::double_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; default: std::cout << "Unhandled event type: " << event.event_type() << " " << "\n"; break; } } } // Filtering the stream void filtering_a_json_stream() { bool author_next = false; auto filter = [&](const staj_event& event, const ser_context&) -> bool { if (event.event_type() == staj_event_type::key && event.get() == "author") { author_next = true; return false; } if (author_next) { author_next = false; return true; } return false; }; std::ifstream is("./output/book_catalog.json"); assert(is); json_stream_cursor cursor(is); auto filtered_c = cursor | filter; for (; !filtered_c.done(); filtered_c.next()) { const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::string_value: std::cout << event.get() << "\n"; break; default: std::cout << "Unhandled event type: " << event.event_type() << " " << "\n"; break; } } } void read_nested_objects_to_basic_json() { std::ifstream is("./output/book_catalog.json"); assert(is); json_stream_cursor cursor(is); json_decoder decoder; for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: { std::cout << event.event_type() << " " << "\n"; break; } case staj_event_type::end_array: { std::cout << event.event_type() << " " << "\n"; break; } case staj_event_type::begin_object: { std::cout << event.event_type() << " " << "\n"; cursor.read_to(decoder); json j = decoder.get_result(); std::cout << pretty_print(j) << "\n"; break; } default: { std::cout << "Unhandled event type: " << event.event_type() << " " << "\n"; break; } } } } void iterate_over_complete_objects1() { std::ifstream is("./output/book_catalog.json"); assert(is); json_stream_cursor cursor(is); auto view = staj_array(cursor); for (const auto& j : view) { std::cout << pretty_print(j) << "\n"; } } void iterate_over_complete_objects2() { std::ifstream is("./output/book_catalog.json"); assert(is); json_stream_cursor cursor(is); auto view = staj_array(cursor); for (const auto& book : view) { std::cout << book.author << ", " << book.title << "\n"; } } int main() { std::cout << "\njson_cursor examples\n\n"; std::cout << "\n"; create_some_json(); read_json_parse_events(); filtering_a_json_stream(); read_nested_objects_to_basic_json(); iterate_over_complete_objects1(); iterate_over_complete_objects2(); std::cout << "\n"; } jsoncons-1.3.2/examples/src/json_filter_examples.cpp000066400000000000000000000066271477700171100227160ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include using namespace jsoncons; class name_fixup_filter : public json_filter { public: name_fixup_filter(json_visitor& visitor) : json_filter(visitor) { } private: bool visit_key(const string_view_type& name, const ser_context& context, std::error_code&) override { member_name_ = std::string(name); if (member_name_ != "name") { this->destination().key(name, context); } return true; } bool visit_string(const string_view_type& s, semantic_tag tag, const ser_context& context, std::error_code&) override { if (member_name_ == "name") { std::size_t end_first = s.find_first_of(" \t"); std::size_t start_last = s.find_first_not_of(" \t", end_first); this->destination().key("first-name", context); string_view_type first = s.substr(0, end_first); this->destination().string_value(first, tag, context); if (start_last != string_view_type::npos) { this->destination().key("last-name", context); string_view_type last = s.substr(start_last); this->destination().string_value(last, tag, context); } else { std::cerr << "Incomplete name \"" << s << "\" at line " << context.line() << " and column " << context.column() << '\n'; } } else { this->destination().string_value(s, tag, context); } return true; } std::string member_name_; }; void name_fixup_example1() { std::string in_file = "./input/address-book.json"; std::string out_file = "./output/new-address-book1.json"; std::ifstream is(in_file); std::ofstream os(out_file); json_stream_encoder encoder(os); name_fixup_filter filter(encoder); json_stream_reader reader(is, filter); reader.read_next(); } void name_fixup_example2() { std::string in_file = "./input/address-book.json"; std::string out_file = "./output/new-address-book2.json"; std::ifstream is(in_file); std::ofstream os(out_file); json j; is >> j; json_stream_encoder encoder(os); name_fixup_filter filter(encoder); j.dump(filter); } void change_member_name_example() { std::string s = R"({"first":1,"second":2,"fourth":3,"fifth":4})"; json_stream_encoder encoder(std::cout); // Filters can be chained rename_object_key_filter filter2("fifth", "fourth", encoder); rename_object_key_filter filter1("fourth", "third", filter2); // A filter can be passed to any function that takes // a json_visitor ... std::cout << "(1) "; std::istringstream is(s); json_stream_reader reader(is, filter1); reader.read(); std::cout << '\n'; // or a json_visitor std::cout << "(2) "; ojson j = ojson::parse(s); j.dump(filter1); std::cout << '\n'; } int main() { std::cout << "\njson_filter examples\n\n"; name_fixup_example1(); name_fixup_example2(); change_member_name_example(); std::cout << '\n'; } jsoncons-1.3.2/examples/src/json_merge_patch_examples.cpp000066400000000000000000000037231477700171100237010ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include using jsoncons::json; namespace mergepatch = jsoncons::mergepatch; void apply_json_merge_patch() { // Apply a JSON Patch json doc = json::parse(R"( { "title": "Goodbye!", "author" : { "givenName" : "John", "familyName" : "Doe" }, "tags":[ "example", "sample" ], "content": "This will be unchanged" } )"); json doc2 = doc; json patch = json::parse(R"( { "title": "Hello!", "phoneNumber": "+01-123-456-7890", "author": { "familyName": null }, "tags": [ "example" ] } )"); mergepatch::apply_merge_patch(doc, patch); std::cout << "(1)\n" << pretty_print(doc) << '\n'; // Create a JSON Patch auto patch2 = mergepatch::from_diff(doc2,doc); std::cout << "(2)\n" << pretty_print(patch2) << '\n'; mergepatch::apply_merge_patch(doc2,patch2); std::cout << "(3)\n" << pretty_print(doc2) << '\n'; } void create_json_merge_patch() { json source = json::parse(R"( { "title": "Goodbye!", "author" : { "givenName" : "John", "familyName" : "Doe" }, "tags":[ "example", "sample" ], "content": "This will be unchanged" } )"); json target = json::parse(R"( { "title": "Hello!", "author": { "givenName": "John" }, "tags": [ "example" ], "content": "This will be unchanged", "phoneNumber": "\u002B01-123-456-7890" } )"); auto patch = mergepatch::from_diff(source, target); mergepatch::apply_merge_patch(source, patch); std::cout << "(1)\n" << pretty_print(patch) << '\n'; std::cout << "(2)\n" << pretty_print(source) << '\n'; } int main() { std::cout << "\njson_merge_patch examples\n\n"; create_json_merge_patch(); apply_json_merge_patch(); std::cout << '\n'; } jsoncons-1.3.2/examples/src/json_parse_examples.cpp000066400000000000000000000067401477700171100225370ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include using namespace jsoncons; void parse_with_comment() { std::string s = R"( { // Single line comments /* Multi line comments */ } )"; // Default { auto j = json::parse(s); std::cout << "(1) " << j << '\n'; } // Strict try { // until 0.170.0 auto j1 = json::parse(s, strict_json_parsing()); // since 0.171.0 auto options = json_options{} .err_handler(strict_json_parsing()); auto j2 = json::parse(s, options); // since 1.3.0 auto options = json_options{} .allow_comments(false); auto j3 = json::parse(s, options); } catch (const ser_error& e) { std::cout << "(2) " << e.what() << '\n'; } } void parse_with_trailing_commas() { std::string s = R"( { "first" : 1, "second" : 2, } )"; // Default try { auto j = json::parse(s); } catch (const ser_error& e) { std::cout << "(1) " << e.what() << "\n\n"; } // Allow trailing commas // until 0.170.0 // auto j = json::parse(s, allow_trailing_commas()); // since 0.170.0 // auto options = json_options{} // .err_handler(allow_trailing_commas()); // auto j = json::parse(s, options); // since 1.3.0 auto options = json_options{} .allow_trailing_comma(true); auto j = json::parse(s, options); std::cout << "(2) " << j << "\n\n"; } void parse_error_example() { std::string s = "[1,2,3,4,]"; try { json val = json::parse(s); } catch(const ser_error& e) { std::cout << "Caught ser_error with category " << e.code().category().name() << ", code " << e.code().value() << " and message " << e.what() << '\n'; } } void max_nesting_path_example() { std::string s = "[[[[[[[[[[[[[[[[[[[[[\"Too deep\"]]]]]]]]]]]]]]]]]]]]]"; try { auto options = json_options{} .max_nesting_depth(20); json::parse(s, options); } catch (const ser_error& e) { std::cout << e.what() << '\n'; } } #if defined(JSONCONS_HAS_POLYMORPHIC_ALLOCATOR) && JSONCONS_HAS_POLYMORPHIC_ALLOCATOR == 1 #include // since 0.171.0 void using_polymorphic_allocator() { using pmr_json = pmr::json; char buffer[1024] = {}; // a small buffer on the stack std::pmr::monotonic_buffer_resource pool{std::data(buffer), std::size(buffer)}; std::pmr::polymorphic_allocator alloc(&pool); std::string json_text = R"( { "street_number" : "100", "street_name" : "Queen St W", "city" : "Toronto", "country" : "Canada" } )"; try { auto doc = pmr_json::parse(combine_allocators(alloc), json_text, json_options{}); std::cout << pretty_print(doc) << "\n\n"; } catch (const std::exception& ex) { std::cerr << ex.what() << '\n'; } } #endif int main() { try { std::cout << "jsoncons version: " << version() << '\n'; parse_error_example(); parse_with_comment(); max_nesting_path_example(); using_polymorphic_allocator(); parse_with_trailing_commas(); } catch (const std::exception& e) { std::cout << e.what() << '\n'; } return 0; } jsoncons-1.3.2/examples/src/json_parser_examples.cpp000066400000000000000000000053341477700171100227170ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include void incremental_parsing_example() { jsoncons::json_decoder decoder; jsoncons::json_parser parser; try { parser.update("[fal"); parser.parse_some(decoder); std::cout << "(1) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n"; parser.update("se,"); parser.parse_some(decoder); std::cout << "(2) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n"; parser.update("9"); parser.parse_some(decoder); std::cout << "(3) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n"; parser.update("0]"); parser.parse_some(decoder); std::cout << "(4) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n"; parser.finish_parse(decoder); std::cout << "(5) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n"; parser.check_done(); std::cout << "(6) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n"; jsoncons::json j = decoder.get_result(); std::cout << "(7) " << j << "\n\n"; } catch (const jsoncons::ser_error& e) { std::cout << e.what() << '\n'; } } void parse_nan_replacement_example() { std::string s = R"( { "A" : "NaN", "B" : "Infinity", "C" : "-Infinity" } )"; auto options = jsoncons::json_options{} .nan_to_str("NaN") .inf_to_str("Infinity"); jsoncons::json_decoder decoder; jsoncons::json_parser parser(options); try { parser.update(s.data(), s.size()); // since 1.0.0 parser.parse_some(decoder); parser.finish_parse(decoder); parser.check_done(); } catch (const jsoncons::ser_error& e) { std::cout << e.what() << '\n'; } jsoncons::json j = decoder.get_result(); // performs move if (j["A"].is()) { std::cout << "A: " << j["A"].as() << '\n'; } if (j["B"].is()) { std::cout << "B: " << j["B"].as() << '\n'; } if (j["C"].is()) { std::cout << "C: " << j["C"].as() << '\n'; } } int main() { std::cout << "\njson_parser examples\n\n"; incremental_parsing_example(); parse_nan_replacement_example(); std::cout << '\n'; } jsoncons-1.3.2/examples/src/json_reader_examples.cpp000066400000000000000000000074421477700171100226670ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include "free_list_allocator.hpp" #include using namespace jsoncons; template using MyScopedAllocator = std::scoped_allocator_adaptor>; class MyIterator { const char* p_; public: using iterator_category = std::input_iterator_tag; using value_type = char; using difference_type = std::ptrdiff_t; using pointer = const char*; using reference = const char&; MyIterator(const char* p) : p_(p) { } reference operator*() const { return *p_; } pointer operator->() const { return p_; } MyIterator& operator++() { ++p_; return *this; } MyIterator operator++(int) { MyIterator temp(*this); ++*this; return temp; } bool operator!=(const MyIterator& rhs) const { return p_ != rhs.p_; } }; void custom_iterator_source() { char source[] = {'[','\"', 'f','o','o','\"',',','\"', 'b','a','r','\"',']'}; MyIterator first(source); MyIterator last(source + sizeof(source)); json j = json::parse(first, last); std::cout << j << "\n\n"; } void read_mulitple_json_objects() { std::ifstream is("./input/multiple-json-objects.json"); if (!is.is_open()) { throw std::runtime_error("Cannot open file"); } json_decoder decoder; json_stream_reader reader(is, decoder); while (!reader.eof()) { reader.read_next(); // until 1.0.0 //if (!reader.eof()) //{ // json j = decoder.get_result(); // std::cout << j << '\n'; //} // since 1.0.0 json j = decoder.get_result(); std::cout << j << '\n'; } } // https://jsonlines.org/ void read_json_lines() { std::string data = R"( ["Name", "Session", "Score", "Completed"] ["Gilbert", "2013", 24, true] ["Alexa", "2013", 29, true] ["May", "2012B", 14, false] ["Deloise", "2012A", 19, true] )"; std::stringstream is(data); json_decoder decoder; json_stream_reader reader(is, decoder); while (!reader.eof()) { reader.read_next(); if (!reader.eof()) { json j = decoder.get_result(); std::cout << j << '\n'; } } } void read_with_stateful_allocator() { using cust_json = basic_json>; std::string input = R"( [ { "author" : "Haruki Murakami", "title" : "Hard-Boiled Wonderland and the End of the World", "isbn" : "0679743464", "publisher" : "Vintage", "date" : "1993-03-02", "price": 18.90 }, { "author" : "Graham Greene", "title" : "The Comedians", "isbn" : "0099478374", "publisher" : "Vintage Classics", "date" : "2005-09-21", "price": 15.74 } ] )"; // Until 0.171.0 //json_decoder> decoder(result_allocator_arg, MyScopedAllocator(1), // MyScopedAllocator(2)); // Since 0.171.0 json_decoder> decoder(MyScopedAllocator(1), MyScopedAllocator(2)); auto myAlloc = MyScopedAllocator(3); basic_json_reader, MyScopedAllocator> reader(input, decoder, myAlloc); reader.read(); cust_json j = decoder.get_result(); std::cout << pretty_print(j) << "\n"; } int main() { std::cout << "\njson_reader examples\n\n"; //read_mulitple_json_objects(); //read_with_stateful_allocator(); //custom_iterator_source(); read_json_lines(); } jsoncons-1.3.2/examples/src/json_traits_bitset_examples.cpp000066400000000000000000000017141477700171100243010ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include using namespace jsoncons; void json_example() { std::bitset<70> bs1(ULLONG_MAX); std::string s; encode_json(bs1, s); std::cout << s << "\n\n"; auto bs2 = decode_json>(s); assert(bs2 == bs1); } void cbor_example() { std::bitset<8> bs1(42); std::vector data; cbor::encode_cbor(bs1, data); std::cout << byte_string_view(data) << "\n\n"; /* 0xd7, // Expected conversion to base16 0x41, // Byte string value of length 1 0x54 */ auto bs2 = cbor::decode_cbor>(data); assert(bs2 == bs1); } int main() { std::cout << "\njson traits bitset examples\n\n"; json_example(); cbor_example(); std::cout << '\n'; } jsoncons-1.3.2/examples/src/json_traits_integer_examples.cpp000066400000000000000000000016551477700171100244500ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #include #include #include using namespace jsoncons; #if (defined(__GNUC__) || defined(__clang__)) && defined(JSONCONS_HAS_INT128) void int128_example() { json j1("-18446744073709551617", semantic_tag::bigint); std::cout << j1 << "\n\n"; __int128 val = j1.as<__int128>(); json j2(val); assert(j2 == j1); } #endif int main() { std::cout << "\njson traits integer examples\n\n"; #if (defined(__GNUC__) || defined(__clang__)) && defined(JSONCONS_HAS_INT128) int128_example(); #endif std::cout << '\n'; } jsoncons-1.3.2/examples/src/json_traits_macros_examples.cpp000066400000000000000000000323031477700171100242710ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include namespace { namespace ns { class Foo { public: virtual ~Foo() noexcept = default; }; class Bar : public Foo { static const bool bar = true; JSONCONS_TYPE_TRAITS_FRIEND }; class Baz : public Foo { static const bool baz = true; JSONCONS_TYPE_TRAITS_FRIEND }; enum class BookCategory {fiction,biography}; inline std::ostream& operator<<(std::ostream& os, const BookCategory& category) { switch (category) { case BookCategory::fiction: os << "fiction, "; break; case BookCategory::biography: os << "biography, "; break; } return os; } // #1 Class with public member data and default constructor struct Book1 { BookCategory category; std::string author; std::string title; double price; }; // #2 Class with private member data and default constructor class Book2 { BookCategory category; std::string author; std::string title; double price; Book2() = default; JSONCONS_TYPE_TRAITS_FRIEND public: BookCategory get_category() const {return category;} const std::string& get_author() const {return author;} const std::string& get_title() const{return title;} double get_price() const{return price;} }; // #3 Class with getters and initializing constructor class Book3 { BookCategory category_; std::string author_; std::string title_; double price_; public: Book3(BookCategory category, const std::string& author, const std::string& title, double price) : category_(category), author_(author), title_(title), price_(price) { } BookCategory category() const {return category_;} const std::string& author() const{return author_;} const std::string& title() const{return title_;} double price() const{return price_;} }; // #4 Class with getters and setters class Book4 { BookCategory category_; std::string author_; std::string title_; double price_; public: Book4() : category_(), price_(0) { } Book4(BookCategory category, const std::string& author, const std::string& title, double price) : category_(category), author_(author), title_(title), price_(price) { } BookCategory get_category() const { return category_; } void set_category(BookCategory value) { category_ = value; } const std::string& get_author() const { return author_; } void set_author(const std::string& value) { author_ = value; } const std::string& get_title() const { return title_; } void set_title(const std::string& value) { title_ = value; } double get_price() const { return price_; } void set_price(double value) { price_ = value; } }; class Employee { std::string firstName_; std::string lastName_; public: Employee(const std::string& firstName, const std::string& lastName) : firstName_(firstName), lastName_(lastName) { } virtual ~Employee() noexcept = default; virtual double calculatePay() const = 0; const std::string& firstName() const {return firstName_;} const std::string& lastName() const {return lastName_;} }; class HourlyEmployee : public Employee { double wage_; unsigned hours_; public: HourlyEmployee(const std::string& firstName, const std::string& lastName, double wage, unsigned hours) : Employee(firstName, lastName), wage_(wage), hours_(hours) { } double wage() const {return wage_;} unsigned hours() const {return hours_;} double calculatePay() const override { return wage_*hours_; } }; class CommissionedEmployee : public Employee { double baseSalary_; double commission_; unsigned sales_; public: CommissionedEmployee(const std::string& firstName, const std::string& lastName, double baseSalary, double commission, unsigned sales) : Employee(firstName, lastName), baseSalary_(baseSalary), commission_(commission), sales_(sales) { } double baseSalary() const { return baseSalary_; } double commission() const { return commission_; } unsigned sales() const { return sales_; } double calculatePay() const override { return baseSalary_ + commission_*sales_; } }; struct smart_pointer_test { std::shared_ptr field1; std::unique_ptr field2; std::shared_ptr field3; std::unique_ptr field4; std::shared_ptr field5; std::unique_ptr field6; std::shared_ptr field7; std::unique_ptr field8; }; #if defined(JSONCONS_HAS_STD_OPTIONAL) class MetaDataReplyTest { public: MetaDataReplyTest() : description() { } const std::string& GetStatus() const { return status; } const std::string& GetPayload() const { return payload; } const std::optional& GetDescription() const { return description; } private: JSONCONS_TYPE_TRAITS_FRIEND std::string status; std::string payload; std::optional description; }; #endif } // namespace ns } // namespace // Declare the traits at global scope JSONCONS_ENUM_TRAITS(ns::BookCategory,fiction,biography) JSONCONS_ALL_MEMBER_TRAITS(ns::Book1,category,author,title,price) JSONCONS_ALL_MEMBER_TRAITS(ns::Book2,category,author,title,price) JSONCONS_ALL_CTOR_GETTER_TRAITS(ns::Book3,category,author,title,price) JSONCONS_ALL_GETTER_SETTER_TRAITS(ns::Book4,get_,set_,category,author,title,price) JSONCONS_N_CTOR_GETTER_TRAITS(ns::HourlyEmployee, 3, firstName, lastName, wage, hours) JSONCONS_N_CTOR_GETTER_TRAITS(ns::CommissionedEmployee, 4, firstName, lastName, baseSalary, commission, sales) JSONCONS_POLYMORPHIC_TRAITS(ns::Employee, ns::HourlyEmployee, ns::CommissionedEmployee) JSONCONS_N_MEMBER_TRAITS(ns::Bar,1,bar) JSONCONS_N_MEMBER_TRAITS(ns::Baz,1,baz) JSONCONS_POLYMORPHIC_TRAITS(ns::Foo, ns::Bar, ns::Baz) #if defined(JSONCONS_HAS_STD_OPTIONAL) JSONCONS_N_MEMBER_TRAITS(ns::MetaDataReplyTest, 2, status, payload, description) #endif // Declare the traits, first 4 members mandatory, last 4 non-mandatory JSONCONS_N_MEMBER_TRAITS(ns::smart_pointer_test,4,field1,field2,field3,field4,field5,field6,field7,field8) using namespace jsoncons; #if defined(JSONCONS_HAS_STD_OPTIONAL) void json_type_traits_optional_examples() { std::string input1 = R"({ "status": "OK", "payload": "Modified", "description": "TEST" })"; std::string input2 = R"({ "status": "OK", "payload": "Modified" })"; auto val1 = decode_json(input1); assert(val1.GetStatus() == "OK"); assert(val1.GetPayload() == "Modified"); assert(val1.GetDescription()); assert(val1.GetDescription() == "TEST"); auto val2 = decode_json(input2); assert(val2.GetStatus() == "OK"); assert(val2.GetPayload() == "Modified"); assert(!val2.GetDescription()); std::string output1; std::string output2; encode_json(val2, output2, indenting::indent); encode_json(val1, output1, indenting::indent); std::cout << "(1)\n"; std::cout << output1 << "\n\n"; std::cout << "(2)\n"; std::cout << output2 << "\n\n"; } #endif void smart_pointer_traits_test() { ns::smart_pointer_test val; val.field1 = std::make_shared("Field 1"); val.field2 = jsoncons::make_unique("Field 2"); val.field3 = std::shared_ptr(nullptr); val.field4 = std::unique_ptr(nullptr); val.field5 = std::make_shared("Field 5"); val.field6 = jsoncons::make_unique("Field 6"); val.field7 = std::shared_ptr(nullptr); val.field8 = std::unique_ptr(nullptr); std::string buf; encode_json(val, buf, indenting::indent); std::cout << buf << "\n"; auto other = decode_json(buf); assert(*other.field1 == *val.field1); assert(*other.field2 == *val.field2); assert(!other.field3); assert(!other.field4); assert(*other.field5 == *val.field5); assert(*other.field6 == *val.field6); assert(!other.field7); assert(!other.field8); } void json_type_traits_book_examples() { const std::string input = R"( [ { "category" : "fiction", "author" : "Haruki Murakami", "title" : "Kafka on the Shore", "price" : 25.17 }, { "category" : "biography", "author" : "Robert A. Caro", "title" : "The Path to Power: The Years of Lyndon Johnson I", "price" : 16.99 } ] )"; std::cout << "(1)\n\n"; auto books1 = decode_json>(input); for (const auto& item : books1) { std::cout << item.category << ", " << item.author << ", " << item.title << ", " << item.price << "\n"; } std::cout << "\n"; encode_json(books1, std::cout, indenting::indent); std::cout << "\n\n"; std::cout << "(2)\n\n"; auto books2 = decode_json>(input); for (const auto& item : books2) { std::cout << item.get_category() << ", " << item.get_author() << ", " << item.get_title() << ", " << item.get_price() << "\n"; } std::cout << "\n"; encode_json(books2, std::cout, indenting::indent); std::cout << "\n\n"; std::cout << "(3)\n\n"; auto books3 = decode_json>(input); for (const auto& item : books3) { std::cout << item.category() << ", " << item.author() << ", " << item.title() << ", " << item.price() << "\n"; } std::cout << "\n"; encode_json(books3, std::cout, indenting::indent); std::cout << "\n\n"; std::cout << "(4)\n\n"; auto books4 = decode_json>(input); for (const auto& item : books4) { std::cout << item.get_category() << ", " << item.get_author() << ", " << item.get_title() << ", " << item.get_price() << "\n"; } std::cout << "\n"; encode_json(books4, std::cout, indenting::indent); std::cout << "\n\n"; } void employee_polymorphic_example() { std::string input = R"( [ { "firstName": "John", "hours": 1000, "lastName": "Smith", "wage": 40.0 }, { "baseSalary": 30000.0, "commission": 0.25, "firstName": "Jane", "lastName": "Doe", "sales": 1000 } ] )"; auto v = decode_json>>(input); std::cout << "(1)\n"; for (const auto& p : v) { std::cout << p->firstName() << " " << p->lastName() << ", " << p->calculatePay() << "\n"; } std::cout << "\n(2)\n"; encode_json(v, std::cout, indenting::indent); std::cout << "\n\n(3)\n"; json j(v); std::cout << pretty_print(j) << "\n\n"; } void foo_bar_baz_example() { std::vector> u; u.emplace_back(new ns::Bar()); u.emplace_back(new ns::Baz()); std::string buffer; encode_json(u, buffer); std::cout << "(1)\n" << buffer << "\n\n"; auto v = decode_json>>(buffer); std::cout << "(2)\n"; for (const auto& ptr : v) { if (dynamic_cast(ptr.get())) { std::cout << "A bar\n"; } else if (dynamic_cast(ptr.get())) { std::cout << "A baz\n"; } } } int main() { std::cout << "\njson_type_traits macro examples\n\n"; std::cout << std::setprecision(6); json_type_traits_book_examples(); employee_polymorphic_example(); foo_bar_baz_example(); #if defined(JSONCONS_HAS_STD_OPTIONAL) json_type_traits_optional_examples(); #endif smart_pointer_traits_test(); std::cout << '\n'; } jsoncons-1.3.2/examples/src/json_traits_name_macro_examples.cpp000066400000000000000000000253041477700171100251110ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include namespace { namespace ns { enum class BookCategory {fiction,biography}; inline std::ostream& operator<<(std::ostream& os, const BookCategory& category) { switch (category) { case BookCategory::fiction: os << "fiction, "; break; case BookCategory::biography: os << "biography, "; break; } return os; } // #1 Class with public member data and default constructor struct Book1 { BookCategory category; std::string author; std::string title; double price; }; // #2 Class with private member data and default constructor class Book2 { BookCategory category_; std::string author_; std::string title_; double price_; Book2() = default; JSONCONS_TYPE_TRAITS_FRIEND public: BookCategory category() const {return category_;} const std::string& author() const {return author_;} const std::string& title() const{return title_;} double price() const{return price_;} }; // #3 Class with getters and initializing constructor class Book3 { BookCategory category_; std::string author_; std::string title_; double price_; public: Book3(BookCategory category, const std::string& author, const std::string& title, double price) : category_(category), author_(author), title_(title), price_(price) { } BookCategory category() const {return category_;} const std::string& author() const{return author_;} const std::string& title() const{return title_;} double price() const{return price_;} }; // #4 Class with getters, setters and default constructor class Book4 { BookCategory category_; std::string author_; std::string title_; double price_; public: BookCategory getCategory() const {return category_;} void setCategory(const BookCategory& value) {category_ = value;} const std::string& getAuthor() const {return author_;} void setAuthor(const std::string& value) {author_ = value;} const std::string& getTitle() const {return title_;} void setTitle(const std::string& value) {title_ = value;} double getPrice() const {return price_;} void setPrice(double value) {price_ = value;} }; class Employee { std::string name_; std::string surname_; public: Employee() = default; Employee(const std::string& name, const std::string& surname) : name_(name), surname_(surname) { } std::string getName() const { return name_; } void setName(const std::string& name) { name_ = name; } std::string getSurname()const { return surname_; } void setSurname(const std::string& surname) { surname_ = surname; } friend bool operator<(const Employee& lhs, const Employee& rhs) { if (lhs.surname_ < rhs.surname_) return true; return lhs.name_ < rhs.name_; } }; class Company { std::string name_; std::vector employeeIds_; public: std::string getName() const { return name_; } void setName(const std::string& name) { name_ = name; } const std::vector getIds() const { return employeeIds_; } void setIds(const std::vector& employeeIds) { employeeIds_ = employeeIds; } }; std::vector fromEmployeesToIds(const std::vector& employees) { static std::map employee_id_map = {{Employee("John", "Smith"), 1},{Employee("Jane", "Doe"), 2}}; std::vector ids; for (auto employee : employees) { ids.push_back(employee_id_map.at(employee)); } return ids; } std::vector toEmployeesFromIds(const std::vector& ids) { static std::map id_employee_map = {{1, Employee("John", "Smith")},{2, Employee("Jane", "Doe")}}; std::vector employees; for (auto id : ids) { employees.push_back(id_employee_map.at(id)); } return employees; } class Person { std::string name_; jsoncons::optional socialSecurityNumber_; public: Person(const std::string& name, const jsoncons::optional& socialSecurityNumber) : name_(name), socialSecurityNumber_(socialSecurityNumber) { } std::string getName() const { return name_; } jsoncons::optional getSsn() const { return socialSecurityNumber_; } }; } // namespace ns } // namespace // Declare the traits at global scope JSONCONS_ENUM_NAME_TRAITS(ns::BookCategory,(fiction,"Fiction"),(biography,"Biography")) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::Book1,(category,"Category"),(author,"Author"), (title,"Title"),(price,"Price")) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::Book2,(category_,"Category"),(author_,"Author"), (title_,"Title"),(price_,"Price")) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Book3,(category,"Category"),(author,"Author"), (title,"Title"),(price,"Price")) JSONCONS_ALL_GETTER_SETTER_NAME_TRAITS(ns::Book4,(getCategory,setCategory,"Category"), (getAuthor,setAuthor,"Author"), (getTitle,setTitle,"Title"), (getPrice,setPrice,"Price")) JSONCONS_ALL_GETTER_SETTER_NAME_TRAITS(ns::Employee, (getName, setName, "employee_name"), (getSurname, setSurname, "employee_surname") ) JSONCONS_ALL_GETTER_SETTER_NAME_TRAITS(ns::Company, (getName, setName, "company"), (getIds, setIds, "resources", JSONCONS_RDWR, jsoncons::always_true(), ns::toEmployeesFromIds, ns::fromEmployeesToIds) ) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Person, (getName, "name"), (getSsn, "social_security_number", JSONCONS_RDWR, jsoncons::always_true(), jsoncons::identity(), [] (const jsoncons::optional& unvalidated) { if (!unvalidated) { return unvalidated; } std::regex myRegex(("^(\\d{9})$")); if (!std::regex_match(*unvalidated, myRegex) ) { return jsoncons::optional(); } return unvalidated; } ) ) using namespace jsoncons; void json_type_traits_book_examples() { const std::string input = R"( [ { "Category" : "Fiction", "Author" : "Haruki Murakami", "Title" : "Kafka on the Shore", "Price" : 25.17 }, { "Category" : "Biography", "Author" : "Robert A. Caro", "Title" : "The Path to Power: The Years of Lyndon Johnson I", "Price" : 16.99 } ] )"; std::cout << "(1)\n\n"; auto books1 = decode_json>(input); for (const auto& item : books1) { std::cout << item.category << ", " << item.author << ", " << item.title << ", " << item.price << "\n"; } std::cout << "\n"; encode_json(books1, std::cout, indenting::indent); std::cout << "\n\n"; std::cout << "(2)\n\n"; auto books2 = decode_json>(input); for (const auto& item : books2) { std::cout << item.category() << ", " << item.author() << ", " << item.title() << ", " << item.price() << "\n"; } std::cout << "\n"; encode_json(books2, std::cout, indenting::indent); std::cout << "\n\n"; std::cout << "(3)\n\n"; auto books3 = decode_json>(input); for (const auto& item : books3) { std::cout << item.category() << ", " << item.author() << ", " << item.title() << ", " << item.price() << "\n"; } std::cout << "\n"; encode_json(books3, std::cout, indenting::indent); std::cout << "\n\n"; std::cout << "(4)\n\n"; auto books4 = decode_json>(input); for (const auto& item : books4) { std::cout << item.getCategory() << ", " << item.getAuthor() << ", " << item.getTitle() << ", " << item.getPrice() << "\n"; } std::cout << "\n"; encode_json(books4, std::cout, indenting::indent); std::cout << "\n\n"; } void translate_ids_from_to_employees() { std::string input = R"( { "company": "ExampleInc", "resources": [ { "employee_name": "John", "employee_surname": "Smith" }, { "employee_name": "Jane", "employee_surname": "Doe" } ] } )"; auto company = decode_json(input); std::cout << "(1)\n" << company.getName() << "\n"; for (auto id : company.getIds()) { std::cout << id << "\n"; } std::cout << "\n"; std::string output; encode_json(company, output, indenting::indent); std::cout << "(2)\n" << output << "\n\n"; } void tidy_member() { std::string input = R"( [ { "name": "John Smith", "social_security_number": "123456789" }, { "name": "Jane Doe", "social_security_number": "12345678" } ] )"; auto persons = decode_json>(input); std::cout << "(1)\n"; for (const auto& person : persons) { std::cout << person.getName() << ", " << (person.getSsn() ? *person.getSsn() : "n/a") << "\n"; } std::cout << "\n"; std::string output; encode_json(persons, output, indenting::indent); std::cout << "(2)\n" << output << "\n"; } int main() { std::cout << "\njson_type_traits macro named examples\n\n"; std::cout << std::setprecision(6); json_type_traits_book_examples(); translate_ids_from_to_employees(); tidy_member(); std::cout << '\n'; } jsoncons-1.3.2/examples/src/json_traits_polymorphic_examples.cpp000066400000000000000000000072041477700171100253540ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include namespace { namespace ns { class Shape { public: virtual ~Shape() = default; virtual double area() const = 0; }; class Rectangle : public Shape { double height_; double width_; public: Rectangle(double height, double width) : height_(height), width_(width) { } const std::string& type() const { static const std::string type_ = "rectangle"; return type_; } double height() const { return height_; } double width() const { return width_; } double area() const override { return height_ * width_; } }; class Triangle : public Shape { double height_; double width_; public: Triangle(double height, double width) : height_(height), width_(width) { } const std::string& type() const { static const std::string type_ = "triangle"; return type_; } double height() const { return height_; } double width() const { return width_; } double area() const override { return (height_ * width_)/2.0; } }; class Circle : public Shape { double radius_; public: Circle(double radius) : radius_(radius) { } const std::string& type() const { static const std::string type_ = "circle"; return type_; } double radius() const { return radius_; } double area() const override { constexpr double pi = 3.14159265358979323846; return pi*radius_*radius_; } }; } // namespace ns } // namespace JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Rectangle, (type,"type",JSONCONS_RDONLY,[](const std::string& type) noexcept{return type == "rectangle";}), (height, "height"), (width, "width") ) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Triangle, (type,"type", JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "triangle";}), (height, "height"), (width, "width") ) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Circle, (type,"type", JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "circle";}), (radius, "radius") ) JSONCONS_POLYMORPHIC_TRAITS(ns::Shape,ns::Rectangle,ns::Triangle,ns::Circle) namespace { void distinguish_by_type_example() { std::string input = R"( [ {"type" : "rectangle", "width" : 2.0, "height" : 1.5 }, {"type" : "triangle", "width" : 4.0, "height" : 2.0 }, {"type" : "circle", "radius" : 1.0 } ] )"; auto shapes = jsoncons::decode_json>>(input); std::cout << "(1)\n"; for (const auto& shape : shapes) { std::cout << typeid(*shape.get()).name() << " area: " << shape->area() << "\n"; } std::string output; jsoncons::encode_json(shapes, output, jsoncons::indenting::indent); std::cout << "\n(2)\n" << output << "\n"; } } int main() { std::cout << "\njson traits polymorphic examples\n\n"; distinguish_by_type_example(); std::cout << '\n'; } jsoncons-1.3.2/examples/src/json_traits_tuple_examples.cpp000066400000000000000000000047011477700171100241370ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #include #include #include using namespace jsoncons; using qualifying_results_type = std::tuple; void tuple_example() { std::vector results = { {1,"Lewis Hamilton","Mercedes","1'24.303",std::chrono::milliseconds(0)}, {2,"Valtteri Bottas","Mercedes","1'24.616",std::chrono::milliseconds(313)}, {3,"Max Verstappen","Red Bull","1'25.325",std::chrono::milliseconds(1022)} }; std::string json_data; encode_json(results, json_data, indenting::indent); std::cout << json_data << "\n\n"; auto results1 = decode_json>(json_data); assert(results1 == results); auto csv_options = csv::csv_options{} .column_names("Pos,Driver,Entrant,Time,Gap") .mapping_kind(csv::csv_mapping_kind::n_rows) .header_lines(1); std::string csv_data; csv::encode_csv(results, csv_data, csv_options); std::cout << csv_data << "\n\n"; auto results2 = csv::decode_csv>(csv_data, csv_options); assert(results2 == results); std::vector bson_data; bson::encode_bson(results, bson_data); auto results3 = bson::decode_bson>(bson_data); assert(results3 == results); std::vector cbor_data; cbor::encode_cbor(results, cbor_data); auto results4 = cbor::decode_cbor>(cbor_data); assert(results4 == results); std::vector msgpack_data; msgpack::encode_msgpack(results, msgpack_data); auto results5 = msgpack::decode_msgpack>(msgpack_data); assert(results5 == results); std::vector ubjson_data; ubjson::encode_ubjson(results, ubjson_data); auto results6 = ubjson::decode_ubjson>(ubjson_data); assert(results6 == results); } int main() { std::cout << "\njson traits tuple examples\n\n"; tuple_example(); std::cout << '\n'; } jsoncons-1.3.2/examples/src/json_traits_variant_examples.cpp000066400000000000000000000245351477700171100244610ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #if defined(JSONCONS_HAS_STD_VARIANT) namespace { namespace ns { enum class Color {yellow, red, green, blue}; inline std::ostream& operator<<(std::ostream& os, Color val) { switch (val) { case Color::yellow: os << "yellow"; break; case Color::red: os << "red"; break; case Color::green: os << "green"; break; case Color::blue: os << "blue"; break; } return os; } class Fruit { private: JSONCONS_TYPE_TRAITS_FRIEND std::string name_; Color color_; public: friend std::ostream& operator<<(std::ostream& os, const Fruit& val) { os << "name: " << val.name_ << ", color: " << val.color_ << "\n"; return os; } }; class Fabric { private: JSONCONS_TYPE_TRAITS_FRIEND int size_; std::string material_; public: friend std::ostream& operator<<(std::ostream& os, const Fabric& val) { os << "size: " << val.size_ << ", material: " << val.material_ << "\n"; return os; } }; class Basket { private: JSONCONS_TYPE_TRAITS_FRIEND std::string owner_; std::vector> items_; public: std::string owner() const { return owner_; } std::vector> items() const { return items_; } }; class Rectangle { double height_; double width_; public: Rectangle(double height, double width) : height_(height), width_(width) { } double height() const { return height_; } double width() const { return width_; } double area() const { return height_ * width_; } }; class Triangle { double height_; double width_; public: Triangle(double height, double width) : height_(height), width_(width) { } double height() const { return height_; } double width() const { return width_; } double area() const { return (height_ * width_)/2.0; } }; class Circle { double radius_; public: Circle(double radius) : radius_(radius) { } double radius() const { return radius_; } double area() const { constexpr double pi = 3.14159265358979323846; return pi*radius_*radius_; } }; inline constexpr auto rectangle_marker = [](double) noexcept {return "rectangle"; }; inline constexpr auto triangle_marker = [](double) noexcept {return "triangle";}; inline constexpr auto circle_marker = [](double) noexcept {return "circle";}; } // ns } // namespace JSONCONS_ENUM_NAME_TRAITS(ns::Color, (yellow, "YELLOW"), (red, "RED"), (green, "GREEN"), (blue, "BLUE")) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::Fruit, (name_, "name"), (color_, "color")) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::Fabric, (size_, "size"), (material_, "material")) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::Basket, (owner_, "owner"), (items_, "items")) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Rectangle, (height,"type",JSONCONS_RDONLY, [](const std::string& type) noexcept{return type == "rectangle";}, ns::rectangle_marker), (height, "height"), (width, "width") ) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Triangle, (height,"type", JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "triangle";}, ns::triangle_marker), (height, "height"), (width, "width") ) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Circle, (radius,"type", JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "circle";}, ns::circle_marker), (radius, "radius") ) void variant_example() { std::string input = R"( { "owner": "Rodrigo", "items": [ { "name": "banana", "color": "YELLOW" }, { "size": 40, "material": "wool" }, { "name": "apple", "color": "RED" }, { "size": 40, "material": "cotton" } ] } )"; ns::Basket basket = jsoncons::decode_json(input); std::cout << basket.owner() << "\n\n"; std::cout << "(1)\n"; for (const auto& var : basket.items()) { std::visit([](auto&& arg) { using T = std::decay_t; if constexpr (std::is_same_v) std::cout << "Fruit " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "Fabric " << arg << '\n'; }, var); } std::string output; jsoncons::encode_json(basket, output, jsoncons::indenting::indent); std::cout << "(2)\n" << output << "\n\n"; } void variant_example2() { using variant_type = std::variant; std::vector vars = {100, 10.1, false, std::string("Hello World"), ns::Color::yellow}; std::string buffer; jsoncons::encode_json(vars, buffer, jsoncons::indenting::indent); std::cout << "(1)\n" << buffer << "\n\n"; auto vars2 = jsoncons::decode_json>(buffer); auto visitor = [](auto&& arg) { using T = std::decay_t; if constexpr (std::is_same_v) std::cout << "int " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "double " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "bool " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "std::string " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "ns::Color " << arg << '\n'; }; std::cout << "(2)\n"; for (const auto& item : vars2) { std::visit(visitor, item); } std::cout << "\n"; } void variant_example3() { using variant_type = std::variant; std::vector vars = {100, 10.1, false, std::string("Hello World"), ns::Color::yellow}; std::string buffer; jsoncons::encode_json(vars, buffer, jsoncons::indenting::indent); std::cout << "(1)\n" << buffer << "\n\n"; auto vars2 = jsoncons::decode_json>(buffer); auto visitor = [](auto&& arg) { using T = std::decay_t; if constexpr (std::is_same_v) std::cout << "int " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "double " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "bool " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "std::string " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "ns::Color " << arg << '\n'; }; std::cout << "(2)\n"; for (const auto& item : vars2) { std::visit(visitor, item); } std::cout << "\n"; } void variant_example4() { using variant_type = std::variant; std::vector v = {nullptr, 10, 5.1, true, std::string("Hello World")}; std::string buffer; jsoncons::encode_json_pretty(v, buffer); std::cout << "(1)\n" << buffer << "\n\n"; auto v2 = jsoncons::decode_json>(buffer); auto visitor = [](auto&& arg) { using T = std::decay_t; if constexpr (std::is_same_v) std::cout << "nullptr " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "int " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "double " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "bool " << arg << '\n'; else if constexpr (std::is_same_v) std::cout << "std::string " << arg << '\n'; }; std::cout << "(2)\n"; for (const auto& item : v2) { std::visit(visitor, item); } } void distinguish_by_type() { using shapes_t = std::variant; std::string input = R"( [ {"type" : "rectangle", "width" : 2.0, "height" : 1.5 }, {"type" : "triangle", "width" : 4.0, "height" : 2.0 }, {"type" : "circle", "radius" : 1.0 } ] )"; auto shapes = jsoncons::decode_json>(input); auto visitor = [](auto&& shape) { using T = std::decay_t; if constexpr (std::is_same_v) std::cout << "rectangle area: " << shape.area() << '\n'; else if constexpr (std::is_same_v) std::cout << "triangle area: " << shape.area() << '\n'; else if constexpr (std::is_same_v) std::cout << "circle area: " << shape.area() << '\n'; }; std::cout << "(1)\n"; for (const auto& shape : shapes) { std::visit(visitor, shape); } std::string output; jsoncons::encode_json(shapes, output, jsoncons::indenting::indent); std::cout << "\n(2)\n" << output << "\n"; } #endif // defined(JSONCONS_HAS_STD_VARIANT) int main() { std::cout << "\njson traits variant examples\n\n"; #if defined(JSONCONS_HAS_STD_VARIANT) variant_example(); variant_example4(); variant_example2(); variant_example3(); distinguish_by_type(); #endif std::cout << '\n'; } jsoncons-1.3.2/examples/src/jsonpatch_examples.cpp000066400000000000000000000053101477700171100223550ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include using jsoncons::json; namespace jsonpatch = jsoncons::jsonpatch; void jsonpatch_add_add() { // Apply a JSON Patch json doc = json::parse(R"( { "foo": "bar"} )"); json doc2 = doc; json patch = json::parse(R"( [ { "op": "add", "path": "/baz", "value": "qux" }, { "op": "add", "path": "/foo", "value": [ "bar", "baz" ] } ] )"); std::error_code ec; jsonpatch::apply_patch(doc, patch, ec); std::cout << "(1)\n" << pretty_print(doc) << '\n'; // Create a JSON Patch auto patch2 = jsonpatch::from_diff(doc2,doc); std::cout << "(2)\n" << pretty_print(patch2) << '\n'; jsonpatch::apply_patch(doc2,patch2,ec); std::cout << "(3)\n" << pretty_print(doc2) << '\n'; } void jsonpatch_add_add_add_failed1() { json target = json::parse(R"( { "foo": "bar"} )"); json patch = json::parse(R"( [ { "op": "add", "path": "/baz", "value": "qux" }, { "op": "add", "path": "/foo", "value": [ "bar", "baz" ] }, { "op": "add", "path": "/baz/bat", "value": "qux" } // nonexistent target ] )"); try { jsonpatch::apply_patch(target, patch); } catch (const jsonpatch::jsonpatch_error& e) { std::cout << "(1) " << e.what() << '\n'; std::cout << "(2) " << target << '\n'; } } void jsonpatch_add_add_add_failed2() { json target = json::parse(R"( { "foo": "bar"} )"); json patch = json::parse(R"( [ { "op": "add", "path": "/baz", "value": "qux" }, { "op": "add", "path": "/foo", "value": [ "bar", "baz" ] }, { "op": "add", "path": "/baz/bat", "value": "qux" } // nonexistent target ] )"); std::error_code ec; jsonpatch::apply_patch(target, patch, ec); std::cout << "(1) " << std::error_code(ec).message() << '\n'; std::cout << "(2) " << target << '\n'; } void create_a_json_patch() { json source = json::parse(R"( {"/": 9, "foo": "bar"} )"); json target = json::parse(R"( { "baz":"qux", "foo": [ "bar", "baz" ]} )"); auto patch = jsonpatch::from_diff(source, target); std::error_code ec; jsonpatch::apply_patch(source, patch, ec); std::cout << "(1)\n" << pretty_print(patch) << '\n'; std::cout << "(2)\n" << pretty_print(source) << '\n'; } int main() { std::cout << "\njsonpatch examples\n\n"; create_a_json_patch(); jsonpatch_add_add(); jsonpatch_add_add_add_failed2(); jsonpatch_add_add_add_failed1(); std::cout << '\n'; } jsoncons-1.3.2/examples/src/jsonpath_examples.cpp000066400000000000000000000624161477700171100222240ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include "free_list_allocator.hpp" #include #include #include #include #include template using MyScopedAllocator = std::scoped_allocator_adaptor>; // for brevity namespace jsonpath = jsoncons::jsonpath; namespace jsonpointer = jsoncons::jsonpointer; void json_query_examples() { std::ifstream is("./input/store.json"); auto booklist = jsoncons::json::parse(is); // The authors of books that are cheaper than $10 jsoncons::json result1 = jsonpath::json_query(booklist, "$.store.book[?(@.price < 10)].author"); std::cout << "(1) " << result1 << "\n"; // The number of books jsoncons::json result2 = jsonpath::json_query(booklist, "length($..book)"); std::cout << "(2) " << result2 << "\n"; // The third book jsoncons::json result3 = jsonpath::json_query(booklist, "$..book[2]"); std::cout << "(3)\n" << pretty_print(result3) << "\n"; // All books whose author's name starts with Evelyn jsoncons::json result4 = jsonpath::json_query(booklist, "$.store.book[?(@.author =~ /Evelyn.*?/)]"); std::cout << "(4)\n" << pretty_print(result4) << "\n"; // The titles of all books that have isbn number jsoncons::json result5 = jsonpath::json_query(booklist, "$..book[?(@.isbn)].title"); std::cout << "(5) " << result5 << "\n"; // All authors and titles of books jsoncons::json result6 = jsonpath::json_query(booklist, "$['store']['book']..['author','title']"); std::cout << "(6)\n" << pretty_print(result6) << "\n"; // Union of two ranges of book titles jsoncons::json result7 = jsonpath::json_query(booklist, "$..book[1:2,2:4].title"); std::cout << "(7) " << result7 << "\n"; // Union of a subset of book titles identified by index jsoncons::json result8 = jsonpath::json_query(booklist, "$.store[@.book[0].title,@.book[1].title,@.book[3].title]"); std::cout << "(8) " << result8 << "\n"; // Union of third book title and all book titles with price > 10 jsoncons::json result9 = jsonpath::json_query(booklist, "$.store[@.book[3].title,@.book[?(@.price > 10)].title]"); std::cout << "(9) " << result9 << "\n"; // Intersection of book titles with category fiction and price < 15 jsoncons::json result10 = jsonpath::json_query(booklist, "$.store.book[?(@.category == 'fiction' && @.price < 15)].title"); std::cout << "(10) " << result10 << "\n"; // Normalized path expressions jsoncons::json result11 = jsonpath::json_query(booklist, "$.store.book[?(@.author =~ /Evelyn.*?/)]", jsonpath::result_options::path); std::cout << "(11) " << result11 << "\n"; // All titles whose author's second name is 'Waugh' jsoncons::json result12 = jsonpath::json_query(booklist,"$.store.book[?(tokenize(@.author,'\\\\s+')[1] == 'Waugh')].title"); std::cout << "(12) " << result12 << "\n"; // All keys in the second book jsoncons::json result13 = jsonpath::json_query(booklist,"keys($.store.book[1])"); std::cout << "(13) " << result13 << "\n"; jsoncons::json result14 = jsonpath::json_query(booklist,"$.store.book[?(ceil(@.price) == 9)]"); std::cout << "(14)\n" << pretty_print(result14) << "\n"; jsoncons::json result15 = jsonpath::json_query(booklist,"$.store.book[?(ceil(@.price*100) == 895)]"); std::cout << "(15)\n" << result15 << "\n"; jsoncons::json result16 = jsonpath::json_query(booklist,"$.store.book[?(floor(@.price) == 8)]"); std::cout << "(16)\n" << pretty_print(result16) << "\n"; jsoncons::json result17 = jsonpath::json_query(booklist,"$.store.book[?(floor(@.price*100) == 895)]"); std::cout << "(17) " << result17 << "\n"; jsoncons::json result18 = jsonpath::json_query(booklist,"floor($.store.book[0].price*100)"); std::cout << "(18) " << result18 << "\n"; } void function_tokenize_example() { std::string data = R"( { "books": [ { "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami" }, { "title" : "Almost Transparent Blue", "author" : "Ryu Murakami" }, { "title" : "The Quiet American", "author" : "Graham Greene" } ] } )"; auto j = jsoncons::json::parse(data); // All titles whose author's last name is 'Murakami' std::string expr = R"($.books[?(tokenize(@.author,'\\s+')[-1] == 'Murakami')].title)"; jsoncons::json result = jsonpath::json_query(j, expr); std::cout << pretty_print(result) << "\n\n"; } void function_sum_example() { std::string data = R"( { "books": [ { "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } )"; auto j = jsoncons::json::parse(data); // All titles whose price is greater than the average price std::string expr = R"($.books[?(@.price > sum($.books[*].price)/length($.books[*].price))].title)"; jsoncons::json result = jsonpath::json_query(j, expr); std::cout << result << "\n\n"; } void function_avg_example() { std::string data = R"( { "books": [ { "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } )"; auto j = jsoncons::json::parse(data); // All titles whose price is greater than the average price std::string expr = R"($.books[?(@.price > avg($.books[*].price))].title)"; jsoncons::json result = jsonpath::json_query(j, expr); std::cout << result << "\n\n"; } void function_floor_example() { std::string data = R"( [ { "number" : 8.95 }, { "number" : -8.95 } ] )"; auto j = jsoncons::json::parse(data); jsoncons::json result1 = jsonpath::json_query(j, "$[?(floor(@.number*100) == 895)]"); std::cout << "(1) " << result1 << "\n\n"; jsoncons::json result2 = jsonpath::json_query(j, "$[?(floor(@.number*100) == 894)]"); std::cout << "(2) " << result2 << "\n\n"; jsoncons::json result3 = jsonpath::json_query(j, "$[?(floor(@.number*100) == -895)]"); std::cout << "(3) " << result3 << "\n\n"; } void function_ceil_example() { std::string data = R"( { "books": [ { "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 } ] } )"; auto j = jsoncons::json::parse(data); jsoncons::json result1 = jsonpath::json_query(j, "$.books[?(ceil(@.price) == 23.0)]"); std::cout << "(1) " << result1 << "\n\n"; jsoncons::json result2 = jsonpath::json_query(j, "$.books[?(ceil(@.price*100) == 2358.0)]"); std::cout << "(2) " << result2 << "\n\n"; } void function_keys_example() { std::string data = R"( { "books": [ { "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } )"; auto j = jsoncons::json::parse(data); // All books that don't have a price std::string expr = "$.books[?(!contains(keys(@),'price'))]"; jsoncons::json result = jsonpath::json_query(j, expr); std::cout << result << "\n\n"; } void function_length_example() { std::string data = R"( { "books": [ { "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } )"; auto j = jsoncons::json::parse(data); jsoncons::json result1 = jsonpath::json_query(j, "length($.books[*])"); std::cout << "(1) " << result1 << "\n\n"; jsoncons::json result2 = jsonpath::json_query(j, "length($.books[*].price)"); std::cout << "(2) " << result2 << "\n\n"; } void json_replace_example1() { std::ifstream is("./input/books.json"); auto data =jsoncons::json::parse(is); jsonpath::json_replace(data,"$.books[?(@.title == 'A Wild Sheep Chase')].price",20.0); std::cout << pretty_print(data) << "\n\n"; } void json_replace_example2() { jsoncons::json j; try { j = jsoncons::json::parse(R"( {"store": {"book": [ {"category": "reference", "author": "Margaret Weis", "title": "Dragonlance Series", "price": 31.96}, {"category": "reference", "author": "Brent Weeks", "title": "Night Angel Trilogy", "price": 14.70 }]}} )"); } catch (const std::exception& e) { std::cout << e.what() << "\n"; } std::cout << ("1\n") << pretty_print(j) << "\n"; jsonpath::json_replace(j,"$..book[?(@.price==31.96)].price", 30.9); std::cout << ("2\n") << pretty_print(j) << "\n\n"; } void json_replace_example3() { std::ifstream is("./input/books.json"); auto data =jsoncons::json::parse(is); auto f = [](const std::string& /*location*/, jsoncons::json& price) { price = std::round(price.as() - 1.0); }; // make a discount on all books jsonpath::json_replace(data, "$.books[*].price", f); std::cout << pretty_print(data) << "\n\n"; } void json_replace_example4() { std::ifstream is("./input/books.json"); auto data =jsoncons::json::parse(is); auto f = [](const std::string& /*location*/, jsoncons::json& book) { if (book.at("category") == "memoir" && !book.contains("price")) { book.try_emplace("price",140.0); } }; jsonpath::json_replace(data, "$.books[*]", f); std::cout << pretty_print(data) << "\n\n"; } void jsonpath_complex_examples() { auto j = jsoncons::json::parse(R"( [ { "root": { "id" : 10, "second": [ { "names": [ 2 ], "complex": [ { "names": [ 1 ], "panels": [ { "result": [ 1 ] }, { "result": [ 1, 2, 3, 4 ] }, { "result": [ 1 ] } ] } ] } ] } }, { "root": { "id" : 20, "second": [ { "names": [ 2 ], "complex": [ { "names": [ 1 ], "panels": [ { "result": [ 1 ] }, { "result": [ 3, 4, 5, 6 ] }, { "result": [ 1 ] } ] } ] } ] } } ] )"); // Find all arrays of elements where length(@.result) is 4 jsoncons::json result1 = jsonpath::json_query(j,"$..[?(length(@.result) == 4)].result"); std::cout << "(1) " << result1 << "\n"; // Find array of elements that has id 10 and length(@.result) is 4 jsoncons::json result2 = jsonpath::json_query(j,"$..[?(@.id == 10)]..[?(length(@.result) == 4)].result"); std::cout << "(2) " << result2 << "\n"; // Find all arrays of elements where length(@.result) is 4 and that have value 3 jsoncons::json result3 = jsonpath::json_query(j,"$..[?(length(@.result) == 4 && (@.result[0] == 3 || @.result[1] == 3 || @.result[2] == 3 || @.result[3] == 3))].result"); std::cout << "(3) " << result3 << "\n"; } void jsonpath_union() { auto root = jsoncons::json::parse(R"( { "firstName": "John", "lastName" : "doe", "age" : 26, "address" : { "streetAddress": "naist street", "city" : "Nara", "postalCode" : "630-0192" }, "phoneNumbers": [ { "type" : "iPhone", "number": "0123-4567-8888" }, { "type" : "home", "number": "0123-4567-8910" } ] } )"); std::string path = "$..[@.firstName,@.address.city]"; jsoncons::json result = jsonpath::json_query(root,path); std::cout << result << "\n"; } void flatten_and_unflatten() { auto input = jsoncons::json::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 }, { "rater": "HikingAsylum", "assertion": "intermediate", "rated": "Hongmin", "rating": 0.75 } ] } )"); jsoncons::json result = jsonpath::flatten(input); std::cout << pretty_print(result) << "\n"; jsoncons::json original = jsonpath::unflatten(result); assert(original == input); } void more_json_query_examples() { std::ifstream is("./input/books.json"); auto data =jsoncons::json::parse(is); auto result1 = jsonpath::json_query(data, "$.books[1,1,3].title"); std::cout << "(1)\n" << pretty_print(result1) << "\n\n"; auto result2 = jsonpath::json_query(data, "$.books[1,1,3].title", jsonpath::result_options::path); std::cout << "(2)\n" << pretty_print(result2) << "\n\n"; auto result3 = jsonpath::json_query(data, "$.books[1,1,3].title", jsonpath::result_options::nodups); std::cout << "(3)\n" << pretty_print(result3) << "\n\n"; auto result4 = jsonpath::json_query(data, "$.books[1,1,3].title", jsonpath::result_options::path | jsonpath::result_options::nodups); std::cout << "(4)\n" << pretty_print(result4) << "\n\n"; } void make_expression_examples() { auto expr = jsonpath::make_expression("$.books[1,1,3].title"); std::ifstream is("./input/books.json"); auto data =jsoncons::json::parse(is); jsoncons::json result1 = expr.evaluate(data); std::cout << "(1) " << pretty_print(result1) << "\n\n"; jsoncons::json result2 = expr.evaluate(data, jsonpath::result_options::path); std::cout << "(2) " << pretty_print(result2) << "\n\n"; jsoncons::json result3 = expr.evaluate(data, jsonpath::result_options::nodups); std::cout << "(3) " << pretty_print(result3) << "\n\n"; jsoncons::json result4 = expr.evaluate(data, jsonpath::result_options::path | jsonpath::result_options::nodups); std::cout << "(4) " << pretty_print(result4) << "\n\n"; } void more_make_expression_example() { auto expr = jsonpath::make_expression("$.books[?(@.price > avg($.books[*].price))].title"); std::ifstream is("./input/books.json"); auto data =jsoncons::json::parse(is); jsoncons::json result = expr.evaluate(data); std::cout << pretty_print(result) << "\n\n"; } void make_expression_with_callback_example() { auto expr = jsonpath::make_expression("$.books[?(@.price >= 22.0)]"); std::ifstream is("./input/books.json"); auto data =jsoncons::json::parse(is); auto callback = [](const std::string& path, const jsoncons::json& val) { std::cout << path << ": " << val << "\n"; }; expr.evaluate(data, callback, jsonpath::result_options::path); } void json_query_with_callback_example() { std::ifstream is("./input/books.json"); auto data =jsoncons::json::parse(is); std::string path = "$.books[?(@.price >= 22.0)]"; auto callback = [](const std::string& path, const jsoncons::json& val) { std::cout << path << ": " << val << "\n"; }; jsonpath::json_query(data, path, callback, jsonpath::result_options::path); } void json_query_with_options_example() { std::string s = "[1,2,3,4,5]"; auto data =jsoncons::json::parse(s); std::string path = "$[4,1,1]"; auto result1 = jsonpath::json_query(data, path); std::cout << "(1) " << result1 << "\n\n"; auto result2 = jsonpath::json_query(data, path, jsonpath::result_options::path); std::cout << "(2) " << result2 << "\n\n"; auto result3 = jsonpath::json_query(data, path, jsonpath::result_options::sort); std::cout << "(3) " << result3 << "\n\n"; auto result4 = jsonpath::json_query(data, path, jsonpath::result_options::sort | jsonpath::result_options::path); std::cout << "(4) " << result4 << "\n\n"; auto result5 = jsonpath::json_query(data, path, jsonpath::result_options::nodups); std::cout << "(5) " << result5 << "\n\n"; auto result6 = jsonpath::json_query(data, path, jsonpath::result_options::nodups | jsonpath::result_options::path); std::cout << "(6) " << result6 << "\n\n"; auto result7 = jsonpath::json_query(data, path, jsonpath::result_options::nodups | jsonpath::result_options::sort); std::cout << "(7) " << result7 << "\n\n"; auto result8 = jsonpath::json_query(data, path, jsonpath::result_options::nodups | jsonpath::result_options::sort | jsonpath::result_options::path); std::cout << "(8) " << result8 << "\n\n"; } void search_for_and_replace_a_value() { std::string data = R"( { "books": [ { "author": "Nigel Rees", "title": "Sayings of the Century", "isbn": "0048080489", "price": 8.95 }, { "author": "Evelyn Waugh", "title": "Sword of Honour", "isbn": "0141193557", "price": 12.99 }, { "author": "Herman Melville", "title": "Moby Dick", "isbn": "0553213113", "price": 8.99 } ] } )"; auto j = jsoncons::json::parse(data); // Change the price of "Moby Dick" from $8.99 to $10 jsonpath::json_replace(j,"$.books[?(@.isbn == '0553213113')].price",10.0); // Increase the price of "Sayings of the Century" by $1 auto f = [](const std::string& /*location*/, jsoncons::json& value) { value = value.as() + 1.0; }; jsonpath::json_replace(j, "$.books[?(@.isbn == '0048080489')].price", f); // (since 0.161.0) std::cout << pretty_print(j) << '\n'; } void union_example() { std::ifstream is("./input/store.json"); jsoncons::json store = jsoncons::json::parse(is); std::string path = "$.store.book[0:2,-1,?(@.author=='Herman Melville')].title"; auto result1 = jsonpath::json_query(store, path); std::cout << "(1) " << result1 << "\n\n"; auto result2 = jsonpath::json_query(store, path, jsonpath::result_options::path); std::cout << "(2) " << result2 << "\n\n"; } void parent_operator_example() { std::string doc = R"( [ { "author" : "Haruki Murakami", "title": "A Wild Sheep Chase", "reviews": [{"rating": 4, "reviewer": "Nan"}] }, { "author" : "Sergei Lukyanenko", "title": "The Night Watch", "reviews": [{"rating": 5, "reviewer": "Alan"}, {"rating": 3,"reviewer": "Anne"}] }, { "author" : "Graham Greene", "title": "The Comedians", "reviews": [{"rating": 4, "reviewer": "Lisa"}, {"rating": 5, "reviewer": "Robert"}] } ] )"; jsoncons::json store = jsoncons::json::parse(doc); std::string path = "$[*].reviews[?(@.rating == 5)]^^"; auto result = jsonpath::json_query(store, path); std::cout << pretty_print(result) << "\n\n"; } template class my_custom_functions : public jsonpath::custom_functions { public: my_custom_functions() { this->register_function("divide", // function name 2, // number of arguments [](jsoncons::span> params, std::error_code& ec) -> Json { const Json& arg0 = params[0].value(); const Json& arg1 = params[1].value(); if (!(arg0.is_number() && arg1.is_number())) { ec = jsonpath::jsonpath_errc::invalid_type; return Json::null(); } return Json(arg0.template as() / arg1.template as()); } ); } }; void custom_functions1() { my_custom_functions funcs; jsoncons::json root = jsoncons::json::parse(R"([{"foo": 60, "bar": 10},{"foo": 60, "bar": 5}])"); std::cout << pretty_print(root) << "\n\n"; auto expr = jsonpath::make_expression("$[?(divide(@.foo, @.bar) == 6)]", funcs); jsoncons::json result = expr.evaluate(root); std::cout << pretty_print(result) << "\n\n"; } void custom_functions2() { my_custom_functions funcs; auto root = jsoncons::json::parse(R"([{"foo": 60, "bar": 10},{"foo": 60, "bar": 5}])"); std::cout << pretty_print(root) << "\n\n"; jsoncons::json result = jsonpath::json_query(root, "$[?(divide(@.foo, @.bar) == 6)]", jsonpath::result_options(), funcs); std::cout << pretty_print(result) << "\n\n"; } void make_expression_with_stateful_allocator() { using my_alloc = MyScopedAllocator; // an allocator with a single-argument constructor using cust_json = jsoncons::basic_json; std::string json_text = R"( { "books": [ { "category": "fiction", "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "category": "fiction", "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "category": "fiction", "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "category": "memoir", "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } )"; auto alloc = my_alloc(1); // until 0.171.0 // jsoncons::json_decoder decoder(jsoncons::result_allocator_arg, alloc, alloc); // since 0.171.0 jsoncons::json_decoder decoder(alloc, alloc); jsoncons::basic_json_reader,my_alloc> reader(json_text, decoder, alloc); reader.read(); cust_json doc = decoder.get_result(); std::cout << pretty_print(doc) << "\n\n"; std::string_view p{"$.books[?(@.category == 'fiction')].title"}; auto expr = jsoncons::jsonpath::make_expression(jsoncons::combine_allocators(alloc), p); auto result = expr.evaluate(doc); std::cout << pretty_print(result) << "\n\n"; } int main() { std::cout << "\njsonpath examples\n\n"; json_query_examples(); jsonpath_complex_examples(); jsonpath_union(); flatten_and_unflatten(); more_json_query_examples(); make_expression_examples(); more_make_expression_example(); json_query_with_options_example(); make_expression_with_callback_example(); json_query_with_callback_example(); json_replace_example2(); json_replace_example3(); json_replace_example1(); json_replace_example4(); function_tokenize_example(); function_sum_example(); function_avg_example(); function_length_example(); function_keys_example(); search_for_and_replace_a_value(); custom_functions1(); custom_functions2(); function_floor_example(); function_ceil_example(); union_example(); parent_operator_example(); make_expression_with_stateful_allocator(); std::cout << "\n"; } jsoncons-1.3.2/examples/src/jsonpath_location_examples.cpp000066400000000000000000000146421477700171100241120ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include // for brevity using jsoncons::json; namespace jsonpath = jsoncons::jsonpath; namespace jsonpointer = jsoncons::jsonpointer; // since 0.172.0 void remove_selected_books() { std::string json_string = R"( { "books": [ { "category": "fiction", "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "category": "fiction", "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "category": "fiction", "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "category": "memoir", "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } )"; json doc = json::parse(json_string); auto expr = jsonpath::make_expression("$.books[?(@.category == 'fiction')]"); std::vector locations = expr.select_paths(doc, jsonpath::result_options::sort_descending | jsonpath::result_options::sort_descending); for (const auto& location : locations) { std::cout << jsonpath::to_string(location) << "\n"; } std::cout << "\n"; for (const auto& location : locations) { jsonpath::remove(doc, location); } std::cout << jsoncons::pretty_print(doc) << "\n\n"; } // since 0.172.0 void remove_selected_books_in_one_step() { std::string json_string = R"( { "books": [ { "category": "fiction", "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "category": "fiction", "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "category": "fiction", "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "category": "memoir", "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } )"; json doc = json::parse(json_string); std::size_t n = jsonpath::remove(doc, "$.books[?(@.category == 'fiction')]"); std::cout << "Number of nodes removed: " << n << "\n\n"; std::cout << jsoncons::pretty_print(doc) << "\n\n"; } // since 0.174.0 void replace_example() { std::string json_string = R"( {"books": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour" }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3" } ] } )"; json doc = json::parse(json_string); json new_price{13.0}; jsonpath::json_location loc0 = jsonpath::json_location::parse("$.books[0].price"); auto result0 = jsonpath::replace(doc, loc0, new_price); assert(result0.second); assert(result0.first == std::addressof(doc.at("books").at(0).at("price"))); assert(doc.at("books").at(0).at("price") == new_price); jsonpath::json_location loc1 = jsonpath::json_location::parse("$.books[1].price"); auto result1 = jsonpath::replace(doc, loc1, new_price); assert(!result1.second); // create_if_missing is true result1 = jsonpath::replace(doc, loc1, new_price, true); assert(result1.second); assert(result1.first == std::addressof(doc.at("books").at(1).at("price"))); assert(doc.at("books").at(1).at("price") == new_price); jsonpath::json_location loc2 = jsonpath::json_location::parse("$.books[2].kindle.price"); auto result2 = jsonpath::replace(doc, loc2, new_price, true); assert(result2.second); assert(result2.first == std::addressof(doc.at("books").at(2).at("kindle").at("price"))); assert(doc.at("books").at(2).at("kindle").at("price") == new_price); std::cout << pretty_print(doc) << "\n\n"; } void convert_normalized_path_to_json_pointer() { std::string json_string = R"( { "books": [ { "category": "fiction", "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "category": "fiction", "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "category": "fiction", "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "category": "memoir", "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } )"; json doc = json::parse(json_string); auto expr = jsonpath::make_expression("$.books[?(@.category == 'fiction')]"); std::vector locations = expr.select_paths(doc, jsonpath::result_options::sort_descending); for (const auto& location : locations) { std::cout << jsonpath::to_string(location) << "\n"; } std::cout << "\n"; std::vector pointers; for (const auto& location : locations) { jsonpointer::json_pointer ptr; { for (const jsonpath::path_element& element : location) { if (element.has_name()) { ptr.append(element.name()); } else { ptr.append(element.index()); } } } pointers.push_back(ptr); } for (const auto& ptr : pointers) { std::cout << jsonpointer::to_string(ptr) << "\n"; } std::cout << "\n"; } int main() { std::cout << "\njsonpath location examples\n\n"; remove_selected_books(); convert_normalized_path_to_json_pointer(); remove_selected_books_in_one_step(); replace_example(); std::cout << "\n"; } jsoncons-1.3.2/examples/src/jsonpointer_examples.cpp000066400000000000000000000323021477700171100227370ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include // for brevity using jsoncons::json; namespace jsonpointer = jsoncons::jsonpointer; void jsonpointer_select_RFC6901() { // Example from RFC 6901 auto j = json::parse(R"( { "foo": ["bar", "baz"], "": 0, "a/b": 1, "c%d": 2, "e^f": 3, "g|h": 4, "i\\j": 5, "k\"l": 6, " ": 7, "m~n": 8 } )"); try { const json& result1 = jsonpointer::get(j, ""); std::cout << "(1) " << result1 << '\n'; const json& result2 = jsonpointer::get(j, "/foo"); std::cout << "(2) " << result2 << '\n'; const json& result3 = jsonpointer::get(j, "/foo/0"); std::cout << "(3) " << result3 << '\n'; const json& result4 = jsonpointer::get(j, "/"); std::cout << "(4) " << result4 << '\n'; const json& result5 = jsonpointer::get(j, "/a~1b"); std::cout << "(5) " << result5 << '\n'; const json& result6 = jsonpointer::get(j, "/c%d"); std::cout << "(6) " << result6 << '\n'; const json& result7 = jsonpointer::get(j, "/e^f"); std::cout << "(7) " << result7 << '\n'; const json& result8 = jsonpointer::get(j, "/g|h"); std::cout << "(8) " << result8 << '\n'; const json& result9 = jsonpointer::get(j, "/i\\j"); std::cout << "(9) " << result9 << '\n'; const json& result10 = jsonpointer::get(j, "/k\"l"); std::cout << "(10) " << result10 << '\n'; const json& result11 = jsonpointer::get(j, "/ "); std::cout << "(11) " << result11 << '\n'; const json& result12 = jsonpointer::get(j, "/m~0n"); std::cout << "(12) " << result12 << '\n'; } catch (const jsonpointer::jsonpointer_error& e) { std::cerr << e.what() << '\n'; } } void jsonpointer_contains() { // Example from RFC 6901 auto j = json::parse(R"( { "foo": ["bar", "baz"], "": 0, "a/b": 1, "c%d": 2, "e^f": 3, "g|h": 4, "i\\j": 5, "k\"l": 6, " ": 7, "m~n": 8 } )"); std::cout << "(1) " << jsonpointer::contains(j, "/foo/0") << '\n'; std::cout << "(2) " << jsonpointer::contains(j, "e^g") << '\n'; } void jsonpointer_select_author() { auto j = json::parse(R"( [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 } ] )"); // Using exceptions to report errors try { json result = jsonpointer::get(j, "/1/author"); std::cout << "(1) " << result << '\n'; } catch (const jsonpointer::jsonpointer_error& e) { std::cout << e.what() << '\n'; } // Using error codes to report errors std::error_code ec; const json& result = jsonpointer::get(j, "/0/title", ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << "(2) " << result << '\n'; } } void jsonpointer_add_member_to_object() { auto target = json::parse(R"( { "foo": "bar"} )"); std::error_code ec; jsonpointer::add_if_absent(target, "/baz", json("qux"), ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << target << '\n'; } } void jsonpointer_add_element_to_array() { auto target = json::parse(R"( { "foo": [ "bar", "baz" ] } )"); std::error_code ec; jsonpointer::add_if_absent(target, "/foo/1", json("qux"), ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << target << '\n'; } } void jsonpointer_add_element_to_end_array() { auto target = json::parse(R"( { "foo": [ "bar", "baz" ] } )"); std::error_code ec; jsonpointer::add_if_absent(target, "/foo/-", json("qux"), ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << target << '\n'; } } void jsonpointer_insert_name_exists() { auto target = json::parse(R"( { "foo": "bar", "baz" : "abc"} )"); std::error_code ec; jsonpointer::add_if_absent(target, "/baz", json("qux"), ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << target << '\n'; } } void jsonpointer_add_element_outside_range() { auto target = json::parse(R"( { "foo": [ "bar", "baz" ] } )"); std::error_code ec; jsonpointer::add(target, "/foo/3", json("qux"), ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << target << '\n'; } } void jsonpointer_insert_or_assign_name_exists() { auto target = json::parse(R"( { "foo": "bar", "baz" : "abc"} )"); std::error_code ec; jsonpointer::add(target, "/baz", json("qux"), ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << target << '\n'; } } void jsonpointer_remove_object_member() { auto target = json::parse(R"( { "foo": "bar", "baz" : "qux"} )"); std::error_code ec; jsonpointer::remove(target, "/baz", ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << target << '\n'; } } void jsonpointer_remove_array_element() { auto target = json::parse(R"( { "foo": [ "bar", "qux", "baz" ] } )"); std::error_code ec; jsonpointer::remove(target, "/foo/1", ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << target << '\n'; } } void jsonpointer_replace_object_value() { auto target = json::parse(R"( { "baz": "qux", "foo": "bar" } )"); std::error_code ec; jsonpointer::replace(target, "/baz", json("boo"), ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << target << '\n'; } } void jsonpointer_replace_array_value() { auto target = json::parse(R"( { "foo": [ "bar", "baz" ] } )"); std::error_code ec; jsonpointer::replace(target, "/foo/1", json("qux"), ec); if (ec) { std::cout << ec.message() << '\n'; } else { std::cout << pretty_print(target) << '\n'; } } void jsonpointer_error_example() { auto j = json::parse(R"( [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 } ] )"); try { json result = jsonpointer::get(j, "/1/isbn"); std::cout << "succeeded?" << '\n'; std::cout << result << '\n'; } catch (const jsonpointer::jsonpointer_error& e) { std::cout << "Caught jsonpointer_error with category " << e.code().category().name() << ", code " << e.code().value() << " and message \"" << e.what() << "\"" << '\n'; } } void jsonpointer_get_examples() { { json j(jsoncons::json_array_arg, {"baz","foo"}); json& item = jsonpointer::get(j,"/0"); std::cout << "(1) " << item << '\n'; } { const json j(jsoncons::json_array_arg, {"baz","foo"}); const json& item = jsonpointer::get(j,"/1"); std::cout << "(2) " << item << '\n'; } { json j(jsoncons::json_array_arg, {"baz","foo"}); std::error_code ec; json& item = jsonpointer::get(j,"/1",ec); std::cout << "(4) " << item << '\n'; } { const json j(jsoncons::json_array_arg, {"baz","foo"}); std::error_code ec; const json& item = jsonpointer::get(j,"/0",ec); std::cout << "(5) " << item << '\n'; } } void jsonpointer_address_example() { auto j = json::parse(R"( { "a/b": ["bar", "baz"], "m~n": ["foo", "qux"] } )"); jsonpointer::json_pointer ptr; ptr /= "m~n"; ptr /= "1"; std::cout << "(1) " << ptr << "\n\n"; std::cout << "(2)\n"; for (const auto& item : ptr) { std::cout << item << "\n"; } std::cout << "\n"; json item = jsonpointer::get(j, ptr); std::cout << "(3) " << item << "\n"; } void jsonpointer_address_iterator_example() { jsonpointer::json_pointer ptr("/store/book/1/author"); std::cout << "(1) " << ptr << "\n\n"; std::cout << "(2)\n"; for (const auto& token : ptr) { std::cout << token << "\n"; } std::cout << "\n"; } void jsonpointer_address_append_tokens() { jsonpointer::json_pointer ptr; ptr /= "a/b"; ptr /= ""; ptr /= "m~n"; std::cout << "(1) " << ptr << "\n\n"; std::cout << "(2)\n"; for (const auto& token : ptr) { std::cout << token << "\n"; } std::cout << "\n"; } void jsonpointer_address_concatenate() { jsonpointer::json_pointer ptr("/a~1b"); ptr += jsonpointer::json_pointer("//m~0n"); std::cout << "(1) " << ptr << "\n\n"; std::cout << "(2)\n"; for (const auto& token : ptr) { std::cout << token << "\n"; } std::cout << "\n"; } void flatten_and_unflatten() { json input = json::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 }, { "rater": "HikingAsylum", "assertion": "intermediate", "rated": "Hongmin", "rating": 0.75 } ] } )"); json flattened = jsonpointer::flatten(input); std::cout << pretty_print(flattened) << "\n\n"; json unflattened = jsonpointer::unflatten(flattened); assert(unflattened == input); } void flatten_and_unflatten2() { json input = json::parse(R"( { "discards": { "1000": "Record does not exist", "1004": "Queue limit exceeded", "1010": "Discarding timed-out partial msg" }, "warnings": { "0": "Phone number missing country code", "1": "State code missing", "2": "Zip code missing" } } )"); json flattened = jsonpointer::flatten(input); std::cout << "(1)\n" << pretty_print(flattened) << "\n"; json unflattened1 = jsonpointer::unflatten(flattened); std::cout << "(2)\n" << pretty_print(unflattened1) << "\n"; json unflattened2 = jsonpointer::unflatten(flattened, jsonpointer::unflatten_options::assume_object); std::cout << "(3)\n" << pretty_print(unflattened2) << "\n"; } void get_and_create_if_missing() { std::vector keys = {"foo","bar","baz"}; jsonpointer::json_pointer ptr; for (const auto& key : keys) { ptr /= key; } json doc; json result = jsonpointer::get(doc, ptr, true); std::cout << pretty_print(doc) << "\n\n"; } void add_and_create_if_missing() { std::vector keys = {"foo","bar","baz"}; jsonpointer::json_pointer ptr; for (const auto& key : keys) { ptr /= key; } json doc; jsonpointer::add(doc, ptr, "str", true); std::cout << pretty_print(doc) << "\n\n"; } void add_if_absent_and_create_if_missing() { std::vector keys = { "foo","bar","baz" }; jsonpointer::json_pointer ptr; for (const auto& key : keys) { ptr /= key; } json doc; jsonpointer::add_if_absent(doc, ptr, "str", true); std::cout << pretty_print(doc) << "\n\n"; } void replace_and_create_if_missing() { std::vector keys = {"foo","bar","baz"}; jsonpointer::json_pointer ptr; for (const auto& key : keys) { ptr /= key; } json doc; jsonpointer::replace(doc, ptr, "str", true); std::cout << pretty_print(doc) << "\n\n"; } int main() { std::cout << "\njsonpointer examples\n\n"; jsonpointer_select_author(); jsonpointer_address_example(); jsonpointer_select_RFC6901(); jsonpointer_add_member_to_object(); jsonpointer_add_element_to_array(); jsonpointer_add_element_to_end_array(); jsonpointer_add_element_outside_range(); jsonpointer_remove_object_member(); jsonpointer_remove_array_element(); jsonpointer_replace_object_value(); jsonpointer_replace_array_value(); jsonpointer_contains(); jsonpointer_error_example(); jsonpointer_insert_name_exists(); jsonpointer_insert_or_assign_name_exists(); jsonpointer_get_examples(); jsonpointer_address_iterator_example(); jsonpointer_address_append_tokens(); jsonpointer_address_concatenate(); flatten_and_unflatten(); flatten_and_unflatten2(); get_and_create_if_missing(); add_and_create_if_missing(); add_if_absent_and_create_if_missing(); replace_and_create_if_missing(); } jsoncons-1.3.2/examples/src/jsonschema_examples.cpp000066400000000000000000000360231477700171100225230ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include // for brevity using jsoncons::json; using jsoncons::ojson; namespace jsonschema = jsoncons::jsonschema; namespace jsonpatch = jsoncons::jsonpatch; void validate_three_ways() { std::string schema_str = R"( { "$id": "https://example.com/arrays.schema.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "description": "A representation of a person, company, organization, or place", "type": "object", "properties": { "fruits": { "type": "array", "items": { "type": "string" } }, "vegetables": { "type": "array", "items": { "$ref": "#/$defs/veggie" } } }, "$defs": { "veggie": { "type": "object", "required": [ "veggieName", "veggieLike" ], "properties": { "veggieName": { "type": "string", "description": "The name of the vegetable." }, "veggieLike": { "type": "boolean", "description": "Do I like this vegetable?" } } } } } )"; std::string data_str = R"( { "fruits": [ "apple", "orange", "pear" ], "vegetables": [ { "veggieName": "potato", "veggieLike": true }, { "veggieName": "broccoli", "veggieLike": "false" }, { "veggieName": "carrot", "veggieLike": false }, { "veggieName": "Swiss Chard" } ] } )"; ojson schema = ojson::parse(schema_str); jsonschema::json_schema compiled = jsonschema::make_json_schema(std::move(schema)); ojson data = ojson::parse(data_str); std::cout << "\n(1) Validate using exceptions\n"; try { compiled.validate(data); } catch (const std::exception& e) { std::cout << e.what() << "\n"; } std::cout << "\n(2) Validate using reporter callback\n"; auto reporter = [](const jsonschema::validation_message& msg) -> jsonschema::walk_result { std::cout << msg.instance_location().string() << ": " << msg.message() << "\n"; return jsonschema::walk_result::advance; }; compiled.validate(data, reporter); std::cout << "\n(3) Validate outputting to a json decoder\n"; jsoncons::json_decoder decoder; compiled.validate(data, decoder); ojson output = decoder.get_result(); std::cout << pretty_print(output) << "\n"; } // Until 0.174.0, throw a `schema_error` instead of returning json::null() void resolve_uri_example() { std::string main_schema = R"( { "$id" : "https://www.example.com/main", "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://localhost:1234/draft2020-12/object", "type": "object", "properties": { "name": {"$ref": "/name-defs.json#/$defs/orNull"} } } )"; std::string root_dir = "./input/jsonschema"; auto resolver = [&](const jsoncons::uri& uri) -> json { std::cout << "Requested URI: " << uri.string() << "\n"; std::cout << "base: " << uri.base().string() << ", path: " << uri.path() << "\n\n"; std::string pathname = root_dir + uri.path(); std::fstream is(pathname.c_str()); if (!is) { return json::null(); } return json::parse(is); }; json schema = json::parse(main_schema); // Data json data = json::parse(R"( { "name": { "name": null } } )"); try { // Throws schema_error if JSON Schema compilation fails jsonschema::json_schema compiled = jsonschema::make_json_schema(schema, resolver); auto report = [](const jsonschema::validation_message& msg) -> jsonschema::walk_result { std::cout << msg.instance_location().string() << ": " << msg.message() << "\n"; for (const auto& detail : msg.details()) { std::cout << " " << detail.message() << "\n"; } return jsonschema::walk_result::advance; }; // Will call report function object for each schema violation compiled.validate(data, report); } catch (const std::exception& e) { std::cout << e.what() << '\n'; } } void defaults_example() { json schema = json::parse(R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "bar": { "type": "string", "minLength": 4, "default": "bad" } } } )"); try { // Data json data = json::parse("{}"); // will throw schema_error if JSON Schema compilation fails jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); // will throw a validation_error when a schema violation happens json patch; compiled.validate(data, patch); std::cout << "Patch: " << patch << "\n"; std::cout << "Original data: " << data << "\n"; jsonpatch::apply_patch(data, patch); std::cout << "Patched data: " << data << "\n\n"; } catch (const std::exception& e) { std::cout << e.what() << "\n"; } } #if defined(JSONCONS_HAS_STD_VARIANT) #include namespace ns { struct os_properties { std::string command; }; struct db_properties { std::string query; }; struct api_properties { std::string target; }; struct job_properties { std::string name; std::variant run; }; } // namespace ns JSONCONS_N_MEMBER_TRAITS(ns::os_properties, 1, command) JSONCONS_N_MEMBER_TRAITS(ns::db_properties, 1, query) JSONCONS_N_MEMBER_TRAITS(ns::api_properties, 1, target) JSONCONS_N_MEMBER_TRAITS(ns::job_properties, 2, name, run) void validate_before_decode_example() { std::string schema_str = R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "job", "description": "job properties json schema", "$defs": { "os_properties": { "type": "object", "properties": { "command": { "description": "this is the OS command to run", "type": "string", "minLength": 1 } }, "required": [ "command" ], "additionalProperties": false }, "db_properties": { "type": "object", "properties": { "query": { "description": "this is db query to run", "type": "string", "minLength": 1 } }, "required": [ "query" ], "additionalProperties": false }, "api_properties": { "type": "object", "properties": { "target": { "description": "this is api target to run", "type": "string", "minLength": 1 } }, "required": [ "target" ], "additionalProperties": false } }, "type": "object", "properties": { "name": { "description": "name of the flow", "type": "string", "minLength": 1 }, "run": { "description": "job run properties", "type": "object", "oneOf": [ { "$ref": "#/$defs/os_properties" }, { "$ref": "#/$defs/db_properties" }, { "$ref": "#/$defs/api_properties" } ] } }, "required": [ "name", "run" ], "additionalProperties": false } )"; std::string data_str = R"( { "name": "testing flow", "run" : { "command": "some command" } } )"; try { json schema = json::parse(schema_str); // Throws schema_error if JSON Schema compilation fails jsonschema::json_schema compiled = jsonschema::make_json_schema(std::move(schema)); // Test that input is valid before attempting to decode json data = json::parse(data_str); if (compiled.is_valid(data)) { const ns::job_properties v = data.as(); std::string output; jsoncons::encode_json_pretty(v, output); std::cout << output << '\n'; // Verify that output is valid json test = json::parse(output); assert(compiled.is_valid(test)); } else { std::cout << "Invalid input\n"; } } catch (const std::exception& e) { std::cout << e.what() << '\n'; } } #endif // JSONCONS_HAS_STD_VARIANT void draft_201212_example() { json schema = json::parse(R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://test.json-schema.org/typical-dynamic-resolution/root", "$ref": "list", "$defs": { "foo": { "$dynamicAnchor": "items", "type": "string" }, "list": { "$id": "list", "type": "array", "items": { "$dynamicRef": "#items" }, "$defs": { "items": { "$comment": "This is only needed to satisfy the bookending requirement", "$dynamicAnchor": "items" } } } } } )"); jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); json data = json::parse(R"(["foo", 42])"); jsoncons::json_decoder decoder; compiled.validate(data, decoder); ojson output = decoder.get_result(); std::cout << pretty_print(output) << "\n\n"; } void draft_201909_example() { json schema = json::parse(R"( { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "properties": { "bar": { "type": "string" } } } ], "unevaluatedProperties": false } )"); jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); json data = json::parse(R"({"foo": "foo","bar": "bar","baz": "baz"})"); jsoncons::json_decoder decoder; compiled.validate(data, decoder); ojson output = decoder.get_result(); std::cout << pretty_print(output) << "\n\n"; } void draft_07_example() { json schema = json::parse(R"( { "items": [{}], "additionalItems": {"type": "integer"} } )"); // Need to supply default version because schema does not have $schema keyword auto options = jsonschema::evaluation_options{} .default_version(jsonschema::schema_version::draft7()); auto compiled = jsonschema::make_json_schema(schema, options); json data = json::parse(R"([ null, 2, 3, "foo" ])"); jsoncons::json_decoder decoder; compiled.validate(data, decoder); ojson output = decoder.get_result(); std::cout << pretty_print(output) << "\n\n"; } void cross_schema_example() { json schema = json::parse(R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://example.com/schema", "$defs": { "foo": { "$schema": "http://json-schema.org/draft-07/schema#", "$id": "schema/foo", "definitions" : { "bar" : { "type" : "string" } } } }, "properties" : { "thing" : { "$ref" : "schema/foo#/definitions/bar" } } } )"); jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); json data = json::parse(R"({"thing" : 10})"); jsoncons::json_decoder decoder; compiled.validate(data, decoder); ojson output = decoder.get_result(); std::cout << pretty_print(output) << "\n\n"; } void optional_format_example() { json schema = json::parse(R"( { "$id": "/schema_str", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "Date": { "format": "date-time", "type": "string" } }, "required": [ "Date" ], "type": "object", "unevaluatedProperties": false } )"); auto compiled = jsoncons::jsonschema::make_json_schema(schema, jsonschema::evaluation_options{}.require_format_validation(true)); json data = json::parse(R"( { "Date" : "2024-03-19T26:34:56Z" } )"); jsoncons::json_decoder decoder; compiled.validate(data, decoder); ojson output = decoder.get_result(); std::cout << pretty_print(output) << "\n"; } void walk_example() // since 0.175.0 { std::string schema_str = R"( { "$id": "https://example.com/arrays.schema.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "description": "A representation of a person, company, organization, or place", "type": "object", "properties": { "fruits": { "type": "array", "items": { "type": "string" } }, "vegetables": { "type": "array", "items": { "$ref": "#/$defs/veggie" } } }, "$defs": { "veggie": { "type": "object", "required": [ "veggieName", "veggieLike" ], "properties": { "veggieName": { "type": "string", "description": "The name of the vegetable." }, "veggieLike": { "type": "boolean", "description": "Do I like this vegetable?" } } } } } )"; ojson schema = ojson::parse(schema_str); jsonschema::json_schema compiled = jsonschema::make_json_schema(std::move(schema)); std::string data_str = R"( { "fruits": [ "apple", "orange", "pear" ], "vegetables": [ { "veggieName": "potato", "veggieLike": true }, { "veggieName": "broccoli", "veggieLike": false } ] } )"; // Data ojson data = ojson::parse(data_str); auto reporter = [](const std::string& keyword, const ojson& schema, const jsoncons::uri& /*schema_location*/, const ojson& /*instance*/, const jsoncons::jsonpointer::json_pointer& instance_location) -> jsonschema::walk_result { if (keyword == "type") { assert(schema.is_object()); auto it = schema.find("type"); if (it != schema.object_range().end()) { std::cout << instance_location.string() << ": " << it->value() << "\n"; } } return jsonschema::walk_result::advance; }; compiled.walk(data, reporter); } int main() { std::cout << "\nJSON Schema Examples\n\n"; validate_three_ways(); std::cout << "\n"; #if defined(JSONCONS_HAS_STD_VARIANT) validate_before_decode_example(); #endif defaults_example(); optional_format_example(); draft_201212_example(); draft_201909_example(); draft_07_example(); cross_schema_example(); walk_example(); resolve_uri_example(); std::cout << "\n"; } jsoncons-1.3.2/examples/src/msgpack_examples.cpp000066400000000000000000000130731477700171100220160ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include // For brevity using jsoncons::json; using jsoncons::ojson; namespace msgpack = jsoncons::msgpack; void example1() { ojson j1 = ojson::parse(R"( [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 } ] )"); std::vector v; msgpack::encode_msgpack(j1, v); ojson j2 = msgpack::decode_msgpack(v); std::cout << pretty_print(j2) << '\n'; json j3 = msgpack::decode_msgpack(v); std::cout << pretty_print(j3) << '\n'; std::cout << '\n'; //wjson j4 = msgpack::decode_msgpack(v); //std::wcout << pretty_print(j4) << '\n'; //std::cout << '\n'; } void example2() { ojson j1; j1["zero"] = 0; j1["one"] = 1; j1["two"] = 2; j1["null"] = jsoncons::null_type(); j1["true"] = true; j1["false"] = false; j1["max int64_t"] = (std::numeric_limits::max)(); j1["max uint64_t"] = (std::numeric_limits::max)(); j1["min int64_t"] = (std::numeric_limits::lowest)(); j1["max int32_t"] = (std::numeric_limits::max)(); j1["max uint32_t"] = (std::numeric_limits::max)(); j1["min int32_t"] = (std::numeric_limits::lowest)(); j1["max int16_t"] = (std::numeric_limits::max)(); j1["max uint16_t"] = (std::numeric_limits::max)(); j1["min int16_t"] = (std::numeric_limits::lowest)(); j1["max int8_t"] = (std::numeric_limits::max)(); j1["max uint8_t"] = (std::numeric_limits::max)(); j1["min int8_t"] = (std::numeric_limits::lowest)(); j1["max double"] = (std::numeric_limits::max)(); j1["min double"] = (std::numeric_limits::lowest)(); j1["max float"] = (std::numeric_limits::max)(); j1["zero float"] = 0.0; j1["min float"] = (std::numeric_limits::lowest)(); j1["Key too long for small string optimization"] = "String too long for small string optimization"; std::vector v; msgpack::encode_msgpack(j1, v); ojson j2 = msgpack::decode_msgpack(v); std::cout << pretty_print(j2) << '\n'; std::cout << '\n'; } void ext_example() { std::vector input = { 0x82, // map, length 2 0xa5, // string, length 5 'H','e','l','l','o', 0xa5, // string, length 5 'W','o','r','l','d', 0xa4, // string, length 4 'D','a','t','a', 0xc7, // ext8 format code 0x06, // length 6 0x07, // type 'f','o','o','b','a','r' }; ojson j = msgpack::decode_msgpack(input); std::cout << "(1)\n" << pretty_print(j) << "\n\n"; std::cout << "(2) " << j["Data"].tag() << "(" << j["Data"].ext_tag() << ")\n\n"; // Get ext value as a std::vector auto v = j["Data"].as>(); std::cout << "(3)\n"; std::cout << jsoncons::byte_string_view(v) << "\n\n"; std::vector output; msgpack::encode_msgpack(j,output); assert(output == input); } void duration_example1() { std::vector data = { 0xd6, // fixext 4 stores an integer and a byte array whose length is 4 bytes 0xff, // timestamp 0x5a,0x4a,0xf6,0xa5 // 1514862245 }; auto seconds = msgpack::decode_msgpack(data); std::cout << "Seconds elapsed since 1970-01-01 00:00:00 UTC: " << seconds.count() << "\n"; } void duration_example2() { auto duration = std::chrono::system_clock::now().time_since_epoch(); auto dur_nano = std::chrono::duration_cast(duration); std::vector data; msgpack::encode_msgpack(dur_nano, data); std::cout << "MessagePack bytes:\n" << jsoncons::byte_string_view(data) << "\n\n"; /* d7, ff, // timestamp 64 e3,94,56,e0, // nanoseconds in 30-bit unsigned int 5f,22,b6,8b // seconds in 34-bit unsigned int */ auto nanoseconds = msgpack::decode_msgpack(data); std::cout << "nanoseconds elapsed since 1970-01-01 00:00:00 UTC: " << nanoseconds.count() << "\n"; auto milliseconds = msgpack::decode_msgpack(data); std::cout << "milliseconds elapsed since 1970-01-01 00:00:00 UTC: " << milliseconds.count() << "\n"; auto seconds = msgpack::decode_msgpack(data); std::cout << "seconds elapsed since 1970-01-01 00:00:00 UTC: " << seconds.count() << "\n"; } void duration_example3() { std::vector input = { 0xc7,0x0c,0xff, // timestamp 96 0x3b,0x9a,0xc9,0xff, // 999999999 nanoseconds in 32-bit unsigned int 0xff,0xff,0xff,0xff,0x7c,0x55,0x81,0x7f // -2208988801 seconds in 64-bit signed int }; auto milliseconds = msgpack::decode_msgpack(input); std::cout << "milliseconds elapsed since 1970-01-01 00:00:00 UTC: " << milliseconds.count() << "\n"; auto seconds = msgpack::decode_msgpack(input); std::cout << "seconds elapsed since 1970-01-01 00:00:00 UTC: " << seconds.count() << "\n"; } int main() { std::cout << "\nmsgpack examples\n\n"; example1(); example2(); ext_example(); duration_example1(); duration_example2(); duration_example3(); std::cout << '\n'; } jsoncons-1.3.2/examples/src/ojson_examples.cpp000066400000000000000000000015341477700171100215200ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include using namespace jsoncons; int main() { std::cout << "\nojson examples\n\n"; ojson o = ojson::parse(R"( { "street_number" : "100", "street_name" : "Queen St W", "city" : "Toronto", "country" : "Canada" } )"); std::cout << pretty_print(o) << '\n'; o.insert_or_assign("postal_code", "M5H 2N2"); std::cout << pretty_print(o) << '\n'; ojson o2 = o; ojson o3 = o; o3["street_name"] = "Queen St W"; auto it = o.find("country"); o.insert_or_assign(it,"province","Ontario"); o.insert_or_assign("unit_type","O"); std::cout << pretty_print(o) << '\n'; o.erase("unit_type"); std::cout << pretty_print(o) << '\n'; std::cout << '\n'; } jsoncons-1.3.2/examples/src/pmr_allocator_examples.cpp000066400000000000000000000122141477700171100232230ustar00rootroot00000000000000#include #include #include #include #include #include void propagtion() { char buffer[1024]; std::pmr::monotonic_buffer_resource pool{ std::data(buffer), std::size(buffer) }; std::pmr::polymorphic_allocator alloc(&pool); std::string key = "key too long for short string"; std::string value = "string too long for short string"; jsoncons::pmr::json j{ jsoncons::json_object_arg, alloc }; assert(j.get_allocator().resource() == &pool); j.try_emplace(key, value); auto it = std::search(std::begin(buffer), std::end(buffer), key.begin(), key.end()); assert(it != std::end(buffer)); it = std::search(std::begin(buffer), std::end(buffer), value.begin(), value.end()); assert(it != std::end(buffer)); } void copy_construction() { char buffer[1024]; std::pmr::monotonic_buffer_resource pool{ std::data(buffer), std::size(buffer) }; std::pmr::polymorphic_allocator alloc(&pool); jsoncons::pmr::json j{ "String too long for short string", alloc }; assert(j.is_string()); assert(j.get_allocator().resource() == &pool); jsoncons::pmr::json j1(j); assert(j1 == j); assert(j1.get_allocator() == std::allocator_traits>:: select_on_container_copy_construction(j.get_allocator())); assert(j1.get_allocator() == std::pmr::polymorphic_allocator{}); // expected result for pmr allocators } void allocator_extended_copy_construction() // extended copy { char buffer[1024]; std::pmr::monotonic_buffer_resource pool{ std::data(buffer), std::size(buffer) }; std::pmr::polymorphic_allocator alloc(&pool); char buffer1[1024]; std::pmr::monotonic_buffer_resource pool1{ std::data(buffer1), std::size(buffer1) }; std::pmr::polymorphic_allocator alloc1(&pool1); jsoncons::pmr::json j{ "String too long for short string", alloc }; assert(j.is_string()); assert(j.get_allocator().resource() == &pool); jsoncons::pmr::json j1(j, alloc1); assert(j1 == j); assert(j1.get_allocator().resource() == &pool1); } void move_construction() // move { char buffer[1024]; std::pmr::monotonic_buffer_resource pool{ std::data(buffer), std::size(buffer) }; std::pmr::polymorphic_allocator alloc(&pool); jsoncons::pmr::json j{ "String too long for short string", alloc}; assert(j.is_string()); assert(j.get_allocator().resource() == &pool); jsoncons::pmr::json j1(std::move(j)); assert(j1.is_string()); assert(j1.get_allocator().resource() == &pool); assert(j.is_null()); } void allocator_extended_move_construction() // move { char buffer[1024]; std::pmr::monotonic_buffer_resource pool{ std::data(buffer), std::size(buffer) }; std::pmr::polymorphic_allocator alloc(&pool); char buffer1[1024]; std::pmr::monotonic_buffer_resource pool1{ std::data(buffer1), std::size(buffer1) }; std::pmr::polymorphic_allocator alloc1(&pool1); jsoncons::pmr::json j{ "String too long for short string", alloc }; assert(j.is_string()); assert(j.get_allocator().resource() == &pool); jsoncons::pmr::json j1(std::move(j), alloc1); assert(j1.is_string()); assert(j1.get_allocator().resource() == &pool1); } void copy_assignment() // assignment { char buffer[1024]; std::pmr::monotonic_buffer_resource pool{ std::data(buffer), std::size(buffer) }; std::pmr::polymorphic_allocator alloc(&pool); char buffer1[1024]; std::pmr::monotonic_buffer_resource pool1{ std::data(buffer1), std::size(buffer1) }; std::pmr::polymorphic_allocator alloc1(&pool1); jsoncons::pmr::json j{ "String too long for short string", alloc }; assert(j.is_string()); assert(j.get_allocator().resource() == &pool); // copy long string to number jsoncons::pmr::json j1{10}; j1 = j; assert(j1.is_string()); assert(j1.get_allocator() == std::allocator_traits>:: select_on_container_copy_construction(j.get_allocator())); assert(j1.get_allocator() == std::pmr::polymorphic_allocator{}); // copy long string to array jsoncons::pmr::json j2{ jsoncons::json_array_arg, {1,2,3,4}, jsoncons::semantic_tag::none, alloc1}; j2 = j; assert(j2.is_string()); assert(j2.get_allocator().resource() == &pool1); } void move_assignment() // assignment { char buffer[1024]; std::pmr::monotonic_buffer_resource pool{ std::data(buffer), std::size(buffer) }; std::pmr::polymorphic_allocator alloc(&pool); jsoncons::pmr::json j{ "String too long for short string", alloc }; assert(j.is_string()); assert(j.get_allocator().resource() == &pool); jsoncons::pmr::json j1{ 10 }; assert(j1.is_number()); j1 = std::move(j); assert(j1.is_string()); assert(j1.get_allocator().resource() == &pool); assert(j.is_number()); } int main() { propagtion(); copy_construction(); allocator_extended_copy_construction(); move_construction(); allocator_extended_move_construction(); copy_assignment(); move_assignment(); } jsoncons-1.3.2/examples/src/readme_examples.cpp000066400000000000000000000251051477700171100216250ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include "sample_types.hpp" #include #include #include #include using namespace jsoncons; void as_a_variant_like_structure() { // Some JSON input data std::string data = R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90, "generated": 1514862245 } ] } )"; // Parse the string of data into a json value json j = json::parse(data); // Does object member reputons exist? std::cout << "(1) " << std::boolalpha << j.contains("reputons") << "\n\n"; // Get a reference to reputons array const json& v = j["reputons"]; // Iterate over reputons array std::cout << "(2)\n"; for (const auto& item : v.array_range()) { // Access rated as string and rating as double std::cout << item["rated"].as() << ", " << item["rating"].as() << "\n"; } std::cout << "\n"; // Select all "rated" with JSONPath std::cout << "(3)\n"; json result = jsonpath::json_query(j,"$..rated"); std::cout << pretty_print(result) << "\n\n"; // Serialize back to JSON std::cout << "(4)\n" << pretty_print(j) << "\n\n"; } void as_a_strongly_typed_cpp_structure() { // Some JSON input data std::string data = R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90, "generated": 1514862245 } ] } )"; // Decode the string of data into a c++ structure ns::hiking_reputation v = decode_json(data); // Iterate over reputons array value std::cout << "(1)\n"; for (const auto& item : v.reputons()) { std::cout << item.rated() << ", " << item.rating(); if (item.generated()) { std::cout << ", " << (*item.generated()).count(); } std::cout << "\n"; } // Encode the c++ structure into a string std::string s; encode_json(v, s, indenting::indent); std::cout << "(2)\n"; std::cout << s << "\n"; } void with_cursor_level_access() { // Some JSON input data std::string data = R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90, "generated": 1514862245 } ] } )"; json_string_cursor cursor(data); for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::end_array: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::begin_object: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::end_object: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::key: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::string_value: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::null_value: std::cout << event.event_type() << "\n"; break; case staj_event_type::bool_value: std::cout << event.event_type() << ": " << std::boolalpha << event.get() << "\n"; break; case staj_event_type::int64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::double_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; default: std::cout << "Unhandled event type: " << event.event_type() << " " << "\n"; break; } } } void as_a_filtered_stream_of_json_events() { // Some JSON input data std::string data = R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90, "generated": 1514862245 } ] } )"; std::string name; auto filter = [&](const staj_event& ev, const ser_context&) -> bool { if (ev.event_type() == staj_event_type::key) { name = ev.get(); return false; } if (name == "rated") { name.clear(); return true; } return false; }; json_string_cursor cursor(data); auto filtered_c = cursor | filter; for (; !filtered_c.done(); filtered_c.next()) { const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::string_value: std::cout << event.get() << "\n"; break; default: std::cout << "Unhandled event type: " << event.event_type() << " " << "\n"; break; } } } void playing_around() { // Construct some CBOR using the streaming API std::vector bytes_in; cbor::cbor_bytes_encoder encoder(bytes_in); encoder.begin_array(); // indefinite length outer array encoder.begin_array(3); // a fixed length array encoder.string_value("foo"); encoder.byte_string_value(std::vector{'P','u','s','s'}); // no suggested conversion encoder.string_value("-18446744073709551617", semantic_tag::bigint); encoder.end_array(); encoder.end_array(); encoder.flush(); // Print bytes std::cout << "(1)\n" << byte_string_view(bytes_in) << "\n\n"; /* 9f -- Start indefinte length array 83 -- Array of length 3 63 -- String value of length 3 666f6f -- "foo" 44 -- Byte string value of length 4 50757373 -- 'P''u''s''s' c3 -- Tag 3 (negative bignum) 49 -- Byte string value of length 9 010000000000000000 -- Bytes content ff -- "break" */ // Unpack bytes into a json variant value, and add some more elements json j = cbor::decode_cbor(bytes_in); // Loop over the rows std::cout << "(2)\n"; for (const json& row : j.array_range()) { std::cout << row << "\n"; } std::cout << "\n"; // Get bignum value at position 0/2 using jsonpointer json& v = jsonpointer::get(j, "/0/2"); std::cout << "(3) " << v.as() << "\n\n"; // Print JSON representation with default options std::cout << "(4)\n"; std::cout << pretty_print(j) << "\n\n"; // Print JSON representation with different options auto options = json_options{} .byte_string_format(byte_string_chars_format::base64) .bignum_format(bignum_format_kind::base64url); std::cout << "(5)\n"; std::cout << pretty_print(j, options) << "\n\n"; // Add some more elements json another_array(json_array_arg); another_array.emplace_back(byte_string_arg, std::vector({'P','u','s','s'}), semantic_tag::base64); // suggested conversion to base64 another_array.emplace_back("273.15", semantic_tag::bigdec); another_array.emplace(another_array.array_range().begin(),"bar"); // place at front j.push_back(std::move(another_array)); std::cout << "(6)\n"; std::cout << pretty_print(j) << "\n\n"; // Get big decimal value at position /1/2 using jsonpointer json& ref = jsonpointer::get(j, "/1/2"); std::cout << "(7) " << ref.as() << "\n\n"; #if (defined(__GNUC__) || defined(__clang__)) && defined(JSONCONS_HAS_INT128) // e.g. if code compiled with GCC and std=gnu++11 (rather than std=c++11) __int128 i = j[1][2].as<__int128>(); #endif // Get byte string value at position /1/1 as a std::vector auto bstr = j[1][1].as>(); std::cout << "(8) " << byte_string_view(bstr) << "\n\n"; // Repack bytes std::vector bytes_out; cbor::encode_cbor(j, bytes_out); // Print the repacked bytes std::cout << "(9)\n" << byte_string_view(bytes_out) << "\n\n"; /* 82 -- Array of length 2 83 -- Array of length 3 63 -- String value of length 3 666f6f -- "foo" 44 -- Byte string value of length 4 50757373 -- 'P''u''s''s' c3 -- Tag 3 (negative bignum) 49 -- Byte string value of length 9 010000000000000000 -- Bytes content 83 -- Another array of length 3 63 -- String value of length 3 626172 -- "bar" d6 - Expected conversion to base64 44 -- Byte string value of length 4 50757373 -- 'P''u''s''s' c4 -- Tag 4 (decimal fraction) 82 -- Array of length 2 21 -- -2 19 6ab3 -- 27315 */ // Encode to CSV auto csv_options = csv::csv_options{} .column_names("Column 1,Column 2,Column 3"); std::cout << "(10)\n"; csv::encode_csv(j, std::cout, csv_options); } int main() { std::cout << "\nReadme examples\n\n"; playing_around(); as_a_variant_like_structure(); as_a_strongly_typed_cpp_structure(); with_cursor_level_access(); as_a_filtered_stream_of_json_events(); std::cout << '\n'; } jsoncons-1.3.2/examples/src/sample_types.hpp000066400000000000000000000156031477700171100212060ustar00rootroot00000000000000#ifndef EXAMPLE_TYPES #define EXAMPLE_TYPES #include #include #include // book example namespace ns { struct bond { double principal; std::string maturity; double coupon; std::string period; }; struct employee { std::string employeeNo; std::string name; std::string title; }; class fixing { std::string index_id_; std::string observation_date_; double rate_; public: fixing(const std::string& index_id, const std::string& observation_date, double rate) : index_id_(index_id), observation_date_(observation_date), rate_(rate) { } const std::string& index_id() const {return index_id_;} const std::string& observation_date() const {return observation_date_;} double rate() const {return rate_;} }; struct book { std::string author; std::string title; double price; }; class Person { public: Person(const std::string& name, const std::string& surname, const std::string& ssn, unsigned int age) : name(name), surname(surname), ssn(ssn), age(age) { } bool operator==(const Person& rhs) const { return name == rhs.name && surname == rhs.surname && ssn == rhs.ssn && age == rhs.age; } bool operator!=(const Person& rhs) const { return !(rhs == *this); } private: // Make json_type_traits specializations friends to give accesses to private members JSONCONS_TYPE_TRAITS_FRIEND Person() : age(0) {} std::string name; std::string surname; std::string ssn; unsigned int age; }; enum class hiking_experience {beginner,intermediate,advanced}; class hiking_reputon { std::string rater_; hiking_experience assertion_; std::string rated_; double rating_; jsoncons::optional generated_; // use std::optional if C++17 jsoncons::optional expires_; public: hiking_reputon(const std::string& rater, hiking_experience assertion, const std::string& rated, double rating, const jsoncons::optional& generated = jsoncons::optional(), const jsoncons::optional& expires = jsoncons::optional()) : rater_(rater), assertion_(assertion), rated_(rated), rating_(rating), generated_(generated), expires_(expires) { } const std::string& rater() const {return rater_;} hiking_experience assertion() const {return assertion_;} const std::string& rated() const {return rated_;} double rating() const {return rating_;} jsoncons::optional generated() const {return generated_;} jsoncons::optional expires() const {return expires_;} friend bool operator==(const hiking_reputon& lhs, const hiking_reputon& rhs) { return lhs.rater_ == rhs.rater_ && lhs.assertion_ == rhs.assertion_ && lhs.rated_ == rhs.rated_ && lhs.rating_ == rhs.rating_ && lhs.generated_ == rhs.generated_ && lhs.expires_ == rhs.expires_; } friend bool operator!=(const hiking_reputon& lhs, const hiking_reputon& rhs) { return !(lhs == rhs); }; }; class hiking_reputation { std::string application_; std::vector reputons_; public: hiking_reputation(const std::string& application, const std::vector& reputons) : application_(application), reputons_(reputons) {} const std::string& application() const { return application_;} const std::vector& reputons() const { return reputons_;} friend bool operator==(const hiking_reputation& lhs, const hiking_reputation& rhs) { return (lhs.application_ == rhs.application_) && (lhs.reputons_ == rhs.reputons_); } friend bool operator!=(const hiking_reputation& lhs, const hiking_reputation& rhs) { return !(lhs == rhs); }; }; template struct TemplatedStruct { T1 aT1; T2 aT2; friend bool operator==(const TemplatedStruct& lhs, const TemplatedStruct& rhs) { return lhs.aT1 == rhs.aT1 && lhs.aT2 == rhs.aT2; } friend bool operator!=(const TemplatedStruct& lhs, const TemplatedStruct& rhs) { return !(lhs == rhs); } }; } // namespace ns namespace jsoncons { template struct json_type_traits { using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return j.is_object() && j.contains("author") && j.contains("title") && j.contains("price"); } static ns::book as(const Json& j) { ns::book val; val.author = j.at("author").template as(); val.title = j.at("title").template as(); val.price = j.at("price").template as(); return val; } static Json to_json(const ns::book& val, allocator_type alloc=allocator_type()) { Json j(json_object_arg, semantic_tag::none, alloc); j.try_emplace("author", val.author); j.try_emplace("title", val.title); j.try_emplace("price", val.price); return j; } }; } // namespace jsoncons // Declare the traits. Specify which data members need to be serialized. JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::bond, (principal,"notional"), (maturity,"maturityDate"), (coupon,"couponRate"), (period,"frequency")) JSONCONS_ENUM_TRAITS(ns::hiking_experience, beginner, intermediate, advanced) // First four members listed are mandatory, generated and expires are optional JSONCONS_N_CTOR_GETTER_TRAITS(ns::hiking_reputon, 4, rater, assertion, rated, rating, generated, expires) // All members are mandatory JSONCONS_ALL_CTOR_GETTER_TRAITS(ns::hiking_reputation, application, reputons) JSONCONS_ALL_CTOR_GETTER_TRAITS(ns::fixing, index_id, observation_date, rate) JSONCONS_ALL_MEMBER_TRAITS(ns::employee, employeeNo, name, title) // Declare the traits. Specify which data members need to be serialized. JSONCONS_ALL_MEMBER_TRAITS(ns::Person, name, surname, ssn, age) JSONCONS_TPL_ALL_MEMBER_TRAITS(2,ns::TemplatedStruct,aT1,aT2) #endif jsoncons-1.3.2/examples/src/staj_iterator_examples.cpp000066400000000000000000000035201477700171100232370ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include "sample_types.hpp" using namespace jsoncons; // Example JSON text const std::string array_example = R"( [ { "employeeNo" : "101", "name" : "Tommy Cochrane", "title" : "Supervisor" }, { "employeeNo" : "102", "name" : "Bill Skeleton", "title" : "Line manager" } ] )"; const std::string object_example = R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum.array_example.com", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 } ] } )"; void staj_array_iterator_example() { std::istringstream is(array_example); json_stream_cursor cursor(is); auto view = staj_array(cursor); for (const auto& j : view) { std::cout << pretty_print(j) << "\n"; } std::cout << "\n\n"; } void staj_array_iterator_example2() { std::istringstream is(array_example); json_stream_cursor cursor(is); auto view = staj_array(cursor); for (const auto& val : view) { std::cout << val.employeeNo << ", " << val.name << ", " << val.title << "\n"; } std::cout << "\n\n"; } void staj_object_iterator_example() { json_string_cursor cursor(object_example); auto view = staj_object(cursor); for (const auto& kv : view) { std::cout << kv.first << ":\n" << pretty_print(kv.second) << "\n"; } std::cout << "\n\n"; } int main() { std::cout << "\nstaj_iterator examples\n\n"; staj_array_iterator_example(); staj_array_iterator_example2(); staj_object_iterator_example(); std::cout << "\n"; } jsoncons-1.3.2/examples/src/type_extensibility_examples.cpp000066400000000000000000000112241477700171100243220ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include "sample_types.hpp" #include #include #include #include #include #include using namespace jsoncons; void book_extensibility_example() { ns::book book1{"Haruki Murakami", "Kafka on the Shore", 25.17}; json j = book1; std::cout << "(1) " << std::boolalpha << j.is() << "\n\n"; std::cout << "(2) " << pretty_print(j) << "\n\n"; ns::book temp = j.as(); std::cout << "(3) " << temp.author << "," << temp.title << "," << temp.price << "\n\n"; ns::book book2{"Charles Bukowski", "Women: A Novel", 12.0}; std::vector book_array{book1, book2}; json ja = book_array; std::cout << "(4) " << std::boolalpha << ja.is>() << "\n\n"; std::cout << "(5)\n" << pretty_print(ja) << "\n\n"; auto book_list = ja.as>(); std::cout << "(6)" << '\n'; for (auto b : book_list) { std::cout << b.author << ", " << b.title << ", " << b.price << '\n'; } } void book_extensibility_example2() { const std::string s = R"( [ { "author" : "Haruki Murakami", "title" : "Kafka on the Shore", "price" : 25.17 }, { "author" : "Charles Bukowski", "title" : "Pulp", "price" : 22.48 } ] )"; std::vector book_list = decode_json>(s); std::cout << "(1)\n"; for (const auto& item : book_list) { std::cout << item.author << ", " << item.title << ", " << item.price << "\n"; } std::cout << "\n(2)\n"; encode_json(book_list, std::cout, indenting::indent); std::cout << "\n\n"; } void reputons_extensibility_example() { ns::hiking_reputation val("hiking", { ns::hiking_reputon{"HikingAsylum",ns::hiking_experience::advanced,"Marilyn C",0.90} }); std::string s; encode_json(val, s, indenting::indent); std::cout << s << "\n"; auto val2 = decode_json(s); assert(val2 == val); } void person_extensibility_example() { try { //Incomplete json string: field ssn missing std::string data = R"({"name":"Rod","surname":"Bro","age":30})"; auto person = jsoncons::decode_json(data); std::string s; jsoncons::encode_json(person, s, indenting::indent); std::cout << s << "\n"; } catch (const std::exception& e) { std::cout << e.what() << ""; } } void named_example() { ns::bond bond{1000000,"2024-03-30",0.02,"6M"}; std::string s; jsoncons::encode_json(bond, s, indenting::indent); std::cout << s << "\n"; } //own vector will always be of an even length struct own_vector : std::vector { using std::vector::vector; }; namespace jsoncons { template struct json_type_traits { static bool is(const Json& j) noexcept { return j.is_object() && j.size() % 2 == 0; } static own_vector as(const Json& j) { own_vector v; for (auto& item : j.object_range()) { std::string s(item.key()); v.push_back(std::strtol(s.c_str(),nullptr,10)); v.push_back(item.value().template as()); } return v; } static Json to_json(const own_vector& val){ Json j; for (std::size_t i=0;i struct is_json_type_traits_declared : public std::true_type {}; } // namespace jsoncons void own_vector_extensibility_example() { json j(json_object_arg, {{"1",2},{"3",4}}); assert(j.is()); auto v = j.as(); json j2 = v; std::cout << j2 << "\n"; } void templated_struct_example() { using value_type = ns::TemplatedStruct; value_type val{1, L"sss"}; std::wstring s; encode_json(val, s); auto val2 = decode_json(s); assert(val2 == val); } int main() { std::cout << std::setprecision(6); std::cout << "\nType extensibility examples\n\n"; book_extensibility_example(); own_vector_extensibility_example(); book_extensibility_example2(); reputons_extensibility_example(); person_extensibility_example(); templated_struct_example(); named_example(); std::cout << '\n'; } jsoncons-1.3.2/examples/src/ubjson_examples.cpp000066400000000000000000000155241477700171100216740ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include "sample_types.hpp" #include #include #include #include using namespace jsoncons; void to_from_ubjson_using_basic_json() { ojson j1 = ojson::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90, "generated": 1514862245 } ] } )"); // Encode a basic_json value to UBJSON std::vector data; ubjson::encode_ubjson(j1, data); // Decode UBJSON to a basic_json value ojson j2 = ubjson::decode_ubjson(data); std::cout << "(1)\n" << pretty_print(j2) << "\n\n"; // Accessing the data items const ojson& reputons = j2["reputons"]; std::cout << "(2)\n"; for (auto element : reputons.array_range()) { std::cout << element.at("rated").as() << ", "; std::cout << element.at("rating").as() << "\n"; } std::cout << '\n'; // Get a UBJSON value for a nested data item with jsonpointer std::error_code ec; auto const& rated = jsonpointer::get(j2, "/reputons/0/rated", ec); if (!ec) { std::cout << "(3) " << rated.as_string() << "\n"; } std::cout << '\n'; } void to_from_ubjson_using_example_type() { ns::hiking_reputation val("hiking", { ns::hiking_reputon{"HikingAsylum",ns::hiking_experience::advanced,"Marilyn C",0.90} }); // Encode a ns::hiking_reputation value to UBJSON std::vector data; ubjson::encode_ubjson(val, data); // Decode UBJSON to a ns::hiking_reputation value ns::hiking_reputation val2 = ubjson::decode_ubjson(data); assert(val2 == val); } const std::vector data = {0x5b,0x23,0x55,0x05, // [ # i 5 0x44, // float64 0x40,0x3d,0xf8,0x51,0xeb,0x85,0x1e,0xb8, // 29.97 0x44, // float64 0x40,0x3f,0x21,0x47,0xae,0x14,0x7a,0xe1, // 31.13 0x64, // float32 0x42,0x86,0x00,0x00, // 67.0 0x44, // float64 0x40,0x00,0xe7,0x6c,0x8b,0x43,0x95,0x81, // 2.113 0x44, // float64 0x40,0x37,0xe3,0x8e,0xf3,0x4d,0x6a,0x16 // 23.8889 }; void working_with_ubjson_1() { std::cout << std::dec; std::cout << std::setprecision(15); // Parse the string of data into a json value json j = ubjson::decode_ubjson(data); // Pretty print std::cout << "(1)\n" << pretty_print(j) << "\n\n"; // Iterate over rows std::cout << "(2)\n"; for (const auto& item : j.array_range()) { std::cout << item.as() << " (" << item.tag() << ")\n"; } std::cout << "\n"; // Select all values less than 30 with JSONPath std::cout << "(3)\n"; json result = jsonpath::json_query(j,"$[?(@ < 30)]"); std::cout << pretty_print(result) << "\n"; } void working_with_ubjson_2() { // Parse the string of data into a std::vector value auto val = ubjson::decode_ubjson>(data); for (auto item : val) { std::cout << item << "\n"; } } void working_with_ubjson_3() { ubjson::ubjson_bytes_cursor cursor(data); for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::end_array: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::begin_object: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::end_object: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::key: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::string_value: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::null_value: std::cout << event.event_type() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::bool_value: std::cout << event.event_type() << ": " << std::boolalpha << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::int64_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; case staj_event_type::double_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; default: std::cout << "Unhandled event type " << event.event_type() << " " << "(" << event.tag() << ")\n"; break; } } } void working_with_ubjson_4() { auto filter = [&](const staj_event& ev, const ser_context&) -> bool { return (ev.event_type() == staj_event_type::double_value) && (ev.get() < 30.0); }; ubjson::ubjson_bytes_cursor cursor(data); auto filtered_c = cursor | filter; for (; !filtered_c.done(); filtered_c.next()) { const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::double_value: std::cout << event.event_type() << ": " << event.get() << " " << "(" << event.tag() << ")\n"; break; default: std::cout << "Unhandled event type " << event.event_type() << " " << "(" << event.tag() << ")\n"; break; } } } int main() { std::cout << "\nubjson examples\n\n"; to_from_ubjson_using_basic_json(); std::cout << "\n"; to_from_ubjson_using_example_type(); std::cout << "\n"; working_with_ubjson_1(); std::cout << "\n"; working_with_ubjson_2(); std::cout << "\n"; working_with_ubjson_3(); std::cout << "\n"; working_with_ubjson_4(); std::cout << '\n'; } jsoncons-1.3.2/examples/src/unicode_examples.cpp000066400000000000000000000013421477700171100220130ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include using namespace jsoncons; void read_and_write_escaped_unicode() { std::string input = "[\"\\u8A73\\u7D30\\u95B2\\u89A7\\uD800\\uDC01\\u4E00\"]"; json value = json::parse(input); auto options = json_options{} .escape_all_non_ascii(true); std::string output; value.dump(output,options); std::cout << "Input:" << '\n'; std::cout << input << '\n'; std::cout << '\n'; std::cout << "Output:" << '\n'; std::cout << output << '\n'; } int main() { std::cout << "\nUnicode examples\n\n"; read_and_write_escaped_unicode(); std::cout << '\n'; } jsoncons-1.3.2/examples/src/update_json_in_place_examples.cpp000066400000000000000000000053341477700171100245370ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include using namespace jsoncons; class string_locator : public jsoncons::default_json_visitor { char* data_; std::size_t length_; std::vector path_; std::string from_; std::vector current_; std::vector positions_; public: using jsoncons::default_json_visitor::string_view_type; string_locator(char* data, std::size_t length, const std::vector& path, const std::string& from) : data_(data), length_(length), path_(path), from_(from) { } const std::vector& positions() const { return positions_; } private: bool visit_begin_object(semantic_tag, const ser_context&, std::error_code&) override { current_.emplace_back(); return true; } bool visit_end_object(const ser_context&, std::error_code&) override { current_.pop_back(); return true; } bool visit_key(const string_view_type& key, const ser_context&, std::error_code&) override { current_.back() = std::string(key); return true; } bool visit_string(const string_view_type& value, jsoncons::semantic_tag, const jsoncons::ser_context& context, std::error_code&) override { if (path_.size() <= current_.size() && std::equal(path_.rbegin(), path_.rend(), current_.rbegin())) { if (value == from_) { positions_.push_back(context.position()+1); // one past quote character } } return true; } }; void update_json_in_place(std::string& input, const std::vector& path, const std::string& from, const std::string& to) { if (input.size() > 0) { string_locator locator(&input[0], input.size(), path, from); jsoncons::json_string_reader reader(input, locator); reader.read(); for (auto it = locator.positions().rbegin(); it != locator.positions().rend(); ++it) { input.replace(*it, from.size(), to); } } } int main() { std::cout << "\njson update in place examples\n\n"; std::string input = R"( { "Cola" : {"Type":"Drink", "Price": 10.99},"Water" : {"Type":"Drink"}, "Extra" : {"Cola" : {"Type":"Drink", "Price": 8.99}} } )"; try { std::cout << "(original)\n" << input << "\n"; update_json_in_place(input, {"Cola", "Type"}, "Drink", "SoftDrink"); std::cout << "(updated)\n" << input << "\n"; } catch (std::exception& e) { std::cout << e.what() << "\n"; } std::cout << '\n'; } jsoncons-1.3.2/examples/src/wjson_examples.cpp000066400000000000000000000036541477700171100215350ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #ifdef _MSC_VER #include #endif #include #include #include using namespace jsoncons; void wjson_object() { wjson j; j[L"field1"] = L"test"; j[L"field2"] = 3.9; j[L"field3"] = true; std::wcout << j << L"\n"; } #if 0 void wjson_escape_u2() { #ifdef _MSC_VER std::wstring input = L"[\"\\u007F\\u07FF\\u0800\"]"; std::wistringstream is(input); wjson val = wjson::parse(is); std::wstring s = val[0].as(); std::cout << "length=" << s.length() << '\n'; std::cout << "Hex dump: ["; for (std::size_t i = 0; i < s.size(); ++i) { if (i != 0) std::cout << " "; uint32_t u(s[i] >= 0 ? s[i] : 256 + s[i] ); std::cout << "0x" << std::hex<< std::setfill('0') << std::setw(2) << u; } std::cout << "]" << '\n'; std::wofstream os("./output/xxx.txt"); os.imbue(std::locale(os.getloc(), new std::codecvt_utf8_utf16)); auto options = wjson_options{} .escape_all_non_ascii(true); os << pretty_print(val,options) << L"\n"; #endif } #endif void wjson_surrogate_pair() { #ifdef _MSC_VER std::wstring input = L"[\"\\uD950\\uDF21\"]"; std::wistringstream is(input); wjson val = wjson::parse(is); std::wstring s = val[0].as(); std::cout << "length=" << s.length() << '\n'; std::cout << "Hex dump: ["; for (std::size_t i = 0; i < s.size(); ++i) { if (i != 0) std::cout << " "; uint32_t u(s[i] >= 0 ? s[i] : 256 + s[i] ); std::cout << "0x" << std::hex<< std::setfill('0') << std::setw(2) << u; } std::cout << "]" << '\n'; #endif } int main() { std::cout << "\nwjson examples\n\n"; wjson_object(); //wjson_escape_u2(); wjson_surrogate_pair(); std::cout << '\n'; } jsoncons-1.3.2/examples_boost/000077500000000000000000000000001477700171100164025ustar00rootroot00000000000000jsoncons-1.3.2/examples_boost/extensibility.cpp000066400000000000000000000204051477700171100220030ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #include #include namespace jsoncons { template struct json_type_traits { static bool is(const Json& val) noexcept { if (!val.is_string()) return false; try { std::string s = val.template as(); boost::gregorian::from_simple_string(s); return true; } catch (...) { return false; } } static boost::gregorian::date as(const Json& val) { std::string s = val.template as(); return boost::gregorian::from_simple_string(s); } static Json to_json(boost::gregorian::date val, typename Json::allocator_type alloc = Json::allocator_type()) { return Json(to_iso_extended_string(val), alloc); } }; template struct json_type_traits> { using multiprecision_type = boost::multiprecision::number; static bool is(const Json& val) noexcept { if (!(val.is_string() && val.tag() == semantic_tag::bigdec)) { return false; } else { return true; } } static multiprecision_type as(const Json& val) { return multiprecision_type(val.template as()); } static Json to_json(multiprecision_type val) { return Json(val.str(), semantic_tag::bigdec); } }; template struct json_type_traits> { using allocator_type = typename Json::allocator_type; static bool is(const Json& val) noexcept { if (!val.is_array()) { return false; } if (val.size() > 0) { std::size_t n = val[0].size(); for (const auto& a: val.array_range()) { if (!(a.is_array() && a.size() == n)) { return false; } for (auto x: a.array_range()) { if (!x.template is()) { return false; } } } } return true; } static boost::numeric::ublas::matrix as(const Json& val) { if (val.is_array() && val.size() > 0) { std::size_t m = val.size(); std::size_t n = 0; for (const auto& a : val.array_range()) { if (a.size() > n) { n = a.size(); } } boost::numeric::ublas::matrix A(m,n,T()); for (std::size_t i = 0; i < m; ++i) { const auto& a = val[i]; for (std::size_t j = 0; j < a.size(); ++j) { A(i,j) = a[j].template as(); } } return A; } else { boost::numeric::ublas::matrix A; return A; } } static Json to_json(const boost::numeric::ublas::matrix& val, allocator_type alloc = allocator_type()) { Json a = Json::template make_array<2>(val.size1(), val.size2(), T()); for (std::size_t i = 0; i < val.size1(); ++i) { for (std::size_t j = 0; j < val.size1(); ++j) { a[i][j] = val(i,j); } } return a; } }; } // namespace jsoncons namespace ns { class fixing { std::string index_id_; boost::gregorian::date observation_date_; double rate_; public: fixing(const std::string& index_id, boost::gregorian::date observation_date, double rate) : index_id_(index_id), observation_date_(observation_date), rate_(rate) { } const std::string& index_id() const {return index_id_;} boost::gregorian::date observation_date() const {return observation_date_;} double rate() const {return rate_;} }; } namespace ns JSONCONS_ALL_CTOR_GETTER_TRAITS(ns::fixing, index_id, observation_date, rate) using namespace jsoncons; using boost::numeric::ublas::matrix; void boost_date_conversions() { using boost::gregorian::date; json deal; deal["maturity"] = date(2014,10,14); json observation_dates(json_array_arg); observation_dates.push_back(date(2014,2,14)); observation_dates.push_back(date(2014,2,21)); deal["observationDates"] = std::move(observation_dates); date maturity = deal["maturity"].as(); assert(deal["maturity"].as() == date(2014,10,14)); assert(deal["observationDates"].is_array()); assert(deal["observationDates"].size() == 2); assert(deal["observationDates"][0].as() == date(2014,2,14)); assert(deal["observationDates"][1].as() == date(2014,2,21)); std::cout << pretty_print(deal) << '\n'; } void boost_matrix_conversions() { matrix A(2, 2); A(0, 0) = 1.1; A(0, 1) = 2.1; A(1, 0) = 3.1; A(1, 1) = 4.1; json a = A; assert(a.is>()); assert(!a.is>()); assert(a[0][0].as()==A(0,0)); assert(a[0][1].as()==A(0,1)); assert(a[1][0].as()==A(1,0)); assert(a[1][1].as()==A(1,1)); matrix B = a.as>(); assert(B.size1() ==a.size()); assert(B.size2() ==a[0].size()); assert(a[0][0].as()==B(0,0)); assert(a[0][1].as()==B(0,1)); assert(a[1][0].as()==B(1,0)); assert(a[1][1].as()==B(1,1)); } void boost_multiprecison_conversions() { typedef boost::multiprecision::number multiprecision_type; std::string s = "[100000000000000000000000000000000.1234]"; auto options = json_options{} .lossless_number(true); json j = json::parse(s, options); multiprecision_type x = j[0].as(); std::cout << "(1) " << std::setprecision(std::numeric_limits::max_digits10) << x << "\n"; json j2(json_array_arg,{x}); std::cout << "(2) " << j2[0].as() << "\n"; } void csv_strongly_typed_example() { const std::string data = R"(index_id,observation_date,rate EUR_LIBOR_06M,2015-10-23,0.0000214 EUR_LIBOR_06M,2015-10-26,0.0000143 EUR_LIBOR_06M,2015-10-27,0.0000001 )"; auto options = csv::csv_options{} .assume_header(true); // Decode the CSV data into a c++ structure std::vector v = csv::decode_csv>(data, options); // Iterate over values std::cout << std::fixed << std::setprecision(7); std::cout << "(1)\n"; for (const auto& item : v) { std::cout << item.index_id() << ", " << item.observation_date() << ", " << item.rate() << "\n"; } // Encode the c++ structure into CSV data std::string s; csv::encode_csv(v, s); std::cout << "(2)\n"; std::cout << s << "\n"; //std::vector v = csv::decode_csv>(data, options); //std::cout << v[0]["observation_date"].as() << "\n"; } void extensibility_examples() { std::cout << "extensibility examples\n\n"; boost_date_conversions(); boost_matrix_conversions(); boost_multiprecison_conversions(); csv_strongly_typed_example(); } jsoncons-1.3.2/examples_boost/interprocess_allocator.cpp000066400000000000000000000067741477700171100237040ustar00rootroot00000000000000#include #include #include #include #include //std::system #include #include using shmem_allocator = boost::interprocess::allocator; using cust_allocator = std::scoped_allocator_adaptor; struct boost_sorted_policy { template using object = jsoncons::sorted_json_object; template using array = jsoncons::json_array; template using member_key = boost::interprocess::basic_string; }; using cust_json = jsoncons::basic_json; int main(int argc, char *argv[]) { typedef std::pair MyType; if (argc == 1) // Parent process { //Remove shared memory on construction and destruction struct shm_remove { shm_remove() { boost::interprocess::shared_memory_object::remove("MySharedMemory"); } ~shm_remove() noexcept { boost::interprocess::shared_memory_object::remove("MySharedMemory"); } } remover; //Construct managed shared memory boost::interprocess::managed_shared_memory segment(boost::interprocess::create_only, "MySharedMemory", 65536); //Initialize shared memory STL-compatible allocator const shmem_allocator alloc(segment.get_segment_manager()); // Create json value with all dynamic allocations in shared memory cust_json* j = segment.construct("MyJson")(jsoncons::json_array_arg, alloc); j->push_back(10); cust_json o(jsoncons::json_object_arg, alloc); o.try_emplace("category", "reference"); o.try_emplace("author", "Nigel Rees"); o.insert_or_assign("title", "Sayings of the Century"); o.insert_or_assign("price", 8.95); j->push_back(o); cust_json a(jsoncons::json_array_arg, 2, cust_json(jsoncons::json_object_arg, alloc), jsoncons::semantic_tag::none, alloc); a[0]["first"] = 1; j->push_back(a); std::pair res; res = segment.find("MyJson"); std::cout << "Parent process:\n"; std::cout << pretty_print(*(res.first)) << "\n\n"; //Launch child process std::string s(argv[0]); s += " child "; if (0 != std::system(s.c_str())) return 1; //Check child has destroyed all objects if (segment.find("MyJson").first) return 1; } else // Child process { //Open managed shared memory boost::interprocess::managed_shared_memory segment(boost::interprocess::open_only, "MySharedMemory"); std::pair res; res = segment.find("MyJson"); if (res.first != nullptr) { std::cout << "Child process:\n"; std::cout << pretty_print(*(res.first)) << "\n"; } else { std::cout << "Result is null\n"; } //We're done, delete all the objects segment.destroy("MyJson"); } return 0; } jsoncons-1.3.2/examples_boost/more_examples.cpp000066400000000000000000000005541477700171100217520ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include void extensibility_examples(); void pool_allocator_examples(); int main() { try { extensibility_examples(); pool_allocator_examples(); } catch (const std::exception& e) { std::cout << e.what() << '\n'; } return 0; } jsoncons-1.3.2/examples_boost/pool_allocator.cpp000066400000000000000000000014341477700171100221210ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include using namespace jsoncons; using cust_json = basic_json>; void pool_allocator_examples() { std::cout << "pool_allocator examples\n\n"; jsoncons::json_decoder> decoder; static std::string s("[1,2,3,4,5,6]"); std::istringstream is(s); basic_json_reader,boost::pool_allocator> reader(is,decoder); reader.read(); cust_json j = decoder.get_result(); std::cout << j << '\n'; } jsoncons-1.3.2/examples_boost/serialization_examples.cpp000066400000000000000000000356601477700171100236730ustar00rootroot00000000000000// Copyright 2013-2024 Daniel Parker // Distributed under Boost license #include #include #include #include #include using namespace jsoncons; namespace boost_mp = boost::multiprecision; void serialization_example1() { json val = json::parse(R"( { "sfm_data_version": "0.2", "root_path": "D:\\Lagring\\Plugg\\Examensarbete\\Data\\images", "views": [], "intrinsics": [], "extrinsics": [ { "key": 0, "value": { "rotation": [ [ 0.89280214808572156, 0.35067276062587932, -0.28272413998197254 ], [ -0.090429686592667424, 0.75440463553446824, 0.65015084224113584 ], [ 0.44127859245183554, -0.5548894131618759, 0.70524530697098287 ] ], "center": [ -0.60959634064871249, 0.24123645392011658, 0.57783384588917808 ] } } ] } )"); std::cout << "Default pretty print" << std::endl; std::cout << pretty_print(val) << std::endl; std::cout << "array_array_line_splits(line_split_kind::new_line)" << std::endl; std::cout << "array_object_line_splits(line_split_kind::new_line)" << std::endl; auto options = json_options{} .array_array_line_splits(line_split_kind::new_line) .array_object_line_splits(line_split_kind::new_line); std::cout << pretty_print(val,options) << std::endl; } void serialization_example2() { json val; val["verts"] = json(json_array_arg, {1, 2, 3}); val["normals"] = json(json_array_arg, {1, 0, 1}); val["uvs"] = json(json_array_arg, {0, 0, 1, 1}); std::cout << "Default object-array same line options" << std::endl; std::cout << pretty_print(val) << std::endl; std::cout << "object_array_line_splits(line_split_kind::same_line)" << std::endl; auto options1 = json_options{} .object_array_line_splits(line_split_kind::same_line); std::cout << pretty_print(val,options1) << std::endl; std::cout << "object_array_line_splits(line_split_kind::new_line)" << std::endl; auto options2 = json_options{} .object_array_line_splits(line_split_kind::new_line); std::cout << pretty_print(val,options2 ) << std::endl; std::cout << "object_array_line_splits(line_split_kind::multi_line)" << std::endl; auto options3 = json_options{} .object_array_line_splits(line_split_kind::multi_line); std::cout << pretty_print(val,options3) << std::endl; } void serialization_example3() { { json val = json::parse(R"( [ {"first-name" : "John", "last-name" : "Doe"}, {"first-name" : "Jane", "last-name" : "Doe"} ] )"); auto options = json_options{} .array_object_line_splits(line_split_kind::same_line); std::cout << "array_object_line_splits(line_split_kind::same_line)" << std::endl; std::cout << pretty_print(val,options) << std::endl; } { json val = json::parse(R"({ "verts" : [1, 2, 3], "normals" : [1, 0, 1], "uvs" : [ 0, 0, 1, 1 ] } )"); std::cout << "Default print" << std::endl; std::cout << print(val) << std::endl; std::cout << "Default pretty print" << std::endl; std::cout << pretty_print(val) << std::endl; auto options1 = json_options{} .array_array_line_splits(line_split_kind::same_line); std::cout << pretty_print(val,options1) << std::endl; auto options = json_options{} .object_object_line_splits(line_split_kind::new_line);; std::cout << pretty_print(val,options) << std::endl; } { json val2 = json::parse(R"( { "data": { "item": [[2],[4,5,2,3],[4],[4,5,2,3],[2],[4,5,3],[2],[4,3]], //A two-dimensional array //blank line "id": [0,1,2,3,4,5,6,7] //A one-dimensional array } } )"); std::cout << "Default" << std::endl; std::cout << pretty_print(val2) << std::endl; std::cout << "array_array_line_splits(line_split_kind::new_line)" << std::endl; auto options2 = json_options{} .array_array_line_splits(line_split_kind::new_line); std::cout << pretty_print(val2,options2 ) << std::endl; std::cout << "array_array_line_splits(line_split_kind::same_line)" << std::endl; auto options4 = json_options{} .array_array_line_splits(line_split_kind::same_line); std::cout << pretty_print(val2, options4) << std::endl; std::cout << "array_array_line_splits(line_split_kind::same_line)" << std::endl; auto options5 = json_options{} .array_array_line_splits(line_split_kind::same_line); std::cout << pretty_print(val2, options5) << std::endl; } json val3 = json::parse(R"( { "data": { "item": [[2]] //A two-dimensional array } } )"); std::cout << "array_array_line_splits(line_split_kind::new_line)" << std::endl; auto options6 = json_options{} .array_array_line_splits(line_split_kind::new_line); std::cout << pretty_print(val3,options6) << std::endl; } void serialization_example4() { json val; val["data"]["id"] = json(json_array_arg, {0,1,2,3,4,5,6,7}); val["data"]["item"] = json(json_array_arg, {json(json_array_arg, {2}), json(json_array_arg, {4,5,2,3}), json(json_array_arg, {4}), json(json_array_arg, {4,5,2,3}), json(json_array_arg, {2}), json(json_array_arg, {4,5,3}), json(json_array_arg, {2}), json(json_array_arg, {4,3})}); std::cout << "Default array-array split line options" << std::endl; std::cout << pretty_print(val) << std::endl; std::cout << "Array-array same line options" << std::endl; auto options1 = json_options{} .array_array_line_splits(line_split_kind::same_line); std::cout << pretty_print(val, options1) << std::endl; std::cout << "object_array_line_splits(line_split_kind::new_line)" << std::endl; std::cout << "array_array_line_splits(line_split_kind::same_line)" << std::endl; auto options2 = json_options{} .object_array_line_splits(line_split_kind::new_line) .array_array_line_splits(line_split_kind::same_line); std::cout << pretty_print(val, options2 ) << std::endl; std::cout << "object_array_line_splits(line_split_kind::new_line)" << std::endl; std::cout << "array_array_line_splits(line_split_kind::multi_line)" << std::endl; auto options3 = json_options{} .object_array_line_splits(line_split_kind::new_line) .array_array_line_splits(line_split_kind::multi_line); std::cout << pretty_print(val, options3) << std::endl; { json val = json::parse(R"( { "header" : {"properties": {}}, "data": { "tags" : [], "id" : [1,2,3], "item": [[1,2,3]] } } )"); std::cout << "Default" << std::endl; std::cout << pretty_print(val) << std::endl; std::string style1 = "array_array_line_splits(line_split_kind:same_line)"; std::cout << style1 << std::endl; auto options1 = json_options{} .array_array_line_splits(line_split_kind::same_line); std::cout << pretty_print(val,options1) << std::endl; std::string style2 = "array_array_line_splits(line_split_kind::new_line)"; std::cout << style2 << std::endl; auto options2 = json_options{} .array_array_line_splits(line_split_kind::new_line); std::cout << pretty_print(val,options2 ) << std::endl; std::string style3 = "array_array_line_splits(line_split_kind::multi_line)"; std::cout << style3 << std::endl; auto options3 = json_options{} .array_array_line_splits(line_split_kind::multi_line); std::cout << pretty_print(val,options3) << std::endl; std::string style4 = "object_array_line_splits(line_split_kind:same_line)"; std::cout << style4 << std::endl; auto options4 = json_options{} .object_array_line_splits(line_split_kind::same_line); std::cout << pretty_print(val,options4) << std::endl; std::string style5 = "object_array_line_splits(line_split_kind::new_line)"; std::cout << style5 << std::endl; auto options5 = json_options{} .object_array_line_splits(line_split_kind::new_line); std::cout << pretty_print(val,options5) << std::endl; std::string style6 = "object_array_line_splits(line_split_kind::multi_line)"; std::cout << style6 << std::endl; auto options6 = json_options{} .object_array_line_splits(line_split_kind::multi_line); std::cout << pretty_print(val,options6) << std::endl; } } void dump_json_fragments() { const json some_books = json::parse(R"( [ { "title" : "Kafka on the Shore", "author" : "Haruki Murakami", "price" : 25.17 }, { "title" : "Women: A Novel", "author" : "Charles Bukowski", "price" : 12.00 } ] )"); const json more_books = json::parse(R"( [ { "title" : "A Wild Sheep Chase: A Novel", "author" : "Haruki Murakami", "price" : 9.01 }, { "title" : "Cutter's Way", "author" : "Ivan Passer", "price" : 8.00 } ] )"); json_stream_encoder encoder(std::cout); // pretty print encoder.begin_array(); for (const auto& book : some_books.array_range()) { book.dump(encoder); } for (const auto& book : more_books.array_range()) { book.dump(encoder); } encoder.end_array(); encoder.flush(); } void nan_inf_replacement() { json j; j["field1"] = std::sqrt(-1.0); j["field2"] = 1.79e308 * 1000; j["field3"] = -1.79e308 * 1000; auto options = json_options{} .nan_to_str("NaN") .inf_to_str("Inf"); std::ostringstream os; os << pretty_print(j, options); std::cout << "(1)\n" << os.str() << std::endl; json j2 = json::parse(os.str(),options); std::cout << "\n(2) " << j2["field1"].as() << std::endl; std::cout << "(3) " << j2["field2"].as() << std::endl; std::cout << "(4) " << j2["field3"].as() << std::endl; std::cout << "\n(5)\n" << pretty_print(j2,options) << std::endl; } void bignum_serialization_examples1() { std::string s = "-18446744073709551617"; json j(bigint::from_string(s.c_str())); std::cout << "(default) "; j.dump(std::cout); std::cout << "\n\n"; std::cout << "(integer) "; auto options1 = json_options{} .bigint_format(bigint_chars_format::number); j.dump(std::cout, options1); std::cout << "\n\n"; std::cout << "(base64) "; auto options3 = json_options{} .bigint_format(bigint_chars_format::base64); j.dump(std::cout, options3); std::cout << "\n\n"; std::cout << "(base64url) "; auto options4 = json_options{} .bigint_format(bigint_chars_format::base64url); j.dump(std::cout, options4); std::cout << "\n\n"; } void bignum_serialization_examples2() { std::string s = "-18446744073709551617"; json j = json::parse(s); std::cout << "(1) "; j.dump(std::cout); std::cout << "\n\n"; std::cout << "(2) "; auto options1 = json_options{} .bigint_format(bigint_chars_format::number); j.dump(std::cout, options1); std::cout << "\n\n"; std::cout << "(3) "; auto options2 = json_options{} .bigint_format(bigint_chars_format::base64url); j.dump(std::cout, options2); std::cout << "\n\n"; } void bignum_access_examples() { std::string input = "-18446744073709551617"; json j = json::parse(input); // Access as string std::string s = j.as(); std::cout << "(1) " << s << "\n\n"; // Access as double double d = j.as(); std::cout << "(2) " << std::setprecision(17) << d << "\n\n"; // Access as jsoncons::bigint jsoncons::bigint bn = j.as(); std::cout << "(3) " << bn << "\n\n"; // If your compiler supports extended integral types #if (defined(__GNUC__) || defined(__clang__)) && defined(JSONCONS_HAS_INT128) __int128 i = j.as<__int128>(); boost_mp::int128_t boost_i = static_cast(i); std::cout << "(4) " << boost_i << "\n\n"; #endif } void decimal_precision_examples() { std::string s = R"( { "a" : 12.00, "b" : 1.23456789012345678901234567890 } )"; // Default json j = json::parse(s); std::cout.precision(15); // Access as string std::cout << "(1) a: " << j["a"].as() << ", b: " << j["b"].as() << "\n"; // Access as double std::cout << "(2) a: " << j["a"].as() << ", b: " << j["b"].as() << "\n\n"; // Using lossless_number option auto options = json_options{} .lossless_number(true); json j2 = json::parse(s, options); // Access as string std::cout << "(3) a: " << j2["a"].as() << ", b: " << j2["b"].as() << "\n"; // Access as double std::cout << "(4) a: " << j2["a"].as() << ", b: " << j2["b"].as() << "\n\n"; } void chinese_char() { jsoncons::json j; std::string s = (const char*)u8"你好"; j.try_emplace("hello", s); assert(j["hello"].as() == s); std::string json_string; j.dump(json_string); } #ifdef __cpp_char8_t void chinese_uchar8_t() { jsoncons::json j; std::u8string s = u8"你好"; j.try_emplace("hello", s); assert(j["hello"].as() == s); std::string json_string; j.dump(json_string); } #endif int main() { std::cout << "\nSerialization examples\n\n"; serialization_example1(); serialization_example2(); serialization_example3(); serialization_example4(); dump_json_fragments(); nan_inf_replacement(); bignum_serialization_examples2(); bignum_serialization_examples1(); decimal_precision_examples(); bignum_access_examples(); chinese_char(); #ifdef __cpp_char8_t chinese_uchar8_t(); #endif std::cout << std::endl; } jsoncons-1.3.2/fuzzers/000077500000000000000000000000001477700171100150665ustar00rootroot00000000000000jsoncons-1.3.2/fuzzers/build_fuzzers.sh000066400000000000000000000053071477700171100203160ustar00rootroot00000000000000oss_fuzz_compile_all() { # Make sure we are in the root directory of the jsoncons DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" cd ${DIR}/.. $CXX ./fuzzers/fuzz_parse.cpp -I./include $CXXFLAGS $LIB_FUZZING_ENGINE -o $OUT/fuzz_parse $CXX ./fuzzers/fuzz_csv.cpp -I./include $CXXFLAGS $LIB_FUZZING_ENGINE -o $OUT/fuzz_csv # With third party $CXX ./fuzzers/fuzz_cbor.cpp -I./include -I./third_party $CXXFLAGS $LIB_FUZZING_ENGINE -o $OUT/fuzz_cbor $CXX ./fuzzers/fuzz_bson.cpp -I./include -I./third_party $CXXFLAGS $LIB_FUZZING_ENGINE -o $OUT/fuzz_bson $CXX ./fuzzers/fuzz_msgpack.cpp -I./include -I./third_party $CXXFLAGS $LIB_FUZZING_ENGINE -o $OUT/fuzz_msgpack $CXX ./fuzzers/fuzz_ubjson.cpp -I./include -I./third_party $CXXFLAGS $LIB_FUZZING_ENGINE -o $OUT/fuzz_ubjson # Fuzzers with encoders $CXX ./fuzzers/fuzz_bson_encoder.cpp -I./include -I./third_party $CXXFLAGS $LIB_FUZZING_ENGINE -o $OUT/fuzz_bson_encoder $CXX ./fuzzers/fuzz_cbor_encoder.cpp -I./include -I./third_party $CXXFLAGS $LIB_FUZZING_ENGINE -o $OUT/fuzz_cbor_encoder $CXX ./fuzzers/fuzz_csv_encoder.cpp -I./include -I./third_party $CXXFLAGS $LIB_FUZZING_ENGINE -o $OUT/fuzz_csv_encoder $CXX ./fuzzers/fuzz_json_encoder.cpp -I./include -I./third_party $CXXFLAGS $LIB_FUZZING_ENGINE -o $OUT/fuzz_json_encoder $CXX ./fuzzers/fuzz_msgpack_encoder.cpp -I./include -I./third_party $CXXFLAGS $LIB_FUZZING_ENGINE -o $OUT/fuzz_msgpack_encoder $CXX ./fuzzers/fuzz_ubjson_encoder.cpp -I./include -I./third_party $CXXFLAGS $LIB_FUZZING_ENGINE -o $OUT/fuzz_ubjson_encoder # Fuzzers with max parser depth $CXX ./fuzzers/fuzz_bson_parser_max.cpp -I./include -I./third_party $CXXFLAGS $LIB_FUZZING_ENGINE -o $OUT/fuzz_bson_parser_max $CXX ./fuzzers/fuzz_cbor_parser_max.cpp -I./include -I./third_party $CXXFLAGS $LIB_FUZZING_ENGINE -o $OUT/fuzz_cbor_parser_max $CXX ./fuzzers/fuzz_json_parser_max.cpp -I./include -I./third_party $CXXFLAGS $LIB_FUZZING_ENGINE -o $OUT/fuzz_json_parser_max $CXX ./fuzzers/fuzz_msgpack_parser_max.cpp -I./include -I./third_party $CXXFLAGS $LIB_FUZZING_ENGINE -o $OUT/fuzz_msgpack_parser_max $CXX ./fuzzers/fuzz_ubjson_parser_max.cpp -I./include -I./third_party $CXXFLAGS $LIB_FUZZING_ENGINE -o $OUT/fuzz_ubjson_parser_max # Fuzzers that target the cursors $CXX ./fuzzers/fuzz_json_cursor.cpp -I./include -I./third_party $CXXFLAGS $LIB_FUZZING_ENGINE -o $OUT/fuzz_json_cursor } if [[ -z "${OUT}" ]]; then echo "This script assumes we run inside an oss-fuzz environment with the proper environment variables set" echo "Please set these environment variables for it to run properly" else echo "Compiling the fuzzers" oss_fuzz_compile_all fi jsoncons-1.3.2/fuzzers/fuzz_bson.cpp000066400000000000000000000007461477700171100176200ustar00rootroot00000000000000#include #include #include #include #include #include #include using namespace jsoncons; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) { std::string input(reinterpret_cast(data), size); std::istringstream is(input); try { json j2 = bson::decode_bson(is); } catch(const jsoncons::ser_error&) {} return 0; } jsoncons-1.3.2/fuzzers/fuzz_bson_encoder.cpp000066400000000000000000000010261477700171100213070ustar00rootroot00000000000000#include #include #include #include using namespace jsoncons; using namespace jsoncons::bson; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) { std::string s(reinterpret_cast(data), size); std::istringstream is(s); std::vector s1; bson_bytes_encoder encoder(s1); bson_stream_reader reader(is, encoder); std::error_code ec; reader.read(ec); return 0; } jsoncons-1.3.2/fuzzers/fuzz_bson_parser_max.cpp000066400000000000000000000007561477700171100220420ustar00rootroot00000000000000#include #include #include #include using namespace jsoncons; using namespace bson; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) { std::string s(reinterpret_cast(data), size); std::istringstream is(s); default_json_visitor visitor; bson_stream_reader reader(is, visitor); std::error_code ec; reader.read(ec); return 0; } jsoncons-1.3.2/fuzzers/fuzz_cbor.cpp000066400000000000000000000011151477700171100175730ustar00rootroot00000000000000#include #include #include #include using namespace jsoncons; using namespace jsoncons::cbor; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) { std::string input(reinterpret_cast(data), size); std::istringstream is(input); try { json j2 = decode_cbor(is); } catch(const jsoncons::ser_error&) {} catch(jsoncons::json_runtime_error e2) {} return 0; } jsoncons-1.3.2/fuzzers/fuzz_cbor_encoder.cpp000066400000000000000000000010271477700171100212740ustar00rootroot00000000000000#include #include #include #include using namespace jsoncons; using namespace jsoncons::cbor; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) { std::string s(reinterpret_cast(data), size); std::istringstream is(s); std::vector s1; cbor_bytes_encoder encoder(s1); cbor_stream_reader reader(is, encoder); std::error_code ec; reader.read(ec); return 0; }jsoncons-1.3.2/fuzzers/fuzz_cbor_parser_max.cpp000066400000000000000000000007601477700171100220210ustar00rootroot00000000000000#include #include #include #include using namespace jsoncons; using namespace cbor; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) { std::string s(reinterpret_cast(data), size); std::istringstream is(s); default_json_visitor visitor; cbor_stream_reader reader(is, visitor); std::error_code ec; reader.read(ec); return 0; } jsoncons-1.3.2/fuzzers/fuzz_csv.cpp000066400000000000000000000014301477700171100174410ustar00rootroot00000000000000#include #include #include #include using namespace jsoncons; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) { std::string input(reinterpret_cast(data), size); json_decoder decoder; auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_rows); try { csv::csv_string_reader reader1(input, decoder, options); reader1.read(); } catch (jsoncons::ser_error e) {} catch (jsoncons::json_runtime_error e) {} catch (json_runtime_error e3) {} return 0; } jsoncons-1.3.2/fuzzers/fuzz_csv_encoder.cpp000066400000000000000000000007641477700171100211510ustar00rootroot00000000000000#include #include #include using namespace jsoncons; using namespace jsoncons::csv; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) { std::string s(reinterpret_cast(data), size); std::istringstream is(s); std::string s2; csv_string_encoder visitor(s2); csv_stream_reader reader(is, visitor); std::error_code ec; reader.read(ec); return 0; } jsoncons-1.3.2/fuzzers/fuzz_json_cursor.cpp000066400000000000000000000012371477700171100212210ustar00rootroot00000000000000#include #include #include using namespace jsoncons; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) { std::string s(reinterpret_cast(data), size); std::istringstream is(s); std::error_code ec; json_stream_cursor reader(is, ec); while (!reader.done() && !ec) { const auto& event = reader.current(); std::string s2 = event.get(ec); if (!ec) { reader.next(ec); } } return 0; } jsoncons-1.3.2/fuzzers/fuzz_json_encoder.cpp000066400000000000000000000006541477700171100213250ustar00rootroot00000000000000#include #include using namespace jsoncons; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) { std::string s(reinterpret_cast(data), size); std::istringstream is(s); std::string s2; json_string_encoder visitor(s2); json_stream_reader reader(is, visitor); std::error_code ec; reader.read(ec); return 0; } jsoncons-1.3.2/fuzzers/fuzz_json_parser_max.cpp000066400000000000000000000006261477700171100220460ustar00rootroot00000000000000#include #include using namespace jsoncons; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) { std::string s(reinterpret_cast(data), size); std::istringstream is(s); default_json_visitor visitor; json_stream_reader reader(is, visitor); std::error_code ec; reader.read(ec); return 0; } jsoncons-1.3.2/fuzzers/fuzz_msgpack.cpp000066400000000000000000000007621477700171100203020ustar00rootroot00000000000000#include #include #include #include #include #include #include using namespace jsoncons; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) { std::string input(reinterpret_cast(data), size); std::istringstream is(input); try { json j2 = msgpack::decode_msgpack(is); } catch(const jsoncons::ser_error&) {} return 0; } jsoncons-1.3.2/fuzzers/fuzz_msgpack_encoder.cpp000066400000000000000000000010541477700171100217740ustar00rootroot00000000000000#include #include #include #include using namespace jsoncons; using namespace jsoncons::msgpack; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) { std::string s(reinterpret_cast(data), size); std::istringstream is(s); std::vector s1; msgpack_bytes_encoder encoder(s1); msgpack_stream_reader reader(is, encoder); std::error_code ec; reader.read(ec); return 0; } jsoncons-1.3.2/fuzzers/fuzz_msgpack_parser_max.cpp000066400000000000000000000010021477700171100225070ustar00rootroot00000000000000#include #include #include #include using namespace jsoncons; using namespace msgpack; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) { std::string s(reinterpret_cast(data), size); std::istringstream is(s); default_json_visitor visitor; msgpack_stream_reader reader(is, visitor); std::error_code ec; reader.read(ec); return 0; } jsoncons-1.3.2/fuzzers/fuzz_parse.cpp000066400000000000000000000005121477700171100177600ustar00rootroot00000000000000#include #include using namespace jsoncons; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) { std::string input(reinterpret_cast(data), size); try{ json val = json::parse(input); } catch(const jsoncons::ser_error&) {} return 0; } jsoncons-1.3.2/fuzzers/fuzz_ubjson.cpp000066400000000000000000000007571477700171100201610ustar00rootroot00000000000000#include #include #include #include #include #include #include using namespace jsoncons; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) { std::string input(reinterpret_cast(data), size); std::istringstream is(input); try { json j2 = ubjson::decode_ubjson(is); } catch(const jsoncons::ser_error&) {} return 0; } jsoncons-1.3.2/fuzzers/fuzz_ubjson_encoder.cpp000066400000000000000000000010441477700171100216460ustar00rootroot00000000000000#include #include #include #include using namespace jsoncons; using namespace jsoncons::ubjson; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) { std::string s(reinterpret_cast(data), size); std::istringstream is(s); std::vector s1; ubjson_bytes_encoder encoder(s1); ubjson_stream_reader reader(is, encoder); std::error_code ec; reader.read(ec); return 0; } jsoncons-1.3.2/fuzzers/fuzz_ubjson_parser_max.cpp000066400000000000000000000010151477700171100223660ustar00rootroot00000000000000#include #include #include #include #include using namespace jsoncons; using namespace ubjson; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) { std::string s(reinterpret_cast(data), size); std::istringstream is(s); default_json_visitor visitor; ubjson_stream_reader reader(is, visitor); std::error_code ec; reader.read(ec); return 0; } jsoncons-1.3.2/include/000077500000000000000000000000001477700171100150015ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons/000077500000000000000000000000001477700171100166355ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons/allocator_holder.hpp000066400000000000000000000017211477700171100226640ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_ALLOCATOR_HOLDER_HPP #define JSONCONS_ALLOCATOR_HOLDER_HPP namespace jsoncons { template class allocator_holder { public: using allocator_type = Allocator; private: allocator_type alloc_; public: allocator_holder() = default; allocator_holder(const allocator_holder&) = default; allocator_holder(allocator_holder&&) = default; allocator_holder& operator=(const allocator_holder&) = delete; allocator_holder(const allocator_type& alloc) : alloc_(alloc) {} ~allocator_holder() = default; allocator_type get_allocator() const { return alloc_; } }; } // namespace jsoncons #endif // JSONCONS_ALLOCATOR_HOLDER_HPP jsoncons-1.3.2/include/jsoncons/allocator_set.hpp000066400000000000000000000041551477700171100222060ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_ALLOCATOR_SET_HPP #define JSONCONS_ALLOCATOR_SET_HPP #include #include namespace jsoncons { template class allocator_set { Allocator result_alloc_; TempAllocator temp_alloc_; public: using allocator_type = Allocator; using temp_allocator_type = TempAllocator; allocator_set(const Allocator& alloc=Allocator(), const TempAllocator& temp_alloc=TempAllocator()) : result_alloc_(alloc), temp_alloc_(temp_alloc) { } allocator_set(const allocator_set&) = default; allocator_set(allocator_set&&) = default; allocator_set& operator=(const allocator_set&) = delete; allocator_set& operator=(allocator_set&&) = delete; ~allocator_set() = default; Allocator get_allocator() const {return result_alloc_;} TempAllocator get_temp_allocator() const {return temp_alloc_;} }; inline allocator_set,std::allocator> combine_allocators() { return allocator_set,std::allocator>(std::allocator(), std::allocator()); } template allocator_set> combine_allocators(const Allocator& alloc) { return allocator_set>(alloc, std::allocator()); } template allocator_set combine_allocators(const Allocator& alloc, const TempAllocator& temp_alloc) { return allocator_set(alloc, temp_alloc); } template allocator_set,TempAllocator> temp_allocator_only(const TempAllocator& temp_alloc) { return allocator_set,TempAllocator>(std::allocator(), temp_alloc); } } // namespace jsoncons #endif // JSONCONS_ALLOCATOR_SET_HPP jsoncons-1.3.2/include/jsoncons/basic_json.hpp000066400000000000000000005661771477700171100215060ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_BASIC_JSON_HPP #define JSONCONS_BASIC_JSON_HPP #include // std::swap #include #include #include #include // std::initializer_list #include // std::basic_istream #include // std::numeric_limits #include // std::allocator #include #include #include #include #include // std::enable_if #include #include // std::move #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(JSONCONS_HAS_POLYMORPHIC_ALLOCATOR) #include // std::poymorphic_allocator #endif namespace jsoncons { namespace extension_traits { template using container_array_iterator_type_t = decltype(Container::array_iterator_type); template using container_const_array_iterator_type_t = decltype(Container::const_array_iterator_type); template using container_object_iterator_type_t = decltype(Container::object_iterator_type); template using container_const_object_iterator_type_t = decltype(Container::const_object_iterator_type); namespace detail { template using basic_json_t = basic_json; } // namespace detail template struct is_basic_json : std::false_type {}; template struct is_basic_json::type>::value>::type > : std::true_type {}; } // namespace extension_traits namespace detail { template class random_access_iterator_wrapper { }; template class random_access_iterator_wrapper::iterator_category, std::random_access_iterator_tag>::value>::type> { Iterator it_; bool has_value_; template friend class random_access_iterator_wrapper; public: using iterator_category = std::random_access_iterator_tag; using value_type = typename std::iterator_traits::value_type; using difference_type = typename std::iterator_traits::difference_type; using pointer = typename std::iterator_traits::pointer; using reference = typename std::iterator_traits::reference; random_access_iterator_wrapper() : it_(), has_value_(false) { } explicit random_access_iterator_wrapper(Iterator ptr) : it_(ptr), has_value_(true) { } random_access_iterator_wrapper(const random_access_iterator_wrapper&) = default; random_access_iterator_wrapper(random_access_iterator_wrapper&&) = default; random_access_iterator_wrapper& operator=(const random_access_iterator_wrapper&) = default; random_access_iterator_wrapper& operator=(random_access_iterator_wrapper&&) = default; template ::value && std::is_convertible::value>::type> random_access_iterator_wrapper(const random_access_iterator_wrapper& other) : it_(other.it_), has_value_(other.has_value_) { } operator Iterator() const { return it_; } reference operator*() const { return *it_; } pointer operator->() const { return &(*it_); } random_access_iterator_wrapper& operator++() { ++it_; return *this; } random_access_iterator_wrapper operator++(int) { random_access_iterator_wrapper temp = *this; ++*this; return temp; } random_access_iterator_wrapper& operator--() { --it_; return *this; } random_access_iterator_wrapper operator--(int) { random_access_iterator_wrapper temp = *this; --*this; return temp; } random_access_iterator_wrapper& operator+=(const difference_type offset) { it_ += offset; return *this; } random_access_iterator_wrapper operator+(const difference_type offset) const { random_access_iterator_wrapper temp = *this; return temp += offset; } random_access_iterator_wrapper& operator-=(const difference_type offset) { return *this += -offset; } random_access_iterator_wrapper operator-(const difference_type offset) const { random_access_iterator_wrapper temp = *this; return temp -= offset; } difference_type operator-(const random_access_iterator_wrapper& rhs) const noexcept { return it_ - rhs.it_; } reference operator[](const difference_type offset) const noexcept { return *(*this + offset); } bool operator==(const random_access_iterator_wrapper& rhs) const noexcept { if (!has_value_ || !rhs.has_value_) { return has_value_ == rhs.has_value_ ? true : false; } else { return it_ == rhs.it_; } } bool operator!=(const random_access_iterator_wrapper& rhs) const noexcept { return !(*this == rhs); } bool operator<(const random_access_iterator_wrapper& rhs) const noexcept { if (!has_value_ || !rhs.has_value_) { return has_value_ == rhs.has_value_ ? false :(has_value_ ? false : true); } else { return it_ < rhs.it_; } } bool operator>(const random_access_iterator_wrapper& rhs) const noexcept { return rhs < *this; } bool operator<=(const random_access_iterator_wrapper& rhs) const noexcept { return !(rhs < *this); } bool operator>=(const random_access_iterator_wrapper& rhs) const noexcept { return !(*this < rhs); } inline friend random_access_iterator_wrapper operator+( difference_type offset, random_access_iterator_wrapper next) { return next += offset; } bool has_value() const { return has_value_; } }; } // namespace detail struct sorted_policy { template using object = sorted_json_object; template using array = json_array; template using member_key = std::basic_string; }; struct order_preserving_policy { template using object = order_preserving_json_object; template using array = json_array; template using member_key = std::basic_string; }; template struct object_iterator_typedefs { }; template struct object_iterator_typedefs::value || !extension_traits::is_detected::value>::type> { using object_iterator_type = jsoncons::detail::random_access_iterator_wrapper::iterator>; using const_object_iterator_type = jsoncons::detail::random_access_iterator_wrapper::const_iterator>; }; template struct object_iterator_typedefs::value && extension_traits::is_detected::value>::type> { using object_iterator_type = jsoncons::detail::random_access_iterator_wrapper>; using const_object_iterator_type = jsoncons::detail::random_access_iterator_wrapper>; }; template struct array_iterator_typedefs { }; template struct array_iterator_typedefs::value || !extension_traits::is_detected::value>::type> { using array_iterator_type = typename Policy::template array::iterator; using const_array_iterator_type = typename Policy::template array::const_iterator; }; template struct array_iterator_typedefs::value && extension_traits::is_detected::value>::type> { using array_iterator_type = typename Policy::template array_iterator_type; using const_array_iterator_type = typename Policy::template const_array_iterator_type; }; template class range { public: using iterator = IteratorT; using const_iterator = ConstIteratorT; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; private: iterator first_; iterator last_; public: range(const IteratorT& first, const IteratorT& last) : first_(first), last_(last) { } iterator begin() const noexcept { return first_; } iterator end() const noexcept { return last_; } const_iterator cbegin() const noexcept { return first_; } const_iterator cend() const noexcept { return last_; } reverse_iterator rbegin() const noexcept { return reverse_iterator(last_); } reverse_iterator rend() const noexcept { return reverse_iterator(first_); } const_reverse_iterator crbegin() const noexcept { return reverse_iterator(last_); } const_reverse_iterator crend() const noexcept { return reverse_iterator(first_); } }; template class basic_json { public: static_assert(std::allocator_traits::is_always_equal::value || extension_traits::is_propagating_allocator::value, "Regular stateful allocators must be wrapped with std::scoped_allocator_adaptor"); using allocator_type = Allocator; using policy_type = Policy; using char_type = CharT; using char_traits_type = std::char_traits; using string_view_type = jsoncons::basic_string_view; using char_allocator_type = typename std::allocator_traits:: template rebind_alloc; using string_type = std::basic_string; using key_type = typename policy_type::template member_key; using reference = basic_json&; using const_reference = const basic_json&; using pointer = basic_json*; using const_pointer = const basic_json*; using key_value_type = key_value; using array = typename policy_type::template array; using key_value_allocator_type = typename std::allocator_traits:: template rebind_alloc; using object = typename policy_type::template object; using object_iterator = typename object_iterator_typedefs::object_iterator_type; using const_object_iterator = typename object_iterator_typedefs::const_object_iterator_type; using array_iterator = typename array_iterator_typedefs::array_iterator_type; using const_array_iterator = typename array_iterator_typedefs::const_array_iterator_type; using object_range_type = range; using const_object_range_type = range; using array_range_type = range; using const_array_range_type = range; private: static constexpr uint8_t major_type_shift = 0x04; static constexpr uint8_t additional_information_mask = (1U << 4) - 1; public: struct common_storage { uint8_t storage_kind_:4; uint8_t short_str_length_:4; semantic_tag tag_; }; struct null_storage { uint8_t storage_kind_:4; uint8_t short_str_length_:4; semantic_tag tag_; null_storage(semantic_tag tag = semantic_tag::none) : storage_kind_(static_cast(json_storage_kind::null)), short_str_length_(0), tag_(tag) { } }; struct empty_object_storage { uint8_t storage_kind_:4; uint8_t short_str_length_:4; semantic_tag tag_; empty_object_storage(semantic_tag tag) : storage_kind_(static_cast(json_storage_kind::empty_object)), short_str_length_(0), tag_(tag) { } }; struct bool_storage { uint8_t storage_kind_:4; uint8_t short_str_length_:4; semantic_tag tag_; bool val_; bool_storage(bool val, semantic_tag tag) : storage_kind_(static_cast(json_storage_kind::boolean)), short_str_length_(0), tag_(tag), val_(val) { } bool value() const { return val_; } }; struct int64_storage { uint8_t storage_kind_:4; uint8_t short_str_length_:4; semantic_tag tag_; int64_t val_; int64_storage(int64_t val, semantic_tag tag = semantic_tag::none) : storage_kind_(static_cast(json_storage_kind::int64)), short_str_length_(0), tag_(tag), val_(val) { } int64_t value() const { return val_; } }; struct uint64_storage { uint8_t storage_kind_:4; uint8_t short_str_length_:4; semantic_tag tag_; uint64_t val_; uint64_storage(uint64_t val, semantic_tag tag = semantic_tag::none) : storage_kind_(static_cast(json_storage_kind::uint64)), short_str_length_(0), tag_(tag), val_(val) { } uint64_t value() const { return val_; } }; struct half_storage { uint8_t storage_kind_:4; uint8_t short_str_length_:4; semantic_tag tag_; uint16_t val_; half_storage(uint16_t val, semantic_tag tag = semantic_tag::none) : storage_kind_(static_cast(json_storage_kind::half_float)), short_str_length_(0), tag_(tag), val_(val) { } uint16_t value() const { return val_; } }; struct double_storage { uint8_t storage_kind_:4; uint8_t short_str_length_:4; semantic_tag tag_; double val_; double_storage(double val, semantic_tag tag = semantic_tag::none) : storage_kind_(static_cast(json_storage_kind::float64)), short_str_length_(0), tag_(tag), val_(val) { } double value() const { return val_; } }; struct short_string_storage { static constexpr size_t capacity = (2*sizeof(uint64_t) - 2*sizeof(uint8_t))/sizeof(char_type); static constexpr size_t max_length = capacity - 1; uint8_t storage_kind_:4; uint8_t short_str_length_:4; semantic_tag tag_; char_type data_[capacity]; short_string_storage(const char_type* p, uint8_t length, semantic_tag tag) : storage_kind_(static_cast(json_storage_kind::short_str)), short_str_length_(length), tag_(tag) { JSONCONS_ASSERT(length <= max_length); std::memcpy(data_,p,length*sizeof(char_type)); data_[length] = 0; } short_string_storage(const short_string_storage& other) : storage_kind_(other.storage_kind_), short_str_length_(other.short_str_length_), tag_(other.tag_) { std::memcpy(data_,other.data_,other.short_str_length_*sizeof(char_type)); data_[short_str_length_] = 0; } short_string_storage& operator=(const short_string_storage& other) = delete; uint8_t length() const { return short_str_length_; } const char_type* data() const { return data_; } const char_type* c_str() const { return data_; } }; // long_string_storage struct long_string_storage { using heap_string_factory_type = jsoncons::utility::heap_string_factory; using pointer = typename heap_string_factory_type::pointer; uint8_t storage_kind_:4; uint8_t short_str_length_:4; semantic_tag tag_; pointer ptr_; long_string_storage(pointer ptr, semantic_tag tag) : storage_kind_(static_cast(json_storage_kind::long_str)), short_str_length_(0), tag_(tag), ptr_(ptr) { } long_string_storage(const long_string_storage& other) : storage_kind_(static_cast(json_storage_kind::long_str)), short_str_length_(0), tag_(other.tag_), ptr_(other.ptr_) { } long_string_storage& operator=(const long_string_storage& other) = delete; semantic_tag tag() const { return tag_; } const char_type* data() const { return ptr_->data(); } const char_type* c_str() const { return ptr_->c_str(); } std::size_t length() const { return ptr_->length(); } Allocator get_allocator() const { return ptr_->get_allocator(); } }; // byte_string_storage struct byte_string_storage { using heap_string_factory_type = jsoncons::utility::heap_string_factory; using pointer = typename heap_string_factory_type::pointer; uint8_t storage_kind_:4; uint8_t short_str_length_:4; semantic_tag tag_; pointer ptr_; byte_string_storage(pointer ptr, semantic_tag tag) : storage_kind_(static_cast(json_storage_kind::byte_str)), short_str_length_(0), tag_(tag), ptr_(ptr) { } byte_string_storage(const byte_string_storage& other) : storage_kind_(other.storage_kind_), short_str_length_(0), tag_(other.tag_), ptr_(other.ptr_) { } byte_string_storage& operator=(const byte_string_storage& other) = delete; semantic_tag tag() const { return tag_; } const uint8_t* data() const { return ptr_->data(); } std::size_t length() const { return ptr_->length(); } uint64_t ext_tag() const { return ptr_->extra(); } Allocator get_allocator() const { return ptr_->get_allocator(); } }; #if defined(__GNUC__) && JSONCONS_GCC_AVAILABLE(12,0,0) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif struct array_storage { using allocator_type = typename std::allocator_traits:: template rebind_alloc; using pointer = typename std::allocator_traits::pointer; uint8_t storage_kind_:4; uint8_t short_str_length_:4; semantic_tag tag_; pointer ptr_; array_storage(pointer ptr, semantic_tag tag) : storage_kind_(static_cast(json_storage_kind::array)), short_str_length_(0), tag_(tag), ptr_(ptr) { } array_storage(const array_storage& other) : storage_kind_(other.storage_kind_), short_str_length_(0), tag_(other.tag_), ptr_(other.ptr_) { } void assign(const array_storage& other) { tag_ = other.tag_; *ptr_ = *(other.ptr_); } array_storage& operator=(const array_storage& other) = delete; semantic_tag tag() const { return tag_; } Allocator get_allocator() const { return ptr_->get_allocator(); } array& value() { return *ptr_; } const array& value() const { return *ptr_; } }; // object_storage struct object_storage { using allocator_type = typename std::allocator_traits:: template rebind_alloc; using pointer = typename std::allocator_traits::pointer; uint8_t storage_kind_:4; uint8_t short_str_length_:4; semantic_tag tag_; pointer ptr_; object_storage(pointer ptr, semantic_tag tag) : storage_kind_(static_cast(json_storage_kind::object)), short_str_length_(0), tag_(tag), ptr_(ptr) { } explicit object_storage(const object_storage& other) : storage_kind_(other.storage_kind_), short_str_length_(0), tag_(other.tag_), ptr_(other.ptr_) { } void assign(const object_storage& other) { tag_ = other.tag_; *ptr_ = *(other.ptr_); } object_storage& operator=(const object_storage& other) = delete; semantic_tag tag() const { return tag_; } object& value() { JSONCONS_ASSERT(ptr_ != nullptr); return *ptr_; } const object& value() const { JSONCONS_ASSERT(ptr_ != nullptr); return *ptr_; } Allocator get_allocator() const { JSONCONS_ASSERT(ptr_ != nullptr); return ptr_->get_allocator(); } }; #if defined(__GNUC__) && JSONCONS_GCC_AVAILABLE(12,0,0) # pragma GCC diagnostic pop #endif private: struct json_const_reference_storage { uint8_t storage_kind_:4; uint8_t short_str_length_:4; semantic_tag tag_; std::reference_wrapper ref_; json_const_reference_storage(const basic_json& ref) : storage_kind_(static_cast(json_storage_kind::json_const_reference)), short_str_length_(0), tag_(ref.tag()), ref_(ref) { } const basic_json& value() const { return ref_.get(); } }; struct json_reference_storage { uint8_t storage_kind_:4; uint8_t short_str_length_:4; semantic_tag tag_; std::reference_wrapper ref_; json_reference_storage(basic_json& ref) : storage_kind_(static_cast(json_storage_kind::json_reference)), short_str_length_(0), tag_(ref.tag()), ref_(ref) { } basic_json& value() { return ref_.get(); } const basic_json& value() const { return ref_.get(); } }; union { common_storage common_; null_storage null_; bool_storage boolean_; int64_storage int64_; uint64_storage uint64_; half_storage half_float_; double_storage float64_; short_string_storage short_str_; long_string_storage long_str_; byte_string_storage byte_str_; array_storage array_; object_storage object_; empty_object_storage empty_object_; json_const_reference_storage json_const_pointer_; json_reference_storage json_ref_; }; void destroy() { switch (storage_kind()) { case json_storage_kind::long_str: { if (cast().ptr_ != nullptr) { long_string_storage::heap_string_factory_type::destroy(cast().ptr_); } break; } case json_storage_kind::byte_str: if (cast().ptr_ != nullptr) { byte_string_storage::heap_string_factory_type::destroy(cast().ptr_); } break; case json_storage_kind::array: { if (cast().ptr_ != nullptr) { auto& storage = cast(); typename array_storage::allocator_type alloc{storage.ptr_->get_allocator()}; std::allocator_traits::destroy(alloc, extension_traits::to_plain_pointer(storage.ptr_)); std::allocator_traits::deallocate(alloc, storage.ptr_,1); } break; } case json_storage_kind::object: { if (cast().ptr_ != nullptr) { auto& storage = cast(); typename object_storage::allocator_type alloc{storage.ptr_->get_allocator()}; std::allocator_traits::destroy(alloc, extension_traits::to_plain_pointer(storage.ptr_)); std::allocator_traits::deallocate(alloc, storage.ptr_,1); } break; } default: break; } } typename long_string_storage::pointer create_long_string(const allocator_type& alloc, const char_type* data, std::size_t length) { using heap_string_factory_type = jsoncons::utility::heap_string_factory; return heap_string_factory_type::create(data, length, null_type(), alloc); } typename byte_string_storage::pointer create_byte_string(const allocator_type& alloc, const uint8_t* data, std::size_t length, uint64_t ext_tag) { using heap_string_factory_type = jsoncons::utility::heap_string_factory; return heap_string_factory_type::create(data, length, ext_tag, alloc); } template typename array_storage::pointer create_array(const allocator_type& alloc, Args&& ... args) { using stor_allocator_type = typename array_storage::allocator_type; stor_allocator_type stor_alloc(alloc); auto ptr = std::allocator_traits::allocate(stor_alloc, 1); JSONCONS_TRY { std::allocator_traits::construct(stor_alloc, extension_traits::to_plain_pointer(ptr), std::forward(args)...); } JSONCONS_CATCH(...) { std::allocator_traits::deallocate(stor_alloc, ptr,1); JSONCONS_RETHROW; } return ptr; } template typename object_storage::pointer create_object(const allocator_type& alloc, Args&& ... args) { using stor_allocator_type = typename object_storage::allocator_type; stor_allocator_type stor_alloc(alloc); auto ptr = std::allocator_traits::allocate(stor_alloc, 1); JSONCONS_TRY { std::allocator_traits::construct(stor_alloc, extension_traits::to_plain_pointer(ptr), std::forward(args)...); } JSONCONS_CATCH(...) { std::allocator_traits::deallocate(stor_alloc, ptr,1); JSONCONS_RETHROW; } return ptr; } template void construct(Args&&... args) { ::new (&cast()) StorageType(std::forward(args)...); } template struct identity { using type = T*; }; public: template T& cast() { return cast(identity()); } template const T& cast() const { return cast(identity()); } private: null_storage& cast(identity) { return null_; } const null_storage& cast(identity) const { return null_; } empty_object_storage& cast(identity) { return empty_object_; } const empty_object_storage& cast(identity) const { return empty_object_; } bool_storage& cast(identity) { return boolean_; } const bool_storage& cast(identity) const { return boolean_; } int64_storage& cast(identity) { return int64_; } const int64_storage& cast(identity) const { return int64_; } uint64_storage& cast(identity) { return uint64_; } const uint64_storage& cast(identity) const { return uint64_; } half_storage& cast(identity) { return half_float_; } const half_storage& cast(identity) const { return half_float_; } double_storage& cast(identity) { return float64_; } const double_storage& cast(identity) const { return float64_; } short_string_storage& cast(identity) { return short_str_; } const short_string_storage& cast(identity) const { return short_str_; } long_string_storage& cast(identity) { return long_str_; } const long_string_storage& cast(identity) const { return long_str_; } byte_string_storage& cast(identity) { return byte_str_; } const byte_string_storage& cast(identity) const { return byte_str_; } object_storage& cast(identity) { return object_; } const object_storage& cast(identity) const { return object_; } array_storage& cast(identity) { return array_; } const array_storage& cast(identity) const { return array_; } json_const_reference_storage& cast(identity) { return json_const_pointer_; } json_reference_storage& cast(identity) { return json_ref_; } const json_const_reference_storage& cast(identity) const { return json_const_pointer_; } const json_reference_storage& cast(identity) const { return json_ref_; } template void swap_l_r(basic_json& other) noexcept { swap_l_r(identity(), identity(), other); } template void swap_l_r(identity,identity,basic_json& other) noexcept { TypeR temp{other.cast()}; other.construct(cast()); construct(temp); } template void swap_l(basic_json& other) noexcept { switch (other.storage_kind()) { case json_storage_kind::null : swap_l_r(other); break; case json_storage_kind::empty_object : swap_l_r(other); break; case json_storage_kind::boolean : swap_l_r(other); break; case json_storage_kind::int64 : swap_l_r(other); break; case json_storage_kind::uint64 : swap_l_r(other); break; case json_storage_kind::half_float : swap_l_r(other); break; case json_storage_kind::float64 : swap_l_r(other); break; case json_storage_kind::short_str : swap_l_r(other); break; case json_storage_kind::long_str : swap_l_r(other); break; case json_storage_kind::byte_str : swap_l_r(other); break; case json_storage_kind::array : swap_l_r(other); break; case json_storage_kind::object : swap_l_r(other); break; case json_storage_kind::json_const_reference : swap_l_r(other); break; case json_storage_kind::json_reference : swap_l_r(other); break; default: JSONCONS_UNREACHABLE(); break; } } void uninitialized_copy(const basic_json& other) { if (is_trivial_storage(other.storage_kind())) { std::memcpy(static_cast(this), &other, sizeof(basic_json)); } else { switch (other.storage_kind()) { case json_storage_kind::long_str: { const auto& storage = other.cast(); auto ptr = create_long_string(std::allocator_traits::select_on_container_copy_construction(storage.get_allocator()), storage.data(), storage.length()); construct(ptr, other.tag()); break; } case json_storage_kind::byte_str: { const auto& storage = other.cast(); auto ptr = create_byte_string(std::allocator_traits::select_on_container_copy_construction(storage.get_allocator()), storage.data(), storage.length(), storage.ext_tag()); construct(ptr, other.tag()); break; } case json_storage_kind::array: { auto ptr = create_array( std::allocator_traits::select_on_container_copy_construction(other.cast().get_allocator()), other.cast().value()); construct(ptr, other.tag()); break; } case json_storage_kind::object: { auto ptr = create_object( std::allocator_traits::select_on_container_copy_construction(other.cast().get_allocator()), other.cast().value()); construct(ptr, other.tag()); break; } default: JSONCONS_UNREACHABLE(); break; } } } void uninitialized_copy_a(const basic_json& other, const Allocator& alloc) { if (is_trivial_storage(other.storage_kind())) { std::memcpy(static_cast(this), &other, sizeof(basic_json)); } else { switch (other.storage_kind()) { case json_storage_kind::long_str: { const auto& storage = other.cast(); auto ptr = create_long_string(alloc, storage.data(), storage.length()); construct(ptr, other.tag()); break; } case json_storage_kind::byte_str: { const auto& storage = other.cast(); auto ptr = create_byte_string(alloc, storage.data(), storage.length(), storage.ext_tag()); construct(ptr, other.tag()); break; } case json_storage_kind::array: { auto ptr = create_array(alloc, other.cast().value()); construct(ptr, other.tag()); break; } case json_storage_kind::object: { auto ptr = create_object(alloc, other.cast().value()); construct(ptr, other.tag()); break; } default: JSONCONS_UNREACHABLE(); break; } } } void uninitialized_move(basic_json&& other) noexcept { if (is_trivial_storage(other.storage_kind())) { std::memcpy(static_cast(this), &other, sizeof(basic_json)); } else { switch (other.storage_kind()) { case json_storage_kind::long_str: construct(other.cast()); other.construct(); break; case json_storage_kind::byte_str: construct(other.cast()); other.construct(); break; case json_storage_kind::array: construct(other.cast()); other.construct(); break; case json_storage_kind::object: construct(other.cast()); other.construct(); break; default: JSONCONS_UNREACHABLE(); break; } } } void uninitialized_move_a(std::true_type /* stateless allocator */, basic_json&& other, const Allocator&) noexcept { uninitialized_move(std::move(other)); } void uninitialized_move_a(std::false_type /* stateful allocator */, basic_json&& other, const Allocator& alloc) noexcept { if (is_trivial_storage(other.storage_kind())) { std::memcpy(static_cast(this), &other, sizeof(basic_json)); } else { uninitialized_copy_a(other, alloc); } } void copy_assignment(const basic_json& other) { if (is_trivial_storage(other.storage_kind())) { destroy(); std::memcpy(static_cast(this), &other, sizeof(basic_json)); } else if (storage_kind() == other.storage_kind()) { switch (other.storage_kind()) { case json_storage_kind::long_str: { auto alloc = cast().get_allocator(); destroy(); uninitialized_copy_a(other, alloc); break; } case json_storage_kind::byte_str: { auto alloc = cast().get_allocator(); destroy(); uninitialized_copy_a(other, alloc); break; } case json_storage_kind::array: cast().assign(other.cast()); break; case json_storage_kind::object: cast().assign(other.cast()); break; default: JSONCONS_UNREACHABLE(); break; } } else if (is_trivial_storage(storage_kind())) // rhs is not trivial storage { destroy(); uninitialized_copy(other); } else // lhs and rhs are not trivial storage { auto alloc = get_allocator(); destroy(); uninitialized_copy_a(other, alloc); } } void move_assignment(basic_json&& other) noexcept { if (is_trivial_storage(storage_kind()) && is_trivial_storage(other.storage_kind())) { std::memcpy(static_cast(this), &other, sizeof(basic_json)); } else { swap(other); } } basic_json& evaluate_with_default() { return *this; } basic_json& evaluate(const string_view_type& name) { return at(name); } const basic_json& evaluate(const string_view_type& name) const { return at(name); } public: basic_json& evaluate() { return *this; } const basic_json& evaluate() const { return *this; } basic_json& operator=(const basic_json& other) { if (this != &other) { copy_assignment(other); } return *this; } basic_json& operator=(basic_json&& other) noexcept { if (this != &other) { move_assignment(std::move(other)); } return *this; } json_storage_kind storage_kind() const { // It is legal to access 'common_.storage_kind_' even though // common_ is not the active member of the union because 'storage_kind_' // is a part of the common initial sequence of all union members // as defined in 11.4-25 of the Standard. return static_cast(common_.storage_kind_); } json_type type() const { switch(storage_kind()) { case json_storage_kind::null: return json_type::null_value; case json_storage_kind::boolean: return json_type::bool_value; case json_storage_kind::int64: return json_type::int64_value; case json_storage_kind::uint64: return json_type::uint64_value; case json_storage_kind::half_float: return json_type::half_value; case json_storage_kind::float64: return json_type::double_value; case json_storage_kind::short_str: case json_storage_kind::long_str: return json_type::string_value; case json_storage_kind::byte_str: return json_type::byte_string_value; case json_storage_kind::array: return json_type::array_value; case json_storage_kind::empty_object: case json_storage_kind::object: return json_type::object_value; case json_storage_kind::json_const_reference: return cast().value().type(); case json_storage_kind::json_reference: return cast().value().type(); default: JSONCONS_UNREACHABLE(); break; } } semantic_tag tag() const { // It is legal to access 'common_.tag_' even though // common_ is not the active member of the union because 'tag_' // is a part of the common initial sequence of all union members // as defined in 11.4-25 of the Standard. switch(storage_kind()) { case json_storage_kind::json_const_reference: return cast().value().tag(); case json_storage_kind::json_reference: return cast().value().tag(); default: return common_.tag_; } } std::size_t size() const { switch (storage_kind()) { case json_storage_kind::array: return cast().value().size(); case json_storage_kind::empty_object: return 0; case json_storage_kind::object: return cast().value().size(); case json_storage_kind::json_const_reference: return cast().value().size(); case json_storage_kind::json_reference: return cast().value().size(); default: return 0; } } string_view_type as_string_view() const { switch (storage_kind()) { case json_storage_kind::short_str: return string_view_type(cast().data(),cast().length()); case json_storage_kind::long_str: return string_view_type(cast().data(),cast().length()); case json_storage_kind::json_const_reference: return cast().value().as_string_view(); case json_storage_kind::json_reference: return cast().value().as_string_view(); default: JSONCONS_THROW(json_runtime_error("Not a string")); } } template > basic_byte_string as_byte_string() const { using byte_string_type = basic_byte_string; std::error_code ec; switch (storage_kind()) { case json_storage_kind::short_str: case json_storage_kind::long_str: { value_converter converter; byte_string_type v = converter.convert(as_string_view(),tag(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } return v; } case json_storage_kind::byte_str: return basic_byte_string(cast().data(),cast().length()); case json_storage_kind::json_const_reference: return cast().value().as_byte_string(); case json_storage_kind::json_reference: return cast().value().as_byte_string(); default: JSONCONS_THROW(json_runtime_error("Not a byte string")); } } byte_string_view as_byte_string_view() const { switch (storage_kind()) { case json_storage_kind::byte_str: return byte_string_view(cast().data(),cast().length()); case json_storage_kind::json_const_reference: return cast().value().as_byte_string_view(); case json_storage_kind::json_reference: return cast().value().as_byte_string_view(); default: JSONCONS_THROW(json_runtime_error("Not a byte string")); } } int compare(const basic_json& rhs) const noexcept { if (this == &rhs) { return 0; } switch (storage_kind()) { case json_storage_kind::json_const_reference: switch (rhs.storage_kind()) { case json_storage_kind::json_const_reference: return cast().value().compare(rhs.cast().value()); default: return cast().value().compare(rhs); } break; case json_storage_kind::json_reference: switch (rhs.storage_kind()) { case json_storage_kind::json_reference: return cast().value().compare(rhs.cast().value()); default: return cast().value().compare(rhs); } break; case json_storage_kind::null: return static_cast(storage_kind()) - static_cast(rhs.storage_kind()); case json_storage_kind::empty_object: switch (rhs.storage_kind()) { case json_storage_kind::empty_object: return 0; case json_storage_kind::object: return rhs.empty() ? 0 : -1; case json_storage_kind::json_const_reference: return compare(rhs.cast().value()); case json_storage_kind::json_reference: return compare(rhs.cast().value()); default: return static_cast(storage_kind()) - static_cast(rhs.storage_kind()); } break; case json_storage_kind::boolean: switch (rhs.storage_kind()) { case json_storage_kind::boolean: return static_cast(cast().value()) - static_cast(rhs.cast().value()); case json_storage_kind::json_const_reference: return compare(rhs.cast().value()); case json_storage_kind::json_reference: return compare(rhs.cast().value()); default: return static_cast(storage_kind()) - static_cast(rhs.storage_kind()); } break; case json_storage_kind::int64: switch (rhs.storage_kind()) { case json_storage_kind::int64: { if (cast().value() == rhs.cast().value()) return 0; return cast().value() < rhs.cast().value() ? -1 : 1; } case json_storage_kind::uint64: if (cast().value() < 0) return -1; else if (static_cast(cast().value()) == rhs.cast().value()) return 0; else return static_cast(cast().value()) < rhs.cast().value() ? -1 : 1; case json_storage_kind::float64: { double r = static_cast(cast().value()) - rhs.cast().value(); return r == 0.0 ? 0 : (r < 0.0 ? -1 : 1); } case json_storage_kind::json_const_reference: return compare(rhs.cast().value()); case json_storage_kind::json_reference: return compare(rhs.cast().value()); default: return static_cast(storage_kind()) - static_cast(rhs.storage_kind()); } break; case json_storage_kind::uint64: switch (rhs.storage_kind()) { case json_storage_kind::int64: if (rhs.cast().value() < 0) return 1; else if (cast().value() == static_cast(rhs.cast().value())) return 0; else return cast().value() < static_cast(rhs.cast().value()) ? -1 : 1; case json_storage_kind::uint64: if (cast().value() == static_cast(rhs.cast().value())) return 0; else return cast().value() < static_cast(rhs.cast().value()) ? -1 : 1; case json_storage_kind::float64: { auto r = static_cast(cast().value()) - rhs.cast().value(); return r == 0 ? 0 : (r < 0.0 ? -1 : 1); } case json_storage_kind::json_const_reference: return compare(rhs.cast().value()); case json_storage_kind::json_reference: return compare(rhs.cast().value()); default: return static_cast(storage_kind()) - static_cast(rhs.storage_kind()); } break; case json_storage_kind::float64: switch (rhs.storage_kind()) { case json_storage_kind::int64: { auto r = cast().value() - static_cast(rhs.cast().value()); return r == 0 ? 0 : (r < 0.0 ? -1 : 1); } case json_storage_kind::uint64: { auto r = cast().value() - static_cast(rhs.cast().value()); return r == 0 ? 0 : (r < 0.0 ? -1 : 1); } case json_storage_kind::float64: { auto r = cast().value() - rhs.cast().value(); return r == 0 ? 0 : (r < 0.0 ? -1 : 1); } case json_storage_kind::json_const_reference: return compare(rhs.cast().value()); case json_storage_kind::json_reference: return compare(rhs.cast().value()); default: if (is_string_storage(rhs.storage_kind()) && is_number_tag(rhs.tag())) { double val1 = as_double(); double val2 = rhs.as_double(); auto r = val1 - val2; return r == 0 ? 0 : (r < 0.0 ? -1 : 1); } else { return static_cast(storage_kind()) - static_cast(rhs.storage_kind()); } } break; case json_storage_kind::short_str: case json_storage_kind::long_str: if (is_number_tag(tag())) { double val1 = as_double(); switch (rhs.storage_kind()) { case json_storage_kind::int64: { auto r = val1 - static_cast(rhs.cast().value()); return r == 0 ? 0 : (r < 0.0 ? -1 : 1); } case json_storage_kind::uint64: { auto r = val1 - static_cast(rhs.cast().value()); return r == 0 ? 0 : (r < 0.0 ? -1 : 1); } case json_storage_kind::float64: { auto r = val1 - rhs.cast().value(); return r == 0 ? 0 : (r < 0.0 ? -1 : 1); } case json_storage_kind::json_const_reference: return compare(rhs.cast().value()); case json_storage_kind::json_reference: return compare(rhs.cast().value()); default: if (is_string_storage(rhs.storage_kind())) { double val2 = rhs.as_double(); auto r = val1 - val2; return r == 0 ? 0 : (r < 0.0 ? -1 : 1); } else { return static_cast(storage_kind()) - static_cast(rhs.storage_kind()); } } } else { // compare regular text switch (rhs.storage_kind()) { case json_storage_kind::short_str: return as_string_view().compare(rhs.as_string_view()); case json_storage_kind::long_str: return as_string_view().compare(rhs.as_string_view()); case json_storage_kind::json_const_reference: return compare(rhs.cast().value()); case json_storage_kind::json_reference: return compare(rhs.cast().value()); default: return static_cast(storage_kind()) - static_cast(rhs.storage_kind()); } } break; case json_storage_kind::byte_str: switch (rhs.storage_kind()) { case json_storage_kind::byte_str: { return as_byte_string_view().compare(rhs.as_byte_string_view()); } case json_storage_kind::json_const_reference: return compare(rhs.cast().value()); case json_storage_kind::json_reference: return compare(rhs.cast().value()); default: return static_cast(storage_kind()) - static_cast(rhs.storage_kind()); } break; case json_storage_kind::array: switch (rhs.storage_kind()) { case json_storage_kind::array: { if (cast().value() == rhs.cast().value()) return 0; else return cast().value() < rhs.cast().value() ? -1 : 1; } case json_storage_kind::json_const_reference: return compare(rhs.cast().value()); case json_storage_kind::json_reference: return compare(rhs.cast().value()); default: return static_cast(storage_kind()) - static_cast(rhs.storage_kind()); } break; case json_storage_kind::object: switch (rhs.storage_kind()) { case json_storage_kind::empty_object: return empty() ? 0 : 1; case json_storage_kind::object: { if (cast().value() == rhs.cast().value()) return 0; else return cast().value() < rhs.cast().value() ? -1 : 1; } case json_storage_kind::json_const_reference: return compare(rhs.cast().value()); case json_storage_kind::json_reference: return compare(rhs.cast().value()); default: return static_cast(storage_kind()) - static_cast(rhs.storage_kind()); } break; default: JSONCONS_UNREACHABLE(); break; } } void swap(basic_json& other) noexcept { if (this == &other) { return; } if (is_trivial_storage(storage_kind()) && is_trivial_storage(other.storage_kind())) { basic_json temp; std::memcpy(static_cast(&temp), static_cast(&other), sizeof(basic_json)); std::memcpy(static_cast(&other), static_cast(this), sizeof(basic_json)); std::memcpy(static_cast(this), static_cast(&temp), sizeof(basic_json)); } else { switch (storage_kind()) { case json_storage_kind::null: swap_l(other); break; case json_storage_kind::empty_object : swap_l(other); break; case json_storage_kind::boolean: swap_l(other); break; case json_storage_kind::int64: swap_l(other); break; case json_storage_kind::uint64: swap_l(other); break; case json_storage_kind::half_float: swap_l(other); break; case json_storage_kind::float64: swap_l(other); break; case json_storage_kind::short_str: swap_l(other); break; case json_storage_kind::long_str: swap_l(other); break; case json_storage_kind::byte_str: swap_l(other); break; case json_storage_kind::array: swap_l(other); break; case json_storage_kind::object: swap_l(other); break; case json_storage_kind::json_const_reference: swap_l(other); break; case json_storage_kind::json_reference: swap_l(other); break; default: JSONCONS_UNREACHABLE(); break; } } } // from string template static typename std::enable_if::value,basic_json>::type parse(const Source& source, const basic_json_decode_options& options = basic_json_options()) { json_decoder decoder; basic_json_parser parser(options); auto r = unicode_traits::detect_encoding_from_bom(source.data(), source.size()); if (!(r.encoding == unicode_traits::encoding_kind::utf8 || r.encoding == unicode_traits::encoding_kind::undetected)) { JSONCONS_THROW(ser_error(json_errc::illegal_unicode_character,parser.line(),parser.column())); } std::size_t offset = (r.ptr - source.data()); parser.update(source.data()+offset,source.size()-offset); parser.parse_some(decoder); parser.finish_parse(decoder); parser.check_done(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(json_errc::source_error, "Failed to parse json string")); } return decoder.get_result(); } template static typename std::enable_if::value,basic_json>::type parse(const allocator_set& alloc_set, const Source& source, const basic_json_decode_options& options = basic_json_options()) { json_decoder decoder(alloc_set.get_allocator(), alloc_set.get_temp_allocator()); basic_json_parser parser(options, alloc_set.get_temp_allocator()); auto r = unicode_traits::detect_encoding_from_bom(source.data(), source.size()); if (!(r.encoding == unicode_traits::encoding_kind::utf8 || r.encoding == unicode_traits::encoding_kind::undetected)) { JSONCONS_THROW(ser_error(json_errc::illegal_unicode_character,parser.line(),parser.column())); } std::size_t offset = (r.ptr - source.data()); parser.update(source.data()+offset,source.size()-offset); parser.parse_some(decoder); parser.finish_parse(decoder); parser.check_done(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(json_errc::source_error, "Failed to parse json string")); } return decoder.get_result(); } static basic_json parse(const char_type* str, std::size_t length, const basic_json_decode_options& options = basic_json_options()) { return parse(jsoncons::string_view(str,length), options); } static basic_json parse(const char_type* source, const basic_json_decode_options& options = basic_json_options()) { return parse(jsoncons::basic_string_view(source), options); } template static basic_json parse(const allocator_set& alloc_set, const char_type* source, const basic_json_decode_options& options = basic_json_options()) { return parse(alloc_set, jsoncons::basic_string_view(source), options); } template static basic_json parse(const allocator_set& alloc_set, const char_type* str, std::size_t length, const basic_json_decode_options& options = basic_json_options()) { return parse(alloc_set, jsoncons::basic_string_view(str, length), options); } // from stream static basic_json parse(std::basic_istream& is, const basic_json_decode_options& options = basic_json_options()) { json_decoder decoder; basic_json_reader,Allocator> reader(is, decoder, options); reader.read_next(); reader.check_done(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(json_errc::source_error, "Failed to parse json stream")); } return decoder.get_result(); } template static basic_json parse(const allocator_set& alloc_set, std::basic_istream& is, const basic_json_decode_options& options = basic_json_options()) { json_decoder decoder(alloc_set.get_allocator(), alloc_set.get_temp_allocator()); basic_json_reader,Allocator> reader(is, decoder, options, alloc_set.get_temp_allocator()); reader.read_next(); reader.check_done(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(json_errc::source_error, "Failed to parse json stream")); } return decoder.get_result(); } // from iterator template static basic_json parse(InputIt first, InputIt last, const basic_json_decode_options& options = basic_json_options()) { json_decoder decoder; basic_json_reader,Allocator> reader(iterator_source(std::forward(first), std::forward(last)), decoder, options); reader.read_next(); reader.check_done(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(json_errc::source_error, "Failed to parse json from iterator pair")); } return decoder.get_result(); } template static basic_json parse(const allocator_set& alloc_set, InputIt first, InputIt last, const basic_json_decode_options& options = basic_json_options()) { json_decoder decoder(alloc_set.get_allocator(), alloc_set.get_temp_allocator()); basic_json_reader,Allocator> reader(iterator_source(std::forward(first), std::forward(last)), decoder, options, alloc_set.get_temp_allocator()); reader.read_next(); reader.check_done(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(json_errc::source_error, "Failed to parse json from iterator pair")); } return decoder.get_result(); } #if !defined(JSONCONS_NO_DEPRECATED) static basic_json parse(const char_type* s, const basic_json_decode_options& options, std::function err_handler) { return parse(jsoncons::basic_string_view(s), options, err_handler); } static basic_json parse(const char_type* s, std::function err_handler) { return parse(jsoncons::basic_string_view(s), basic_json_decode_options(), err_handler); } static basic_json parse(std::basic_istream& is, const basic_json_decode_options& options, std::function err_handler) { json_decoder decoder; basic_json_reader> reader(is, decoder, options, err_handler); reader.read_next(); reader.check_done(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(json_errc::source_error, "Failed to parse json stream")); } return decoder.get_result(); } static basic_json parse(std::basic_istream& is, std::function err_handler) { return parse(is, basic_json_decode_options(), err_handler); } template static basic_json parse(InputIt first, InputIt last, const basic_json_decode_options& options, std::function err_handler) { json_decoder decoder; basic_json_reader> reader(iterator_source(std::forward(first),std::forward(last)), decoder, options, err_handler); reader.read_next(); reader.check_done(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(json_errc::source_error, "Failed to parse json from iterator pair")); } return decoder.get_result(); } template static typename std::enable_if::value,basic_json>::type parse(const Source& source, const basic_json_decode_options& options, std::function err_handler) { json_decoder decoder; basic_json_parser parser(options,err_handler); auto r = unicode_traits::detect_encoding_from_bom(source.data(), source.size()); if (!(r.encoding == unicode_traits::encoding_kind::utf8 || r.encoding == unicode_traits::encoding_kind::undetected)) { JSONCONS_THROW(ser_error(json_errc::illegal_unicode_character,parser.line(),parser.column())); } std::size_t offset = (r.ptr - source.data()); parser.update(source.data()+offset,source.size()-offset); parser.parse_some(decoder); parser.finish_parse(decoder); parser.check_done(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(json_errc::source_error, "Failed to parse json string")); } return decoder.get_result(); } template static typename std::enable_if::value,basic_json>::type parse(const Source& source, std::function err_handler) { return parse(source, basic_json_decode_options(), err_handler); } template static basic_json parse(InputIt first, InputIt last, std::function err_handler) { return parse(first, last, basic_json_decode_options(), err_handler); } #endif static basic_json make_array() { return basic_json(array()); } static basic_json make_array(const array& alloc) { return basic_json(alloc); } static basic_json make_array(const array& a, allocator_type alloc) { return basic_json(a, semantic_tag::none, alloc); } static basic_json make_array(std::initializer_list init, const Allocator& alloc = Allocator()) { return array(std::move(init),alloc); } static basic_json make_array(std::size_t n, const Allocator& alloc = Allocator()) { return array(n,alloc); } template static basic_json make_array(std::size_t n, const T& val, const Allocator& alloc = Allocator()) { return basic_json::array(n, val,alloc); } template static typename std::enable_if::type make_array(std::size_t n) { return array(n); } template static typename std::enable_if::type make_array(std::size_t n, const T& val, const Allocator& alloc = Allocator()) { return array(n,val,alloc); } template static typename std::enable_if<(dim>1),basic_json>::type make_array(std::size_t n, Args... args) { const size_t dim1 = dim - 1; basic_json val = make_array(std::forward(args)...); val.resize(n); for (std::size_t i = 0; i < n; ++i) { val[i] = make_array(std::forward(args)...); } return val; } static const basic_json& null() { static const basic_json a_null = basic_json(null_arg, semantic_tag::none); return a_null; } basic_json() { construct(semantic_tag::none); } explicit basic_json(const Allocator& alloc) { auto ptr = create_object(alloc); construct(ptr, semantic_tag::none); } basic_json(semantic_tag tag, const Allocator& alloc) { auto ptr = create_object(alloc); construct(ptr, tag); } basic_json(semantic_tag tag) { construct(tag); } basic_json(const basic_json& other) { uninitialized_copy(other); } basic_json(const basic_json& other, const Allocator& alloc) { uninitialized_copy_a(other,alloc); } basic_json(basic_json&& other) noexcept { uninitialized_move(std::move(other)); } template basic_json(basic_json&& other, const Allocator& alloc) noexcept { uninitialized_move_a(typename std::allocator_traits::is_always_equal(), std::move(other), alloc); } explicit basic_json(json_object_arg_t, semantic_tag tag, const Allocator& alloc = Allocator()) { auto ptr = create_object(alloc); construct(ptr, tag); } explicit basic_json(json_object_arg_t, const Allocator& alloc = Allocator()) { auto ptr = create_object(alloc); construct(ptr, semantic_tag::none); } template basic_json(json_object_arg_t, InputIt first, InputIt last, semantic_tag tag = semantic_tag::none, const Allocator& alloc = Allocator()) { auto ptr = create_object(alloc, first, last); construct(ptr, tag); } basic_json(json_object_arg_t, std::initializer_list,basic_json>> init, semantic_tag tag = semantic_tag::none, const Allocator& alloc = Allocator()) { //construct(object(init,alloc), tag); auto ptr = create_object(alloc, init); construct(ptr, tag); } explicit basic_json(json_array_arg_t, const Allocator& alloc = Allocator()) { auto ptr = create_array(alloc); construct(ptr, semantic_tag::none); } basic_json(json_array_arg_t, std::size_t count, const basic_json& value, semantic_tag tag = semantic_tag::none, const Allocator& alloc = Allocator()) { auto ptr = create_array(alloc, count, value); construct(ptr, tag); } basic_json(json_array_arg_t, semantic_tag tag, const Allocator& alloc = Allocator()) { auto ptr = create_array(alloc); construct(ptr, tag); } template basic_json(json_array_arg_t, InputIt first, InputIt last, semantic_tag tag = semantic_tag::none, const Allocator& alloc = Allocator()) { auto ptr = create_array(alloc, first, last); construct(ptr, tag); } basic_json(json_array_arg_t, std::initializer_list init, semantic_tag tag = semantic_tag::none, const Allocator& alloc = Allocator()) { auto ptr = create_array(alloc, init); construct(ptr, tag); } basic_json(json_const_pointer_arg_t, const basic_json* ptr) noexcept { if (ptr == nullptr) { construct(semantic_tag::none); } else { construct(*ptr); } } basic_json(json_pointer_arg_t, basic_json* ptr) noexcept { if (ptr == nullptr) { construct(semantic_tag::none); } else { construct(*ptr); } } basic_json(const array& val, semantic_tag tag = semantic_tag::none) { auto ptr = create_array( std::allocator_traits::select_on_container_copy_construction(val.get_allocator()), val); construct(ptr, tag); } basic_json(array&& val, semantic_tag tag = semantic_tag::none) { auto alloc = val.get_allocator(); auto ptr = create_array(alloc, std::move(val)); construct(ptr, tag); } basic_json(const object& val, semantic_tag tag = semantic_tag::none) { auto ptr = create_object( std::allocator_traits::select_on_container_copy_construction(val.get_allocator()), val); construct(ptr, tag); } basic_json(object&& val, semantic_tag tag = semantic_tag::none) { auto alloc = val.get_allocator(); auto ptr = create_object(alloc, std::move(val)); construct(ptr, tag); } template ::value>::type> basic_json(const T& val) : basic_json(json_type_traits::to_json(val)) { } template ::value>::type> basic_json(const T& val, const Allocator& alloc) : basic_json(json_type_traits::to_json(val,alloc)) { } basic_json(const string_type& s) : basic_json(s.data(), s.size(), semantic_tag::none, s.get_allocator()) { } basic_json(const string_view_type& s, const allocator_type& alloc = allocator_type()) : basic_json(s.data(), s.size(), semantic_tag::none, alloc) { } basic_json(const string_type& s, semantic_tag tag) : basic_json(s.data(), s.size(), tag, s.get_allocator()) { } basic_json(const string_type& s, semantic_tag tag, const allocator_type& alloc) : basic_json(s.data(), s.size(), tag, alloc) { } basic_json(const char_type* s, semantic_tag tag = semantic_tag::none) : basic_json(s, char_traits_type::length(s), tag) { } basic_json(const char_type* s, semantic_tag tag, const allocator_type& alloc) : basic_json(s, char_traits_type::length(s), tag, alloc) { } basic_json(const char_type* s, const Allocator& alloc) : basic_json(s, char_traits_type::length(s), semantic_tag::none, alloc) { } basic_json(const char_type* s, std::size_t length, semantic_tag tag = semantic_tag::none) { if (length <= short_string_storage::max_length) { construct(s, static_cast(length), tag); } else { auto ptr = create_long_string(allocator_type{}, s, length); construct(ptr, tag); } } basic_json(const char_type* s, std::size_t length, semantic_tag tag, const Allocator& alloc) { if (length <= short_string_storage::max_length) { construct(s, static_cast(length), tag); } else { auto ptr = create_long_string(alloc, s, length); construct(ptr, tag); } } basic_json(half_arg_t, uint16_t val, semantic_tag tag = semantic_tag::none) { construct(val, tag); } basic_json(half_arg_t, uint16_t val, semantic_tag tag, const allocator_type&) { construct(val, tag); } basic_json(double val, semantic_tag tag) { construct(val, tag); } basic_json(double val, semantic_tag tag, const allocator_type&) { construct(val, tag); } template basic_json(IntegerType val, semantic_tag tag, typename std::enable_if::value && sizeof(IntegerType) <= sizeof(uint64_t), int>::type = 0) { construct(val, tag); } template basic_json(IntegerType val, semantic_tag tag, Allocator, typename std::enable_if::value && sizeof(IntegerType) <= sizeof(uint64_t), int>::type = 0) { construct(val, tag); } template basic_json(IntegerType val, semantic_tag, const Allocator& alloc = Allocator(), typename std::enable_if::value && sizeof(uint64_t) < sizeof(IntegerType), int>::type = 0) { std::basic_string s; jsoncons::detail::from_integer(val, s); if (s.length() <= short_string_storage::max_length) { construct(s.data(), static_cast(s.length()), semantic_tag::bigint); } else { auto ptr = create_long_string(alloc, s.data(), s.length()); construct(ptr, semantic_tag::bigint); } } template basic_json(IntegerType val, semantic_tag tag, typename std::enable_if::value && sizeof(IntegerType) <= sizeof(int64_t),int>::type = 0) { construct(val, tag); } template basic_json(IntegerType val, semantic_tag tag, Allocator, typename std::enable_if::value && sizeof(IntegerType) <= sizeof(int64_t),int>::type = 0) { construct(val, tag); } template basic_json(IntegerType val, semantic_tag, const Allocator& alloc = Allocator(), typename std::enable_if::value && sizeof(int64_t) < sizeof(IntegerType),int>::type = 0) { std::basic_string s; jsoncons::detail::from_integer(val, s); if (s.length() <= short_string_storage::max_length) { construct(s.data(), static_cast(s.length()), semantic_tag::bigint); } else { auto ptr = create_long_string(alloc, s.data(), s.length()); construct(ptr, semantic_tag::bigint); } } basic_json(null_type, semantic_tag tag) { construct(tag); } basic_json(null_type, semantic_tag tag, const Allocator&) { construct(tag); } basic_json(bool val, semantic_tag tag) { construct(val,tag); } basic_json(bool val, semantic_tag tag, const Allocator&) { construct(val,tag); } basic_json(const string_view_type& sv, semantic_tag tag, const allocator_type& alloc = allocator_type()) : basic_json(sv.data(), sv.length(), tag, alloc) { } template basic_json(byte_string_arg_t, const Source& source, semantic_tag tag = semantic_tag::none, const Allocator& alloc = Allocator(), typename std::enable_if::value,int>::type = 0) { auto bytes = jsoncons::span(reinterpret_cast(source.data()), source.size()); auto ptr = create_byte_string(alloc, bytes.data(), bytes.size(), 0); construct(ptr, tag); } template basic_json(byte_string_arg_t, const Source& source, uint64_t ext_tag, const Allocator& alloc = Allocator(), typename std::enable_if::value,int>::type = 0) { auto bytes = jsoncons::span(reinterpret_cast(source.data()), source.size()); auto ptr = create_byte_string(alloc, bytes.data(), bytes.size(), ext_tag); construct(ptr, semantic_tag::ext); } ~basic_json() noexcept { destroy(); } template basic_json& operator=(const T& val) { *this = json_type_traits::to_json(val); return *this; } basic_json& operator=(const char_type* s) { *this = basic_json(s, char_traits_type::length(s), semantic_tag::none); return *this; } basic_json& operator[](std::size_t i) { return at(i); } const basic_json& operator[](std::size_t i) const { return at(i); } basic_json& operator[](const string_view_type& key) { switch (storage_kind()) { case json_storage_kind::empty_object: return try_emplace(key, basic_json{}).first->value(); case json_storage_kind::object: { auto it = cast().value().find(key); if (it == cast().value().end()) { return try_emplace(key, basic_json{}).first->value(); } else { return (*it).value(); } break; } case json_storage_kind::json_reference: return cast().value()[key]; default: JSONCONS_THROW(not_an_object(key.data(),key.length())); } } const basic_json& operator[](const string_view_type& key) const { static const basic_json an_empty_object = basic_json(); switch (storage_kind()) { case json_storage_kind::empty_object: return an_empty_object; case json_storage_kind::object: { auto it = cast().value().find(key); if (it == cast().value().end()) { return an_empty_object; } else { return (*it).value(); } break; } case json_storage_kind::json_const_reference: return cast().value().at(key); case json_storage_kind::json_reference: return cast().value()[key]; default: JSONCONS_THROW(not_an_object(key.data(),key.length())); } } template typename std::enable_if::value>::type dump(CharContainer& cont, const basic_json_encode_options& options = basic_json_options(), indenting indent = indenting::no_indent) const { std::error_code ec; dump(cont, options, indent, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } template typename std::enable_if::value>::type dump_pretty(CharContainer& cont, const basic_json_encode_options& options = basic_json_options()) const { std::error_code ec; dump_pretty(cont, options, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } void dump(std::basic_ostream& os, const basic_json_encode_options& options = basic_json_options(), indenting indent = indenting::no_indent) const { std::error_code ec; dump(os, options, indent, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } template typename std::enable_if::value>::type dump_pretty(CharContainer& cont, const basic_json_encode_options& options, std::error_code& ec) const { basic_json_encoder> encoder(cont, options); dump(encoder, ec); } template typename std::enable_if::value>::type dump_pretty(CharContainer& cont, std::error_code& ec) const { dump_pretty(cont, basic_json_encode_options(), ec); } void dump_pretty(std::basic_ostream& os, const basic_json_encode_options& options = basic_json_options()) const { std::error_code ec; dump_pretty(os, options, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } void dump_pretty(std::basic_ostream& os, const basic_json_encode_options& options, std::error_code& ec) const { basic_json_encoder encoder(os, options); dump(encoder, ec); } void dump_pretty(std::basic_ostream& os, std::error_code& ec) const { dump_pretty(os, basic_json_encode_options(), ec); } template typename std::enable_if::value>::type dump(CharContainer& cont, indenting indent) const { std::error_code ec; dump(cont, indent, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } void dump(std::basic_ostream& os, indenting indent) const { std::error_code ec; dump(os, indent, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } void dump(basic_json_visitor& visitor) const { std::error_code ec; dump(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } // dump template typename std::enable_if::value>::type dump(CharContainer& cont, const basic_json_encode_options& options, std::error_code& ec) const { basic_compact_json_encoder> encoder(cont, options); dump(encoder, ec); } template typename std::enable_if::value>::type dump(CharContainer& cont, std::error_code& ec) const { basic_compact_json_encoder> encoder(cont); dump(encoder, ec); } void dump(std::basic_ostream& os, const basic_json_encode_options& options, std::error_code& ec) const { basic_compact_json_encoder encoder(os, options); dump(encoder, ec); } void dump(std::basic_ostream& os, std::error_code& ec) const { basic_compact_json_encoder encoder(os); dump(encoder, ec); } // legacy template typename std::enable_if::value>::type dump(CharContainer& cont, const basic_json_encode_options& options, indenting indent, std::error_code& ec) const { if (indent == indenting::indent) { dump_pretty(cont, options, ec); } else { dump(cont, options, ec); } } template typename std::enable_if::value>::type dump(CharContainer& cont, indenting indent, std::error_code& ec) const { if (indent == indenting::indent) { dump_pretty(cont, ec); } else { dump(cont, ec); } } void dump(std::basic_ostream& os, const basic_json_encode_options& options, indenting indent, std::error_code& ec) const { if (indent == indenting::indent) { dump_pretty(os, options, ec); } else { dump(os, options, ec); } } void dump(std::basic_ostream& os, indenting indent, std::error_code& ec) const { if (indent == indenting::indent) { dump_pretty(os, ec); } else { dump(os, ec); } } // end legacy void dump(basic_json_visitor& visitor, std::error_code& ec) const { dump_noflush(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { return; } visitor.flush(); } bool is_null() const noexcept { switch (storage_kind()) { case json_storage_kind::null: return true; case json_storage_kind::json_const_reference: return cast().value().is_null(); case json_storage_kind::json_reference: return cast().value().is_null(); default: return false; } } allocator_type get_default_allocator(std::false_type) const { JSONCONS_THROW(json_runtime_error("No default allocator if allocator is not default constructible.")); } allocator_type get_default_allocator(std::true_type) const { return allocator_type{}; } template allocator_type get_allocator() const { switch (storage_kind()) { case json_storage_kind::long_str: return cast().get_allocator(); case json_storage_kind::byte_str: return cast().get_allocator(); case json_storage_kind::array: return cast().get_allocator(); case json_storage_kind::object: return cast().get_allocator(); case json_storage_kind::json_reference: return cast().value().get_allocator(); default: return get_default_allocator(typename std::allocator_traits::is_always_equal()); } } uint64_t ext_tag() const { switch (storage_kind()) { case json_storage_kind::byte_str: { return cast().ext_tag(); } case json_storage_kind::json_const_reference: return cast().value().ext_tag(); case json_storage_kind::json_reference: return cast().value().ext_tag(); default: return 0; } } bool contains(const string_view_type& key) const noexcept { switch (storage_kind()) { case json_storage_kind::object: { auto it = cast().value().find(key); return it != cast().value().end(); } case json_storage_kind::json_const_reference: return cast().value().contains(key); case json_storage_kind::json_reference: return cast().value().contains(key); default: return false; } } std::size_t count(const string_view_type& key) const { switch (storage_kind()) { case json_storage_kind::object: { auto it = cast().value().find(key); if (it == cast().value().end()) { return 0; } std::size_t count = 0; while (it != cast().value().end()&& (*it).key() == key) { ++count; ++it; } return count; } case json_storage_kind::json_const_reference: return cast().value().count(key); case json_storage_kind::json_reference: return cast().value().count(key); default: return 0; } } template bool is(Args&&... args) const noexcept { return json_type_traits::is(*this,std::forward(args)...); } bool is_string() const noexcept { switch (storage_kind()) { case json_storage_kind::short_str: case json_storage_kind::long_str: return true; case json_storage_kind::json_const_reference: return cast().value().is_string(); case json_storage_kind::json_reference: return cast().value().is_string(); default: return false; } } bool is_string_view() const noexcept { return is_string(); } bool is_byte_string() const noexcept { switch (storage_kind()) { case json_storage_kind::byte_str: return true; case json_storage_kind::json_const_reference: return cast().value().is_byte_string(); case json_storage_kind::json_reference: return cast().value().is_byte_string(); default: return false; } } bool is_byte_string_view() const noexcept { return is_byte_string(); } bool is_bignum() const { switch (storage_kind()) { case json_storage_kind::short_str: case json_storage_kind::long_str: return jsoncons::detail::is_base10(as_string_view().data(), as_string_view().length()); case json_storage_kind::int64: case json_storage_kind::uint64: return true; case json_storage_kind::json_reference: return cast().value().is_bignum(); default: return false; } } bool is_bool() const noexcept { switch (storage_kind()) { case json_storage_kind::boolean: return true; case json_storage_kind::json_const_reference: return cast().value().is_bool(); case json_storage_kind::json_reference: return cast().value().is_bool(); default: return false; } } bool is_object() const noexcept { switch (storage_kind()) { case json_storage_kind::empty_object: case json_storage_kind::object: return true; case json_storage_kind::json_const_reference: return cast().value().is_object(); case json_storage_kind::json_reference: return cast().value().is_object(); default: return false; } } bool is_array() const noexcept { switch (storage_kind()) { case json_storage_kind::array: return true; case json_storage_kind::json_const_reference: return cast().value().is_array(); case json_storage_kind::json_reference: return cast().value().is_array(); default: return false; } } bool is_int64() const noexcept { switch (storage_kind()) { case json_storage_kind::int64: return true; case json_storage_kind::uint64: return as_integer() <= static_cast((std::numeric_limits::max)()); case json_storage_kind::json_const_reference: return cast().value().is_int64(); case json_storage_kind::json_reference: return cast().value().is_int64(); default: return false; } } bool is_uint64() const noexcept { switch (storage_kind()) { case json_storage_kind::uint64: return true; case json_storage_kind::int64: return as_integer() >= 0; case json_storage_kind::json_const_reference: return cast().value().is_uint64(); case json_storage_kind::json_reference: return cast().value().is_uint64(); default: return false; } } bool is_half() const noexcept { switch (storage_kind()) { case json_storage_kind::half_float: return true; case json_storage_kind::json_const_reference: return cast().value().is_half(); case json_storage_kind::json_reference: return cast().value().is_half(); default: return false; } } bool is_double() const noexcept { switch (storage_kind()) { case json_storage_kind::float64: return true; case json_storage_kind::json_const_reference: return cast().value().is_double(); case json_storage_kind::json_reference: return cast().value().is_double(); default: return false; } } bool is_number() const noexcept { switch (storage_kind()) { case json_storage_kind::int64: case json_storage_kind::uint64: case json_storage_kind::half_float: case json_storage_kind::float64: return true; case json_storage_kind::short_str: case json_storage_kind::long_str: return tag() == semantic_tag::bigint || tag() == semantic_tag::bigdec || tag() == semantic_tag::bigfloat; case json_storage_kind::json_const_reference: return cast().value().is_number(); case json_storage_kind::json_reference: return cast().value().is_number(); default: return false; } } bool empty() const noexcept { switch (storage_kind()) { case json_storage_kind::byte_str: return cast().length() == 0; break; case json_storage_kind::short_str: return cast().length() == 0; case json_storage_kind::long_str: return cast().length() == 0; case json_storage_kind::array: return cast().value().empty(); case json_storage_kind::empty_object: return true; case json_storage_kind::object: return cast().value().empty(); case json_storage_kind::json_const_reference: return cast().value().empty(); case json_storage_kind::json_reference: return cast().value().empty(); default: return false; } } std::size_t capacity() const { switch (storage_kind()) { case json_storage_kind::array: return cast().value().capacity(); case json_storage_kind::object: return cast().value().capacity(); case json_storage_kind::json_const_reference: return cast().value().capacity(); case json_storage_kind::json_reference: return cast().value().capacity(); default: return 0; } } template void create_object_implicitly() { create_object_implicitly(typename std::allocator_traits::is_always_equal()); } void create_object_implicitly(std::false_type) { JSONCONS_THROW(json_runtime_error("Cannot create object implicitly - allocator is stateful.")); } void create_object_implicitly(std::true_type) { *this = basic_json(json_object_arg, tag()); } void reserve(std::size_t n) { if (n > 0) { switch (storage_kind()) { case json_storage_kind::array: cast().value().reserve(n); break; case json_storage_kind::empty_object: create_object_implicitly(); cast().value().reserve(n); break; case json_storage_kind::object: cast().value().reserve(n); break; case json_storage_kind::json_reference: cast().value().reserve(n); break; default: break; } } } void resize(std::size_t n) { switch (storage_kind()) { case json_storage_kind::array: cast().value().resize(n); break; case json_storage_kind::json_reference: cast().value().resize(n); break; default: break; } } template void resize(std::size_t n, T val) { switch (storage_kind()) { case json_storage_kind::array: cast().value().resize(n, val); break; case json_storage_kind::json_reference: cast().value().resize(n, val); break; default: break; } } template typename std::enable_if::value,T>::type as() const { T val = json_type_traits::as(*this); return val; } template typename std::enable_if<(!extension_traits::is_string::value && extension_traits::is_back_insertable_byte_container::value) || extension_traits::is_basic_byte_string::value,T>::type as(byte_string_arg_t, semantic_tag hint) const { std::error_code ec; switch (storage_kind()) { case json_storage_kind::short_str: case json_storage_kind::long_str: { switch (tag()) { case semantic_tag::base16: case semantic_tag::base64: case semantic_tag::base64url: { value_converter,T> converter; T v = converter.convert(as_string_view(),tag(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } return v; } default: { value_converter, T> converter; T v = converter.convert(as_string_view(), hint, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } return T(v.begin(),v.end()); } break; } break; } case json_storage_kind::byte_str: return T(as_byte_string_view().begin(), as_byte_string_view().end()); case json_storage_kind::json_const_reference: return cast().value().template as(byte_string_arg, hint); case json_storage_kind::json_reference: return cast().value().template as(byte_string_arg, hint); default: JSONCONS_THROW(json_runtime_error("Not a byte string")); } } bool as_bool() const { switch (storage_kind()) { case json_storage_kind::boolean: return cast().value(); case json_storage_kind::int64: return cast().value() != 0; case json_storage_kind::uint64: return cast().value() != 0; case json_storage_kind::json_const_reference: return cast().value().as_bool(); case json_storage_kind::json_reference: return cast().value().as_bool(); default: JSONCONS_THROW(json_runtime_error("Not a bool")); } } template IntegerType as_integer() const { switch (storage_kind()) { case json_storage_kind::short_str: case json_storage_kind::long_str: { IntegerType val; auto result = jsoncons::detail::to_integer(as_string_view().data(), as_string_view().length(), val); if (!result) { JSONCONS_THROW(json_runtime_error(result.error_code().message())); } return val; } case json_storage_kind::half_float: return static_cast(cast().value()); case json_storage_kind::float64: return static_cast(cast().value()); case json_storage_kind::int64: return static_cast(cast().value()); case json_storage_kind::uint64: return static_cast(cast().value()); case json_storage_kind::boolean: return static_cast(cast().value() ? 1 : 0); case json_storage_kind::json_const_reference: return cast().value().template as_integer(); case json_storage_kind::json_reference: return cast().value().template as_integer(); default: JSONCONS_THROW(json_runtime_error("Not an integer")); } } template typename std::enable_if::value && sizeof(IntegerType) <= sizeof(int64_t),bool>::type is_integer() const noexcept { switch (storage_kind()) { case json_storage_kind::int64: return (as_integer() >= (extension_traits::integer_limits::lowest)()) && (as_integer() <= (extension_traits::integer_limits::max)()); case json_storage_kind::uint64: return as_integer() <= static_cast((extension_traits::integer_limits::max)()); case json_storage_kind::json_const_reference: return cast().value().template is_integer(); case json_storage_kind::json_reference: return cast().value().template is_integer(); default: return false; } } template typename std::enable_if::value && sizeof(int64_t) < sizeof(IntegerType),bool>::type is_integer() const noexcept { switch (storage_kind()) { case json_storage_kind::short_str: case json_storage_kind::long_str: { IntegerType val; auto result = jsoncons::detail::to_integer(as_string_view().data(), as_string_view().length(), val); return result ? true : false; } case json_storage_kind::int64: return (as_integer() >= (extension_traits::integer_limits::lowest)()) && (as_integer() <= (extension_traits::integer_limits::max)()); case json_storage_kind::uint64: return as_integer() <= static_cast((extension_traits::integer_limits::max)()); case json_storage_kind::json_const_reference: return cast().value().template is_integer(); case json_storage_kind::json_reference: return cast().value().template is_integer(); default: return false; } } template typename std::enable_if::value && sizeof(IntegerType) <= sizeof(int64_t),bool>::type is_integer() const noexcept { switch (storage_kind()) { case json_storage_kind::int64: return as_integer() >= 0 && static_cast(as_integer()) <= (extension_traits::integer_limits::max)(); case json_storage_kind::uint64: return as_integer() <= (extension_traits::integer_limits::max)(); case json_storage_kind::json_const_reference: return cast().value().template is_integer(); case json_storage_kind::json_reference: return cast().value().template is_integer(); default: return false; } } template typename std::enable_if::value && sizeof(int64_t) < sizeof(IntegerType),bool>::type is_integer() const noexcept { switch (storage_kind()) { case json_storage_kind::short_str: case json_storage_kind::long_str: { IntegerType val; auto result = jsoncons::detail::to_integer(as_string_view().data(), as_string_view().length(), val); return result ? true : false; } case json_storage_kind::int64: return as_integer() >= 0 && static_cast(as_integer()) <= (extension_traits::integer_limits::max)(); case json_storage_kind::uint64: return as_integer() <= (extension_traits::integer_limits::max)(); case json_storage_kind::json_const_reference: return cast().value().template is_integer(); case json_storage_kind::json_reference: return cast().value().template is_integer(); default: return false; } } double as_double() const { switch (storage_kind()) { case json_storage_kind::short_str: case json_storage_kind::long_str: { const jsoncons::detail::chars_to to_double; // to_double() throws std::invalid_argument if conversion fails return to_double(as_cstring(), as_string_view().length()); } case json_storage_kind::half_float: return binary::decode_half(cast().value()); case json_storage_kind::float64: return cast().value(); case json_storage_kind::int64: return static_cast(cast().value()); case json_storage_kind::uint64: return static_cast(cast().value()); case json_storage_kind::json_const_reference: return cast().value().as_double(); case json_storage_kind::json_reference: return cast().value().as_double(); default: JSONCONS_THROW(json_runtime_error("Not a double")); } } template > std::basic_string as_string() const { return as_string(SAllocator()); } template > std::basic_string as_string(const SAllocator& alloc) const { using string_type2 = std::basic_string; std::error_code ec; switch (storage_kind()) { case json_storage_kind::short_str: case json_storage_kind::long_str: { return string_type2(as_string_view().data(),as_string_view().length(),alloc); } case json_storage_kind::byte_str: { value_converter converter; auto s = converter.convert(as_byte_string_view(), tag(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } return s; } case json_storage_kind::array: { string_type2 s(alloc); { basic_compact_json_encoder> encoder(s); dump(encoder); } return s; } case json_storage_kind::json_const_reference: return cast().value().as_string(alloc); case json_storage_kind::json_reference: return cast().value().as_string(alloc); default: { string_type2 s(alloc); basic_compact_json_encoder> encoder(s); dump(encoder); return s; } } } const char_type* as_cstring() const { switch (storage_kind()) { case json_storage_kind::short_str: return cast().c_str(); case json_storage_kind::long_str: return cast().c_str(); case json_storage_kind::json_const_reference: return cast().value().as_cstring(); case json_storage_kind::json_reference: return cast().value().as_cstring(); default: JSONCONS_THROW(json_runtime_error("Not a cstring")); } } basic_json& at(const string_view_type& key) { switch (storage_kind()) { case json_storage_kind::empty_object: JSONCONS_THROW(key_not_found(key.data(),key.length())); case json_storage_kind::object: { auto it = cast().value().find(key); if (it == cast().value().end()) { JSONCONS_THROW(key_not_found(key.data(),key.length())); } return (*it).value(); } case json_storage_kind::json_reference: return cast().value().at(key); default: JSONCONS_THROW(not_an_object(key.data(),key.length())); } } const basic_json& at(const string_view_type& key) const { switch (storage_kind()) { case json_storage_kind::empty_object: JSONCONS_THROW(key_not_found(key.data(),key.length())); case json_storage_kind::object: { auto it = cast().value().find(key); if (it == cast().value().end()) { JSONCONS_THROW(key_not_found(key.data(),key.length())); } return (*it).value(); } case json_storage_kind::json_const_reference: return cast().value().at(key); case json_storage_kind::json_reference: return cast().value().at(key); default: JSONCONS_THROW(not_an_object(key.data(),key.length())); } } basic_json& at(std::size_t i) { switch (storage_kind()) { case json_storage_kind::array: if (i >= cast().value().size()) { JSONCONS_THROW(json_runtime_error("Invalid array subscript")); } return cast().value().operator[](i); case json_storage_kind::object: return cast().value().at(i); case json_storage_kind::json_reference: return cast().value().at(i); default: JSONCONS_THROW(json_runtime_error("Index on non-array value not supported")); } } const basic_json& at(std::size_t i) const { switch (storage_kind()) { case json_storage_kind::array: if (i >= cast().value().size()) { JSONCONS_THROW(json_runtime_error("Invalid array subscript")); } return cast().value().operator[](i); case json_storage_kind::object: return cast().value().at(i); case json_storage_kind::json_const_reference: return cast().value().at(i); case json_storage_kind::json_reference: return cast().value().at(i); default: JSONCONS_THROW(json_runtime_error("Index on non-array value not supported")); } } object_iterator find(const string_view_type& key) { switch (storage_kind()) { case json_storage_kind::empty_object: return object_range().end(); case json_storage_kind::object: return object_iterator(cast().value().find(key)); case json_storage_kind::json_reference: return cast().value().find(key); default: JSONCONS_THROW(not_an_object(key.data(),key.length())); } } const_object_iterator find(const string_view_type& key) const { switch (storage_kind()) { case json_storage_kind::empty_object: return object_range().end(); case json_storage_kind::object: return const_object_iterator(cast().value().find(key)); case json_storage_kind::json_const_reference: return cast().value().find(key); case json_storage_kind::json_reference: return cast().value().find(key); default: JSONCONS_THROW(not_an_object(key.data(),key.length())); } } const basic_json& at_or_null(const string_view_type& key) const { switch (storage_kind()) { case json_storage_kind::null: case json_storage_kind::empty_object: { return null(); } case json_storage_kind::object: { auto it = cast().value().find(key); if (it != cast().value().end()) { return (*it).value(); } else { return null(); } } case json_storage_kind::json_const_reference: return cast().value().at_or_null(key); case json_storage_kind::json_reference: return cast().value().at_or_null(key); default: JSONCONS_THROW(not_an_object(key.data(),key.length())); } } template T get_value_or(const string_view_type& key, U&& default_value) const { static_assert(std::is_copy_constructible::value, "get_value_or: T must be copy constructible"); static_assert(std::is_convertible::value, "get_value_or: U must be convertible to T"); switch (storage_kind()) { case json_storage_kind::null: case json_storage_kind::empty_object: return static_cast(std::forward(default_value)); case json_storage_kind::object: { auto it = cast().value().find(key); if (it != cast().value().end()) { return (*it).value().template as(); } else { return static_cast(std::forward(default_value)); } } case json_storage_kind::json_const_reference: return cast().value().template get_value_or(key,std::forward(default_value)); case json_storage_kind::json_reference: return cast().value().template get_value_or(key,std::forward(default_value)); default: JSONCONS_THROW(not_an_object(key.data(),key.length())); } } // Modifiers void shrink_to_fit() { switch (storage_kind()) { case json_storage_kind::array: cast().value().shrink_to_fit(); break; case json_storage_kind::object: cast().value().shrink_to_fit(); break; case json_storage_kind::json_reference: cast().value().shrink_to_fit(); break; default: break; } } void clear() { switch (storage_kind()) { case json_storage_kind::array: cast().value().clear(); break; case json_storage_kind::object: cast().value().clear(); break; case json_storage_kind::json_reference: cast().value().clear(); break; default: break; } } object_iterator erase(const_object_iterator pos) { switch (storage_kind()) { case json_storage_kind::empty_object: return object_range().end(); case json_storage_kind::object: return object_iterator(cast().value().erase(pos)); case json_storage_kind::json_reference: return cast().value().erase(pos); default: JSONCONS_THROW(json_runtime_error("Not an object")); } } object_iterator erase(const_object_iterator first, const_object_iterator last) { switch (storage_kind()) { case json_storage_kind::empty_object: return object_range().end(); case json_storage_kind::object: return object_iterator(cast().value().erase(first, last)); case json_storage_kind::json_reference: return cast().value().erase(first, last); default: JSONCONS_THROW(json_runtime_error("Not an object")); } } array_iterator erase(const_array_iterator pos) { switch (storage_kind()) { case json_storage_kind::array: return cast().value().erase(pos); case json_storage_kind::json_reference: return cast().value().erase(pos); default: JSONCONS_THROW(json_runtime_error("Not an array")); } } array_iterator erase(const_array_iterator first, const_array_iterator last) { switch (storage_kind()) { case json_storage_kind::array: return cast().value().erase(first, last); case json_storage_kind::json_reference: return cast().value().erase(first, last); default: JSONCONS_THROW(json_runtime_error("Not an array")); } } // Removes all elements from an array value whose index is between from_index, inclusive, and to_index, exclusive. void erase(const string_view_type& key) { switch (storage_kind()) { case json_storage_kind::empty_object: break; case json_storage_kind::object: cast().value().erase(key); break; case json_storage_kind::json_reference: return cast().value().erase(key); default: JSONCONS_THROW(not_an_object(key.data(),key.length())); } } template std::pair insert_or_assign(const string_view_type& key, T&& val) { switch (storage_kind()) { case json_storage_kind::empty_object: { create_object_implicitly(); auto result = cast().value().insert_or_assign(key, std::forward(val)); return std::make_pair(object_iterator(result.first), result.second); } case json_storage_kind::object: { auto result = cast().value().insert_or_assign(key, std::forward(val)); return std::make_pair(object_iterator(result.first), result.second); } case json_storage_kind::json_reference: return cast().value().insert_or_assign(key, std::forward(val)); default: JSONCONS_THROW(not_an_object(key.data(),key.length())); } } template std::pair try_emplace(const string_view_type& key, Args&&... args) { switch (storage_kind()) { case json_storage_kind::empty_object: { create_object_implicitly(); auto result = cast().value().try_emplace(key, std::forward(args)...); return std::make_pair(object_iterator(result.first),result.second); } case json_storage_kind::object: { auto result = cast().value().try_emplace(key, std::forward(args)...); return std::make_pair(object_iterator(result.first),result.second); } case json_storage_kind::json_reference: return cast().value().try_emplace(key, std::forward(args)...); default: JSONCONS_THROW(not_an_object(key.data(),key.length())); } } // merge void merge(const basic_json& source) { switch (source.storage_kind()) { case json_storage_kind::empty_object: break; case json_storage_kind::object: switch (storage_kind()) { case json_storage_kind::empty_object: create_object_implicitly(); cast().value().merge(source.cast().value()); break; case json_storage_kind::object: cast().value().merge(source.cast().value()); break; case json_storage_kind::json_reference: cast().value().merge(source); break; default: JSONCONS_THROW(json_runtime_error("Attempting to merge a value that is not an object")); } break; case json_storage_kind::json_reference: merge(source.cast().value()); break; default: JSONCONS_THROW(json_runtime_error("Attempting to merge a value that is not an object")); } } void merge(basic_json&& source) { switch (source.storage_kind()) { case json_storage_kind::empty_object: break; case json_storage_kind::object: switch (storage_kind()) { case json_storage_kind::empty_object: create_object_implicitly(); cast().value().merge(std::move(source.cast().value())); break; case json_storage_kind::object: cast().value().merge(std::move(source.cast().value())); break; case json_storage_kind::json_reference: cast().value().merge(std::move(source)); break; default: JSONCONS_THROW(json_runtime_error("Attempting to merge a value that is not an object")); } break; case json_storage_kind::json_reference: merge(std::move(source.cast().value())); break; default: JSONCONS_THROW(json_runtime_error("Attempting to merge a value that is not an object")); } } void merge(object_iterator hint, const basic_json& source) { switch (source.storage_kind()) { case json_storage_kind::empty_object: break; case json_storage_kind::object: switch (storage_kind()) { case json_storage_kind::empty_object: create_object_implicitly(); cast().value().merge(hint, source.cast().value()); break; case json_storage_kind::object: cast().value().merge(hint, source.cast().value()); break; case json_storage_kind::json_reference: cast().value().merge(hint, source); break; default: JSONCONS_THROW(json_runtime_error("Attempting to merge a value that is not an object")); } break; case json_storage_kind::json_reference: merge(hint, source.cast().value()); break; default: JSONCONS_THROW(json_runtime_error("Attempting to merge a value that is not an object")); } } void merge(object_iterator hint, basic_json&& source) { switch (source.storage_kind()) { case json_storage_kind::empty_object: break; case json_storage_kind::object: switch (storage_kind()) { case json_storage_kind::empty_object: create_object_implicitly(); cast().value().merge(hint, std::move(source.cast().value())); break; case json_storage_kind::object: cast().value().merge(hint, std::move(source.cast().value())); break; case json_storage_kind::json_reference: cast().value().merge(hint, std::move(source)); break; default: JSONCONS_THROW(json_runtime_error("Attempting to merge a value that is not an object")); } break; case json_storage_kind::json_reference: merge(hint, std::move(source.cast().value())); break; default: JSONCONS_THROW(json_runtime_error("Attempting to merge a value that is not an object")); } } // merge_or_update void merge_or_update(const basic_json& source) { switch (source.storage_kind()) { case json_storage_kind::empty_object: break; case json_storage_kind::object: switch (storage_kind()) { case json_storage_kind::empty_object: create_object_implicitly(); cast().value().merge_or_update(source.cast().value()); break; case json_storage_kind::object: cast().value().merge_or_update(source.cast().value()); break; case json_storage_kind::json_reference: cast().value().merge_or_update(source); break; default: JSONCONS_THROW(json_runtime_error("Attempting to merge or update a value that is not an object")); } break; case json_storage_kind::json_reference: merge_or_update(source.cast().value()); break; default: JSONCONS_THROW(json_runtime_error("Attempting to merge a value that is not an object")); } } void merge_or_update(basic_json&& source) { switch (source.storage_kind()) { case json_storage_kind::empty_object: break; case json_storage_kind::object: switch (storage_kind()) { case json_storage_kind::empty_object: create_object_implicitly(); cast().value().merge_or_update(std::move(source.cast().value())); break; case json_storage_kind::object: cast().value().merge_or_update(std::move(source.cast().value())); break; case json_storage_kind::json_reference: cast().value().merge_or_update(std::move(source)); break; default: JSONCONS_THROW(json_runtime_error("Attempting to merge or update a value that is not an object")); } break; case json_storage_kind::json_reference: merge_or_update(std::move(source.cast().value())); break; default: JSONCONS_THROW(json_runtime_error("Attempting to merge a value that is not an object")); } } void merge_or_update(object_iterator hint, const basic_json& source) { switch (source.storage_kind()) { case json_storage_kind::empty_object: break; case json_storage_kind::object: switch (storage_kind()) { case json_storage_kind::empty_object: create_object_implicitly(); cast().value().merge_or_update(hint, source.cast().value()); break; case json_storage_kind::object: cast().value().merge_or_update(hint, source.cast().value()); break; case json_storage_kind::json_reference: cast().value().merge_or_update(hint, source); break; default: JSONCONS_THROW(json_runtime_error("Attempting to merge or update a value that is not an object")); } break; case json_storage_kind::json_reference: merge_or_update(hint, source.cast().value()); break; default: JSONCONS_THROW(json_runtime_error("Attempting to merge a value that is not an object")); } } void merge_or_update(object_iterator hint, basic_json&& source) { switch (source.storage_kind()) { case json_storage_kind::empty_object: break; case json_storage_kind::object: switch (storage_kind()) { case json_storage_kind::empty_object: create_object_implicitly(); cast().value().merge_or_update(hint, std::move(source.cast().value())); break; case json_storage_kind::object: cast().value().merge_or_update(hint, std::move(source.cast().value())); break; case json_storage_kind::json_reference: cast().value().merge_or_update(hint, std::move(source)); break; default: JSONCONS_THROW(json_runtime_error("Attempting to merge or update a value that is not an object")); } break; case json_storage_kind::json_reference: merge_or_update(hint, std::move(source.cast().value())); break; default: JSONCONS_THROW(json_runtime_error("Attempting to merge a value that is not an object")); } } template object_iterator insert_or_assign(object_iterator hint, const string_view_type& name, T&& val) { switch (storage_kind()) { case json_storage_kind::empty_object: create_object_implicitly(); return object_iterator(cast().value().insert_or_assign(hint, name, std::forward(val))); case json_storage_kind::object: return object_iterator(cast().value().insert_or_assign(hint, name, std::forward(val))); case json_storage_kind::json_reference: return object_iterator(cast().value().insert_or_assign(hint, name, std::forward(val))); default: JSONCONS_THROW(not_an_object(name.data(),name.length())); } } template object_iterator try_emplace(object_iterator hint, const string_view_type& name, Args&&... args) { switch (storage_kind()) { case json_storage_kind::empty_object: create_object_implicitly(); return object_iterator(cast().value().try_emplace(hint, name, std::forward(args)...)); case json_storage_kind::object: return object_iterator(cast().value().try_emplace(hint, name, std::forward(args)...)); case json_storage_kind::json_reference: return object_iterator(cast().value().try_emplace(hint, name, std::forward(args)...)); default: JSONCONS_THROW(not_an_object(name.data(),name.length())); } } template array_iterator insert(const_array_iterator pos, T&& val) { switch (storage_kind()) { case json_storage_kind::array: return cast().value().insert(pos, std::forward(val)); break; case json_storage_kind::json_reference: return cast().value().insert(pos, std::forward(val)); break; default: JSONCONS_THROW(json_runtime_error("Attempting to insert into a value that is not an array")); } } template array_iterator insert(const_array_iterator pos, InputIt first, InputIt last) { switch (storage_kind()) { case json_storage_kind::array: return cast().value().insert(pos, first, last); break; case json_storage_kind::json_reference: return cast().value().insert(pos, first, last); break; default: JSONCONS_THROW(json_runtime_error("Attempting to insert into a value that is not an array")); } } template void insert(InputIt first, InputIt last) { switch (storage_kind()) { case json_storage_kind::empty_object: create_object_implicitly(); cast().value().insert(first, last); break; case json_storage_kind::object: cast().value().insert(first, last); break; case json_storage_kind::json_reference: cast().value().insert(first, last); break; default: JSONCONS_THROW(json_runtime_error("Attempting to insert into a value that is not an object")); } } template void insert(sorted_unique_range_tag tag, InputIt first, InputIt last) { switch (storage_kind()) { case json_storage_kind::empty_object: create_object_implicitly(); cast().value().insert(tag, first, last); break; case json_storage_kind::object: cast().value().insert(tag, first, last); break; case json_storage_kind::json_reference: cast().value().insert(tag, first, last); break; default: JSONCONS_THROW(json_runtime_error("Attempting to insert into a value that is not an object")); } } template array_iterator emplace(const_array_iterator pos, Args&&... args) { switch (storage_kind()) { case json_storage_kind::array: return cast().value().emplace(pos, std::forward(args)...); break; case json_storage_kind::json_reference: return cast().value().emplace(pos, std::forward(args)...); default: JSONCONS_THROW(json_runtime_error("Attempting to insert into a value that is not an array")); } } template basic_json& emplace_back(Args&&... args) { switch (storage_kind()) { case json_storage_kind::array: return cast().value().emplace_back(std::forward(args)...); case json_storage_kind::json_reference: return cast().value().emplace_back(std::forward(args)...); default: JSONCONS_THROW(json_runtime_error("Attempting to insert into a value that is not an array")); } } friend void swap(basic_json& a, basic_json& b) noexcept { a.swap(b); } template void push_back(T&& val) { switch (storage_kind()) { case json_storage_kind::array: cast().value().push_back(std::forward(val)); break; case json_storage_kind::json_reference: cast().value().push_back(std::forward(val)); break; default: JSONCONS_THROW(json_runtime_error("Attempting to insert into a value that is not an array")); } } void push_back(basic_json&& val) { switch (storage_kind()) { case json_storage_kind::array: cast().value().push_back(std::move(val)); break; case json_storage_kind::json_reference: cast().value().push_back(std::move(val)); break; default: JSONCONS_THROW(json_runtime_error("Attempting to insert into a value that is not an array")); } } std::basic_string to_string() const noexcept { using string_type2 = std::basic_string; string_type2 s; basic_compact_json_encoder> encoder(s); dump(encoder); return s; } template basic_json(InputIterator first, InputIterator last, const Allocator& alloc = Allocator()) : basic_json(json_array_arg,first,last,alloc) { } object_range_type object_range() { switch (storage_kind()) { case json_storage_kind::empty_object: return object_range_type(object_iterator(), object_iterator()); case json_storage_kind::object: return object_range_type(object_iterator(cast().value().begin()), object_iterator(cast().value().end())); case json_storage_kind::json_reference: return cast().value().object_range(); default: JSONCONS_THROW(json_runtime_error("Not an object")); } } const_object_range_type object_range() const { switch (storage_kind()) { case json_storage_kind::empty_object: return const_object_range_type(const_object_iterator(), const_object_iterator()); case json_storage_kind::object: return const_object_range_type(const_object_iterator(cast().value().begin()), const_object_iterator(cast().value().end())); case json_storage_kind::json_const_reference: return cast().value().object_range(); case json_storage_kind::json_reference: return cast().value().object_range(); default: JSONCONS_THROW(json_runtime_error("Not an object")); } } array_range_type array_range() { switch (storage_kind()) { case json_storage_kind::array: return array_range_type(cast().value().begin(), cast().value().end()); case json_storage_kind::json_reference: return cast().value().array_range(); default: JSONCONS_THROW(json_runtime_error("Not an array")); } } const_array_range_type array_range() const { switch (storage_kind()) { case json_storage_kind::array: return const_array_range_type(cast().value().begin(), cast().value().end()); case json_storage_kind::json_const_reference: return cast().value().array_range(); case json_storage_kind::json_reference: return cast().value().array_range(); default: JSONCONS_THROW(json_runtime_error("Not an array")); } } private: void dump_noflush(basic_json_visitor& visitor, std::error_code& ec) const { const ser_context context{}; switch (storage_kind()) { case json_storage_kind::short_str: case json_storage_kind::long_str: visitor.string_value(as_string_view(), tag(), context, ec); break; case json_storage_kind::byte_str: if (tag() == semantic_tag::ext) { visitor.byte_string_value(as_byte_string_view(), ext_tag(), context, ec); } else { visitor.byte_string_value(as_byte_string_view(), tag(), context, ec); } break; case json_storage_kind::half_float: visitor.half_value(cast().value(), tag(), context, ec); break; case json_storage_kind::float64: visitor.double_value(cast().value(), tag(), context, ec); break; case json_storage_kind::int64: visitor.int64_value(cast().value(), tag(), context, ec); break; case json_storage_kind::uint64: visitor.uint64_value(cast().value(), tag(), context, ec); break; case json_storage_kind::boolean: visitor.bool_value(cast().value(), tag(), context, ec); break; case json_storage_kind::null: visitor.null_value(tag(), context, ec); break; case json_storage_kind::empty_object: visitor.begin_object(0, tag(), context, ec); visitor.end_object(context, ec); break; case json_storage_kind::object: { visitor.begin_object(size(), tag(), context, ec); const object& o = cast().value(); for (auto it = o.begin(); it != o.end(); ++it) { visitor.key(string_view_type(((*it).key()).data(),(*it).key().length()), context, ec); (*it).value().dump_noflush(visitor, ec); } visitor.end_object(context, ec); break; } case json_storage_kind::array: { visitor.begin_array(size(), tag(), context, ec); const array& o = cast().value(); for (const_array_iterator it = o.begin(); it != o.end(); ++it) { (*it).dump_noflush(visitor, ec); } visitor.end_array(context, ec); break; } case json_storage_kind::json_const_reference: return cast().value().dump_noflush(visitor, ec); case json_storage_kind::json_reference: return cast().value().dump_noflush(visitor, ec); default: break; } } friend std::basic_ostream& operator<<(std::basic_ostream& os, const basic_json& o) { o.dump(os); return os; } friend std::basic_istream& operator>>(std::basic_istream& is, basic_json& o) { json_decoder visitor; basic_json_reader> reader(is, visitor); reader.read_next(); reader.check_done(); if (!visitor.is_valid()) { JSONCONS_THROW(json_runtime_error("Failed to parse json stream")); } o = visitor.get_result(); return is; } friend basic_json deep_copy(const basic_json& other) { switch (other.storage_kind()) { case json_storage_kind::array: { basic_json j(json_array_arg, other.tag(), other.get_allocator()); j.reserve(other.size()); for (const auto& item : other.array_range()) { j.push_back(deep_copy(item)); } return j; } case json_storage_kind::object: { basic_json j(json_object_arg, other.tag(), other.get_allocator()); j.reserve(other.size()); for (const auto& item : other.object_range()) { j.try_emplace(item.key(), deep_copy(item.value())); } return j; } case json_storage_kind::json_const_reference: return deep_copy(other.cast().value()); case json_storage_kind::json_reference: return deep_copy(other.cast().value()); default: return other; } } }; // operator== template typename std::enable_if::value,bool>::type operator==(const Json& lhs, const Json& rhs) noexcept { return lhs.compare(rhs) == 0; } template typename std::enable_if::value && std::is_convertible::value,bool>::type operator==(const Json& lhs, const T& rhs) { return lhs.compare(rhs) == 0; } template typename std::enable_if::value && std::is_convertible::value,bool>::type operator==(const T& lhs, const Json& rhs) { return rhs.compare(lhs) == 0; } // operator!= template typename std::enable_if::value,bool>::type operator!=(const Json& lhs, const Json& rhs) noexcept { return lhs.compare(rhs) != 0; } template typename std::enable_if::value && std::is_convertible::value,bool>::type operator!=(const Json& lhs, const T& rhs) { return lhs.compare(rhs) != 0; } template typename std::enable_if::value && std::is_convertible::value,bool>::type operator!=(const T& lhs, const Json& rhs) { return rhs.compare(lhs) != 0; } // operator< template typename std::enable_if::value,bool>::type operator<(const Json& lhs, const Json& rhs) noexcept { return lhs.compare(rhs) < 0; } template typename std::enable_if::value && std::is_convertible::value,bool>::type operator<(const Json& lhs, const T& rhs) { return lhs.compare(rhs) < 0; } template typename std::enable_if::value && std::is_convertible::value,bool>::type operator<(const T& lhs, const Json& rhs) { return rhs.compare(lhs) > 0; } // operator<= template typename std::enable_if::value,bool>::type operator<=(const Json& lhs, const Json& rhs) noexcept { return lhs.compare(rhs) <= 0; } template typename std::enable_if::value && std::is_convertible::value,bool>::type operator<=(const Json& lhs, const T& rhs) { return lhs.compare(rhs) <= 0; } template typename std::enable_if::value && std::is_convertible::value,bool>::type operator<=(const T& lhs, const Json& rhs) { return rhs.compare(lhs) >= 0; } // operator> template typename std::enable_if::value,bool>::type operator>(const Json& lhs, const Json& rhs) noexcept { return lhs.compare(rhs) > 0; } template typename std::enable_if::value && std::is_convertible::value,bool>::type operator>(const Json& lhs, const T& rhs) { return lhs.compare(rhs) > 0; } template typename std::enable_if::value && std::is_convertible::value,bool>::type operator>(const T& lhs, const Json& rhs) { return rhs.compare(lhs) < 0; } // operator>= template typename std::enable_if::value,bool>::type operator>=(const Json& lhs, const Json& rhs) noexcept { return lhs.compare(rhs) >= 0; } template typename std::enable_if::value && std::is_convertible::value,bool>::type operator>=(const Json& lhs, const T& rhs) { return lhs.compare(rhs) >= 0; } template typename std::enable_if::value && std::is_convertible::value,bool>::type operator>=(const T& lhs, const Json& rhs) { return rhs.compare(lhs) <= 0; } // swap template void swap(typename Json::key_value_type& a,typename Json::key_value_type& b) noexcept { a.swap(b); } using json = basic_json>; using wjson = basic_json>; using ojson = basic_json>; using wojson = basic_json>; inline namespace literals { inline jsoncons::json operator ""_json(const char* s, std::size_t n) { return jsoncons::json::parse(jsoncons::json::string_view_type(s, n)); } inline jsoncons::wjson operator ""_json(const wchar_t* s, std::size_t n) { return jsoncons::wjson::parse(jsoncons::wjson::string_view_type(s, n)); } inline jsoncons::ojson operator ""_ojson(const char* s, std::size_t n) { return jsoncons::ojson::parse(jsoncons::ojson::string_view_type(s, n)); } inline jsoncons::wojson operator ""_ojson(const wchar_t* s, std::size_t n) { return jsoncons::wojson::parse(jsoncons::wojson::string_view_type(s, n)); } } // inline namespace literals #if defined(JSONCONS_HAS_POLYMORPHIC_ALLOCATOR) namespace pmr { template< typename CharT,typename Policy> using basic_json = jsoncons::basic_json>; using json = basic_json; using wjson = basic_json; using ojson = basic_json; using wojson = basic_json; } // namespace pmr #endif } // namespace jsoncons #endif // JSONCONS_BASIC_JSON_HPP jsoncons-1.3.2/include/jsoncons/config/000077500000000000000000000000001477700171100201025ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons/config/compiler_support.hpp000066400000000000000000000357041477700171100242320ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_CONFIG_COMPILER_SUPPORT_HPP #define JSONCONS_CONFIG_COMPILER_SUPPORT_HPP #include #include #include // std::memcpy #include // std::numeric_limits #if !defined(JSONCONS_NO_EXCEPTIONS) #define JSONCONS_THROW(exception) throw exception #define JSONCONS_RETHROW throw #define JSONCONS_TRY try #define JSONCONS_CATCH(exception) catch(exception) #else #define JSONCONS_THROW(exception) std::terminate() #define JSONCONS_RETHROW std::terminate() #define JSONCONS_TRY if (true) #define JSONCONS_CATCH(exception) if (false) #endif #if defined(__GNUC__) # if defined(__GNUC_PATCHLEVEL__) # define JSONCONS_GCC_AVAILABLE(major, minor, patch) \ ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) \ >= ((major) * 10000 + (minor) * 100 + (patch))) # else # define JSONCONS_GCC_AVAILABLE(major, minor, patch) \ ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100) \ >= ((major) * 10000 + (minor) * 100 + (patch))) # endif # else # define JSONCONS_GCC_AVAILABLE(major, minor, patch) 0 #endif #if defined(__clang__) # define JSONCONS_CLANG_AVAILABLE(major, minor, patch) \ ((__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) \ >= ((major) * 10000 + (minor) * 100 + (patch))) # else # define JSONCONS_CLANG_AVAILABLE(major, minor, patch) 0 #endif // Uncomment the following line to suppress deprecated names (recommended for new code) //#define JSONCONS_NO_DEPRECATED // The definitions below follow the definitions in compiler_support_p.h, https://github.com/01org/tinycbor // MIT license // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54577 #if defined(__GNUC__) || defined(__clang__) #define JSONCONS_LIKELY(x) __builtin_expect(!!(x), 1) #define JSONCONS_UNLIKELY(x) __builtin_expect(!!(x), 0) #define JSONCONS_UNREACHABLE() __builtin_unreachable() #elif defined(_MSC_VER) #define JSONCONS_LIKELY(x) x #define JSONCONS_UNLIKELY(x) x #define JSONCONS_UNREACHABLE() __assume(0) #else #define JSONCONS_LIKELY(x) x #define JSONCONS_UNLIKELY(x) x #define JSONCONS_UNREACHABLE() do {} while (0) #endif // Deprecated symbols markup #if (defined(__cplusplus) && __cplusplus >= 201402L) #define JSONCONS_DEPRECATED_MSG(msg) [[deprecated(msg)]] #endif #if !defined(JSONCONS_DEPRECATED_MSG) && defined(__GNUC__) && defined(__has_extension) #if __has_extension(attribute_deprecated_with_message) #define JSONCONS_DEPRECATED_MSG(msg) __attribute__((deprecated(msg))) #endif #endif #if !defined(JSONCONS_DEPRECATED_MSG) && defined(_MSC_VER) #if (_MSC_VER) >= 1920 #define JSONCONS_DEPRECATED_MSG(msg) [[deprecated(msg)]] #else #define JSONCONS_DEPRECATED_MSG(msg) __declspec(deprecated(msg)) #endif #endif // Following boost/atomic/detail/config.hpp #if !defined(JSONCONS_DEPRECATED_MSG) && (\ (defined(__GNUC__) && ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0)) >= 405) ||\ (defined(__SUNPRO_CC) && (__SUNPRO_CC + 0) >= 0x5130)) #define JSONCONS_DEPRECATED_MSG(msg) __attribute__((deprecated(msg))) #endif #if !defined(JSONCONS_DEPRECATED_MSG) && defined(__clang__) && defined(__has_extension) #if __has_extension(attribute_deprecated_with_message) #define JSONCONS_DEPRECATED_MSG(msg) __attribute__((deprecated(msg))) #else #define JSONCONS_DEPRECATED_MSG(msg) __attribute__((deprecated)) #endif #endif #if !defined(JSONCONS_DEPRECATED_MSG) #define JSONCONS_DEPRECATED_MSG(msg) #endif #if defined(ANDROID) || defined(__ANDROID__) #if __ANDROID_API__ >= 21 #define JSONCONS_HAS_STRTOLD_L #else #define JSONCONS_NO_LOCALECONV #endif #endif #if defined(_MSC_VER) #define JSONCONS_HAS_MSC_STRTOD_L #define JSONCONS_HAS_FOPEN_S #endif #ifndef JSONCONS_HAS_CP14 #if defined(_MSVC_LANG) #if _MSVC_LANG >= 201402L #define JSONCONS_HAS_CP14 #endif #elif __cplusplus >= 201402L #define JSONCONS_HAS_CP14 #endif #endif #if defined(JSONCONS_HAS_STD_FROM_CHARS) && JSONCONS_HAS_STD_FROM_CHARS #include #endif #if !defined(JSONCONS_HAS_2017) # if defined(__clang__) # if (__cplusplus >= 201703) # define JSONCONS_HAS_2017 1 # endif // (__cplusplus >= 201703) # endif // defined(__clang__) # if defined(__GNUC__) # if (__GNUC__ >= 7) # if (__cplusplus >= 201703) # define JSONCONS_HAS_2017 1 # endif // (__cplusplus >= 201703) # endif // (__GNUC__ >= 7) # endif // defined(__GNUC__) # if defined(_MSC_VER) # if (_MSC_VER >= 1910 && _MSVC_LANG >= 201703) # define JSONCONS_HAS_2017 1 # endif // (_MSC_VER >= 1910 && MSVC_LANG >= 201703) # endif // defined(_MSC_VER) #endif #if defined(JSONCONS_HAS_2017) #define JSONCONS_NODISCARD [[nodiscard]] #define JSONCONS_IF_CONSTEXPR if constexpr #else #define JSONCONS_NODISCARD #define JSONCONS_IF_CONSTEXPR if #endif #if !defined(JSONCONS_HAS_POLYMORPHIC_ALLOCATOR) #if defined(JSONCONS_HAS_2017) # if __has_include() # define JSONCONS_HAS_POLYMORPHIC_ALLOCATOR 1 # endif // __has_include() #endif #endif #if !defined(JSONCONS_HAS_STD_STRING_VIEW) # if (defined JSONCONS_HAS_2017) # if defined(__clang__) # if __has_include() # define JSONCONS_HAS_STD_STRING_VIEW 1 # endif // __has_include() # else # define JSONCONS_HAS_STD_STRING_VIEW 1 # endif # endif // defined(JSONCONS_HAS_2017) #endif // !defined(JSONCONS_HAS_STD_STRING_VIEW) #if !defined(JSONCONS_HAS_STD_BYTE) # if (defined JSONCONS_HAS_2017) # define JSONCONS_HAS_STD_BYTE 1 # endif // defined(JSONCONS_HAS_2017) #endif // !defined(JSONCONS_HAS_STD_BYTE) #if !defined(JSONCONS_HAS_STD_OPTIONAL) # if (defined JSONCONS_HAS_2017) # if defined(__clang__) # if __has_include() # define JSONCONS_HAS_STD_OPTIONAL 1 # endif // __has_include() # else # define JSONCONS_HAS_STD_OPTIONAL 1 # endif # endif // defined(JSONCONS_HAS_2017) #endif // !defined(JSONCONS_HAS_STD_OPTIONAL) #if !defined(JSONCONS_HAS_STD_VARIANT) # if (defined JSONCONS_HAS_2017) # if defined(__clang__) # if defined(__APPLE__) # if JSONCONS_CLANG_AVAILABLE(10,0,1) # define JSONCONS_HAS_STD_VARIANT 1 # endif # elif __has_include() # define JSONCONS_HAS_STD_VARIANT 1 # endif // __has_include() # else # define JSONCONS_HAS_STD_VARIANT 1 # endif # endif // defined(JSONCONS_HAS_2017) #endif // !defined(JSONCONS_HAS_STD_VARIANT) #if !defined(JSONCONS_HAS_FILESYSTEM) # if (defined JSONCONS_HAS_2017) # if defined(__clang__) # if __has_include() # define JSONCONS_HAS_FILESYSTEM 1 # endif // __has_include() # else # define JSONCONS_HAS_FILESYSTEM 1 # endif # endif // defined(JSONCONS_HAS_2017) #endif // !defined(JSONCONS_HAS_FILESYSTEM) #if (!defined(JSONCONS_NO_EXCEPTIONS)) // Check if exceptions are disabled. # if defined( __cpp_exceptions) && __cpp_exceptions == 0 # define JSONCONS_NO_EXCEPTIONS 1 # endif #endif #if !defined(JSONCONS_NO_EXCEPTIONS) #if defined(__GNUC__) && !defined(__EXCEPTIONS) # define JSONCONS_NO_EXCEPTIONS 1 #elif defined(_MSC_VER) #if defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0 # define JSONCONS_NO_EXCEPTIONS 1 #elif !defined(_CPPUNWIND) # define JSONCONS_NO_EXCEPTIONS 1 #endif #endif #endif #if !defined(JSONCONS_HAS_STD_MAKE_UNIQUE) #if defined(__clang__) && defined(__cplusplus) #if defined(__APPLE__) #if __clang_major__ >= 6 && __cplusplus >= 201402L // Xcode 6 #define JSONCONS_HAS_STD_MAKE_UNIQUE #endif #elif ((__clang_major__*100 +__clang_minor__) >= 340) && __cplusplus >= 201402L #define JSONCONS_HAS_STD_MAKE_UNIQUE #endif #elif defined(__GNUC__) #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409 && __cplusplus > 201103L #define JSONCONS_HAS_STD_MAKE_UNIQUE #endif #elif defined(_MSC_VER) #if _MSC_VER >= 1800 #define JSONCONS_HAS_STD_MAKE_UNIQUE #endif #endif #endif // !defined(JSONCONS_HAS_STD_MAKE_UNIQUE) #ifndef JSONCONS_HAS_CP14_CONSTEXPR #if defined(_MSC_VER) #if _MSC_VER >= 1910 #define JSONCONS_HAS_CP14_CONSTEXPR #endif #elif defined(__GNUC__) #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 600 && __cplusplus >= 201402L #define JSONCONS_HAS_CP14_CONSTEXPR #endif #endif #endif #if defined(JSONCONS_HAS_CP14_CONSTEXPR) # define JSONCONS_CPP14_CONSTEXPR constexpr #else # define JSONCONS_CPP14_CONSTEXPR #endif // Follows boost // gcc and clang #if !defined(__CUDA_ARCH__) #if (defined(__clang__) || defined(__GNUC__)) && defined(__cplusplus) #if defined(__SIZEOF_INT128__) && !defined(_MSC_VER) # define JSONCONS_HAS_INT128 #endif #if (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC) #if (__clang_major__ >= 4) && defined(__has_include) #if __has_include() # define JSONCONS_HAS_FLOAT128 #endif #endif #endif #endif #if defined(__GNUC__) #if defined(_GLIBCXX_USE_FLOAT128) # define JSONCONS_HAS_FLOAT128 #endif #endif #if defined(__clang__) #if (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC) #if (__clang_major__ >= 4) && defined(__has_include) #if __has_include() # define JSONCONS_HAS_FLOAT128 #endif #endif #endif #endif #endif // __CUDA_ARCH__ #ifndef JSONCONS_FORCE_INLINE # ifdef _MSC_VER # define JSONCONS_FORCE_INLINE __forceinline # elif defined(__GNUC__) || defined(__clang__) # define JSONCONS_FORCE_INLINE inline __attribute__((always_inline)) # else # define JSONCONS_FORCE_INLINE inline # endif #endif // JSONCONS_FORCE_INLINE // Follows boost config/detail/suffix.hpp #if defined(JSONCONS_HAS_INT128) && defined(__cplusplus) namespace jsoncons{ # ifdef __GNUC__ __extension__ typedef __int128 int128_type; __extension__ typedef unsigned __int128 uint128_type; # else typedef __int128 int128_type; typedef unsigned __int128 uint128_type; # endif } #endif #if defined(JSONCONS_HAS_FLOAT128) && defined(__cplusplus) namespace jsoncons { # ifdef __GNUC__ __extension__ typedef __float128 float128_type; # else typedef __float128 float128_type; # endif } #endif #if defined(_MSC_VER) && _MSC_VER <= 1900 #define JSONCONS_COPY(first,last,d_first) std::copy(first, last, stdext::make_checked_array_iterator(d_first, static_cast(std::distance(first, last)))) #else #define JSONCONS_COPY(first,last,d_first) std::copy(first, last, d_first) #endif #if defined(JSONCONS_HAS_CP14) #define JSONCONS_CONSTEXPR constexpr #else #define JSONCONS_CONSTEXPR #endif #if !defined(JSONCONS_HAS_STD_REGEX) #if defined(__clang__) #define JSONCONS_HAS_STD_REGEX 1 #elif (defined(__GNUC__) && (__GNUC__ == 4)) && (defined(__GNUC__) && __GNUC_MINOR__ < 9) // GCC 4.8 has broken regex support: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53631 #else #define JSONCONS_HAS_STD_REGEX 1 #endif #endif #if !defined(JSONCONS_HAS_STATEFUL_ALLOCATOR) #if defined(__clang__) && !JSONCONS_CLANG_AVAILABLE(11,0,0) #elif defined(__GNUC__) && !JSONCONS_GCC_AVAILABLE(10,0,0) #else #define JSONCONS_HAS_STATEFUL_ALLOCATOR 1 #endif #endif // The definitions below follow the definitions in compiler_support_p.h, https://github.com/01org/tinycbor // MIT license #ifdef __F16C__ # include #endif #ifndef __has_builtin # define __has_builtin(x) 0 #endif #if defined(__GNUC__) #if (__GNUC__ * 100 + __GNUC_MINOR__ >= 403) || (__has_builtin(__builtin_bswap64) && __has_builtin(__builtin_bswap32)) # define JSONCONS_BYTE_SWAP_64 __builtin_bswap64 # define JSONCONS_BYTE_SWAP_32 __builtin_bswap32 # ifdef __INTEL_COMPILER # define JSONCONS_BYTE_SWAP_16 _bswap16 # elif (__GNUC__ * 100 + __GNUC_MINOR__ >= 608) || __has_builtin(__builtin_bswap16) # define JSONCONS_BYTE_SWAP_16 __builtin_bswap16 # endif #endif #elif defined(__sun) # include #elif defined(_MSC_VER) // MSVC, which implies sizeof(long) == 4 # define JSONCONS_BYTE_SWAP_64 _byteswap_uint64 # define JSONCONS_BYTE_SWAP_32 _byteswap_ulong # define JSONCONS_BYTE_SWAP_16 _byteswap_ushort #endif namespace jsoncons { namespace binary { static inline bool add_check_overflow(std::size_t v1, std::size_t v2, std::size_t *r) { #if ((defined(__GNUC__) && (__GNUC__ >= 5)) && !defined(__INTEL_COMPILER)) || __has_builtin(__builtin_add_overflow) return __builtin_add_overflow(v1, v2, r); #else // unsigned additions are well-defined *r = v1 + v2; return v1 > v1 + v2; #endif } #if defined(__apple_build_version__) && ((__clang_major__ < 8) || ((__clang_major__ == 8) && (__clang_minor__ < 1))) #define APPLE_MISSING_INTRINSICS 1 #endif inline uint16_t encode_half(double val) { #if defined(__F16C__) && !defined(APPLE_MISSING_INTRINSICS) return _cvtss_sh((float)val, 3); #else uint64_t v; std::memcpy(&v, &val, sizeof(v)); int64_t sign = static_cast(v >> 63 << 15); int64_t exp = (v >> 52) & 0x7ff; int64_t mant = v << 12 >> 12 >> (53-11); /* keep only the 11 most significant bits of the mantissa */ exp -= 1023; if (exp == 1024) { /* infinity or NaN */ exp = 16; mant >>= 1; } else if (exp >= 16) { /* overflow, as largest number */ exp = 15; mant = 1023; } else if (exp >= -14) { /* regular normal */ } else if (exp >= -24) { /* subnormal */ mant |= 1024; mant >>= -(exp + 14); exp = -15; } else { /* underflow, make zero */ return 0; } /* safe cast here as bit operations above guarantee not to overflow */ return static_cast(sign | ((exp + 15) << 10) | mant); #endif } /* this function was copied & adapted from RFC 7049 Appendix D */ inline double decode_half(uint16_t half) { #if defined(__F16C__) && !defined(APPLE_MISSING_INTRINSICS) return _cvtsh_ss(half); #else int64_t exp = (half >> 10) & 0x1f; int64_t mant = half & 0x3ff; double val; if (exp == 0) { val = ldexp(static_cast(mant), -24); } else if (exp != 31) { val = ldexp(static_cast(mant) + 1024.0, static_cast(exp - 25)); } else { val = mant == 0 ? std::numeric_limits::infinity() : std::nan(""); } return half & 0x8000 ? -val : val; #endif } } // namespace binary } // namespace jsoncons // allow to disable exceptions #endif // JSONCONS_CONFIG_COMPILER_SUPPORT_HPP jsoncons-1.3.2/include/jsoncons/config/jsoncons_config.hpp000066400000000000000000000142541477700171100240020ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_CONFIG_JSONCONS_CONFIG_HPP #define JSONCONS_CONFIG_JSONCONS_CONFIG_HPP #include #include #include #include #include #include #include #include namespace jsoncons { class assertion_error : public std::runtime_error { public: assertion_error(const std::string& s) noexcept : std::runtime_error(s) { } const char* what() const noexcept override { return std::runtime_error::what(); } }; } // namespace jsoncons #define JSONCONS_STR2(x) #x #define JSONCONS_STR(x) JSONCONS_STR2(x) #ifdef _DEBUG #define JSONCONS_ASSERT(x) if (!(x)) { \ JSONCONS_THROW(jsoncons::assertion_error("assertion '" #x "' failed at " __FILE__ ":" \ JSONCONS_STR(__LINE__))); } #else #define JSONCONS_ASSERT(x) if (!(x)) { \ JSONCONS_THROW(jsoncons::assertion_error("assertion '" #x "' failed at <> :" \ JSONCONS_STR( 0 ))); } #endif // _DEBUG #if defined(JSONCONS_HAS_2017) # define JSONCONS_FALLTHROUGH [[fallthrough]] #elif defined(__clang__) # define JSONCONS_FALLTHROUGH [[clang::fallthrough]] #elif defined(__GNUC__) && ((__GNUC__ >= 7)) # define JSONCONS_FALLTHROUGH __attribute__((fallthrough)) #elif defined (__GNUC__) # define JSONCONS_FALLTHROUGH // FALLTHRU #else # define JSONCONS_FALLTHROUGH #endif #if !defined(JSONCONS_HAS_STD_STRING_VIEW) #include namespace jsoncons { using jsoncons::detail::basic_string_view; using string_view = jsoncons::detail::string_view; using wstring_view = jsoncons::detail::wstring_view; } #else #include namespace jsoncons { using std::basic_string_view; using std::string_view; using std::wstring_view; } #endif #if !defined(JSONCONS_HAS_STD_SPAN) #include namespace jsoncons { using jsoncons::detail::span; } #else #include namespace jsoncons { using std::span; } #endif #if defined(JSONCONS_HAS_STD_OPTIONAL) #include namespace jsoncons { using std::optional; } #elif defined(JSONCONS_HAS_BOOST_OPTIONAL) #include namespace jsoncons { using boost::optional; } #else #include namespace jsoncons { using jsoncons::detail::optional; } #endif // !defined(JSONCONS_HAS_STD_OPTIONAL) #if !defined(JSONCONS_HAS_STD_ENDIAN) #include namespace jsoncons { using jsoncons::detail::endian; } #else #include namespace jsoncons { using std::endian; } #endif #if !defined(JSONCONS_HAS_STD_MAKE_UNIQUE) #include #include #include #include namespace jsoncons { template struct unique_if { using value_is_not_array = std::unique_ptr; }; template struct unique_if { typedef std::unique_ptr value_is_array_of_unknown_bound; }; template struct unique_if { using value_is_array_of_known_bound = void; }; template typename unique_if::value_is_not_array make_unique(Args&&... args) { return std::unique_ptr(new T(std::forward(args)...)); } template typename unique_if::value_is_array_of_unknown_bound make_unique(std::size_t n) { using U = typename std::remove_extent::type; return std::unique_ptr(new U[n]()); } template typename unique_if::value_is_array_of_known_bound make_unique(Args&&...) = delete; } // namespace jsoncons #else #include namespace jsoncons { using std::make_unique; } #endif // !defined(JSONCONS_HAS_STD_MAKE_UNIQUE) namespace jsoncons { template constexpr const CharT* cstring_constant_of_type(const char* c, const wchar_t* w); template<> inline constexpr const char* cstring_constant_of_type(const char* c, const wchar_t*) { return c; } template<> inline constexpr const wchar_t* cstring_constant_of_type(const char*, const wchar_t* w) { return w; } template std::basic_string string_constant_of_type(const char* c, const wchar_t* w); template<> inline std::string string_constant_of_type(const char* c, const wchar_t*) { return std::string(c); } template<> inline std::wstring string_constant_of_type(const char*, const wchar_t* w) { return std::wstring(w); } template jsoncons::basic_string_view string_view_constant_of_type(const char* c, const wchar_t* w); template<> inline jsoncons::string_view string_view_constant_of_type(const char* c, const wchar_t*) { return jsoncons::string_view(c); } template<> inline jsoncons::wstring_view string_view_constant_of_type(const char*, const wchar_t* w) { return jsoncons::wstring_view(w); } } // namespace jsoncons #define JSONCONS_EXPAND(X) X #define JSONCONS_QUOTE(Prefix, A) JSONCONS_EXPAND(Prefix ## #A) #define JSONCONS_WIDEN(A) JSONCONS_EXPAND(L ## A) #define JSONCONS_CSTRING_CONSTANT(CharT, Str) cstring_constant_of_type(Str, JSONCONS_WIDEN(Str)) #define JSONCONS_STRING_CONSTANT(CharT, Str) string_constant_of_type(Str, JSONCONS_WIDEN(Str)) #define JSONCONS_STRING_VIEW_CONSTANT(CharT, Str) string_view_constant_of_type(Str, JSONCONS_WIDEN(Str)) #if defined(JSONCONS_VISITOR_VOID_RETURN) #define JSONCONS_VISITOR_RETURN_TYPE void #else #define JSONCONS_VISITOR_RETURN_TYPE bool #endif #if defined(JSONCONS_VISITOR_VOID_RETURN) #define JSONCONS_VISITOR_RETURN return #else #define JSONCONS_VISITOR_RETURN return true #endif #endif // JSONCONS_CONFIG_JSONCONS_CONFIG_HPP jsoncons-1.3.2/include/jsoncons/config/version.hpp000066400000000000000000000017451477700171100223070ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_CONFIG_VERSION_HPP #define JSONCONS_CONFIG_VERSION_HPP #include #define JSONCONS_VERSION_MAJOR 1 #define JSONCONS_VERSION_MINOR 3 #define JSONCONS_VERSION_PATCH 2 namespace jsoncons { struct versioning_info { unsigned int const major; unsigned int const minor; unsigned int const patch; friend std::ostream& operator<<(std::ostream& os, const versioning_info& ver) { os << ver.major << '.' << ver.minor << '.' << ver.patch; return os; } }; constexpr versioning_info version() { return versioning_info{JSONCONS_VERSION_MAJOR, JSONCONS_VERSION_MINOR, JSONCONS_VERSION_PATCH}; } } // namespace jsoncons #endif // JSONCONS_CONFIG_VERSION_HPP jsoncons-1.3.2/include/jsoncons/conv_error.hpp000066400000000000000000000155241477700171100215330ustar00rootroot00000000000000/// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_CONV_ERROR_HPP #define JSONCONS_CONV_ERROR_HPP #include #include #include #include #include #include #include namespace jsoncons { class conv_error : public std::system_error, public virtual json_exception { std::size_t line_number_{0}; std::size_t column_number_{0}; mutable std::string what_; public: conv_error(std::error_code ec) : std::system_error(ec) { } conv_error(std::error_code ec, const std::string& what_arg) : std::system_error(ec, what_arg) { } conv_error(std::error_code ec, std::size_t position) : std::system_error(ec), column_number_(position) { } conv_error(std::error_code ec, std::size_t line, std::size_t column) : std::system_error(ec), line_number_(line), column_number_(column) { } conv_error(const conv_error& other) = default; conv_error(conv_error&& other) = default; const char* what() const noexcept override { if (what_.empty()) { JSONCONS_TRY { what_.append(std::system_error::what()); if (line_number_ != 0 && column_number_ != 0) { what_.append(" at line "); what_.append(std::to_string(line_number_)); what_.append(" and column "); what_.append(std::to_string(column_number_)); } else if (column_number_ != 0) { what_.append(" at position "); what_.append(std::to_string(column_number_)); } return what_.c_str(); } JSONCONS_CATCH(...) { return std::system_error::what(); } } else { return what_.c_str(); } } std::size_t line() const noexcept { return line_number_; } std::size_t column() const noexcept { return column_number_; } }; enum class conv_errc { success = 0, conversion_failed, not_utf8, not_wide_char, not_vector, not_array, not_map, not_pair, not_string, not_string_view, not_byte_string, not_byte_string_view, not_integer, not_signed_integer, not_unsigned_integer, not_bigint, not_double, not_bool, not_variant, not_nullptr, not_jsoncons_null_type, not_bitset, not_base64, not_base64url, not_base16 }; template struct decode_result { InputIt it; conv_errc ec; }; } // namespace jsoncons namespace std { template<> struct is_error_code_enum : public true_type { }; } // namespace std namespace jsoncons { namespace detail { class conv_error_category_impl : public std::error_category { public: const char* name() const noexcept override { return "jsoncons/convert"; } std::string message(int ev) const override { switch (static_cast(ev)) { case conv_errc::conversion_failed: return "Unable to convert into the provided type"; case conv_errc::not_utf8: return "Cannot convert string to UTF-8"; case conv_errc::not_wide_char: return "Cannot convert string to wide characters"; case conv_errc::not_vector: return "Cannot convert to vector"; case conv_errc::not_array: return "Cannot convert to std::array"; case conv_errc::not_map: return "Cannot convert to map"; case conv_errc::not_pair: return "Cannot convert to std::pair"; case conv_errc::not_string: return "Cannot convert to string"; case conv_errc::not_string_view: return "Cannot convert to string_view"; case conv_errc::not_byte_string: return "Cannot convert to byte_string"; case conv_errc::not_byte_string_view: return "Cannot convert to byte_string_view"; case conv_errc::not_integer: return "Cannot convert to integer"; case conv_errc::not_signed_integer: return "Cannot convert to signed integer"; case conv_errc::not_unsigned_integer: return "Cannot convert to unsigned integer"; case conv_errc::not_bigint: return "Cannot convert to bigint"; case conv_errc::not_double: return "Cannot convert to double"; case conv_errc::not_bool: return "Cannot convert to bool"; case conv_errc::not_variant: return "Cannot convert to std::variant"; case conv_errc::not_nullptr: return "Cannot convert to std::nullptr_t"; case conv_errc::not_jsoncons_null_type: return "Cannot convert to jsoncons::null_type"; case conv_errc::not_bitset: return "Cannot convert to std::bitset"; case conv_errc::not_base64: return "Input is not a base64 encoded string"; case conv_errc::not_base64url: return "Input is not a base64url encoded string"; case conv_errc::not_base16: return "Input is not a base16 encoded string"; default: return "Unknown conversion error"; } } }; } // namespace detail extern inline const std::error_category& conv_error_category() { static detail::conv_error_category_impl instance; return instance; } inline std::error_code make_error_code(conv_errc result) { return std::error_code(static_cast(result),conv_error_category()); } } // namespace jsoncons #endif // JSONCONS_CONV_ERROR_HPP jsoncons-1.3.2/include/jsoncons/decode_json.hpp000066400000000000000000000225361477700171100216320ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_DECODE_JSON_HPP #define JSONCONS_DECODE_JSON_HPP #include #include // std::basic_istream #include #include #include #include #include #include #include #include namespace jsoncons { // decode_json template typename std::enable_if::value && extension_traits::is_sequence_of::value,T>::type decode_json(const Source& s, const basic_json_decode_options& options = basic_json_decode_options()) { using char_type = typename Source::value_type; jsoncons::json_decoder decoder; basic_json_reader> reader(s, decoder, options); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value && extension_traits::is_char_sequence::value,T>::type decode_json(const Source& s, const basic_json_decode_options& options = basic_json_decode_options()) { using char_type = typename Source::value_type; basic_json_cursor> cursor(s, options, default_json_parsing()); jsoncons::json_decoder> decoder; std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } template typename std::enable_if::value,T>::type decode_json(std::basic_istream& is, const basic_json_decode_options& options = basic_json_decode_options()) { jsoncons::json_decoder decoder; basic_json_reader> reader(is, decoder, options); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value,T>::type decode_json(std::basic_istream& is, const basic_json_decode_options& options = basic_json_decode_options()) { basic_json_cursor cursor(is, options, default_json_parsing()); json_decoder> decoder{}; std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.line(), cursor.column())); } return val; } template typename std::enable_if::value,T>::type decode_json(InputIt first, InputIt last, const basic_json_decode_options::value_type>& options = basic_json_decode_options::value_type>()) { using char_type = typename std::iterator_traits::value_type; jsoncons::json_decoder decoder; basic_json_reader> reader(iterator_source(first,last), decoder, options); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value,T>::type decode_json(InputIt first, InputIt last, const basic_json_decode_options::value_type>& options = basic_json_decode_options::value_type>()) { using char_type = typename std::iterator_traits::value_type; basic_json_cursor> cursor(iterator_source(first, last), options, default_json_parsing()); jsoncons::json_decoder> decoder; std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.line(), cursor.column())); } return val; } // With leading allocator_set parameter template typename std::enable_if::value && extension_traits::is_sequence_of::value,T>::type decode_json(const allocator_set& alloc_set, const Source& s, const basic_json_decode_options& options = basic_json_decode_options()) { using char_type = typename Source::value_type; json_decoder decoder(alloc_set.get_allocator(), alloc_set.get_temp_allocator()); basic_json_reader,TempAllocator> reader(s, decoder, options, alloc_set.get_temp_allocator()); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value && extension_traits::is_char_sequence::value,T>::type decode_json(const allocator_set& alloc_set, const Source& s, const basic_json_decode_options& options = basic_json_decode_options()) { using char_type = typename Source::value_type; basic_json_cursor,TempAllocator> cursor(s, options, default_json_parsing(), alloc_set.get_temp_allocator()); json_decoder,TempAllocator> decoder(alloc_set.get_temp_allocator(), alloc_set.get_temp_allocator()); std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } template typename std::enable_if::value,T>::type decode_json(const allocator_set& alloc_set, std::basic_istream& is, const basic_json_decode_options& options = basic_json_decode_options()) { json_decoder decoder(alloc_set.get_allocator(), alloc_set.get_temp_allocator()); basic_json_reader,TempAllocator> reader(is, decoder, options, alloc_set.get_temp_allocator()); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value,T>::type decode_json(const allocator_set& alloc_set, std::basic_istream& is, const basic_json_decode_options& options = basic_json_decode_options()) { basic_json_cursor,TempAllocator> cursor(is, options, default_json_parsing(), alloc_set.get_temp_allocator()); json_decoder,TempAllocator> decoder(alloc_set.get_temp_allocator(),alloc_set.get_temp_allocator()); std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } } // namespace jsoncons #endif // JSONCONS_DECODE_JSON_HPP jsoncons-1.3.2/include/jsoncons/decode_traits.hpp000066400000000000000000000544011477700171100221630ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_DECODE_TRAITS_HPP #define JSONCONS_DECODE_TRAITS_HPP #include #include #include #include #include #include #include // std::enable_if, std::true_type, std::false_type #include #include #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { // decode_traits template struct decode_traits { template static T decode(basic_staj_cursor& cursor, json_decoder& decoder, std::error_code& ec) { decoder.reset(); cursor.read_to(decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } else if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, cursor.context().line(), cursor.context().column())); } return decoder.get_result().template as(); } }; // specializations // primitive template struct decode_traits::value >::type> { template static T decode(basic_staj_cursor& cursor, json_decoder&, std::error_code& ec) { T v = cursor.current().template get(ec); return v; } }; // string template struct decode_traits::value && std::is_same::value >::type> { template static T decode(basic_staj_cursor& cursor, json_decoder&, std::error_code& ec) { T v = cursor.current().template get(ec); return v; } }; template struct decode_traits::value && !std::is_same::value >::type> { template static T decode(basic_staj_cursor& cursor, json_decoder&, std::error_code& ec) { auto val = cursor.current().template get>(ec); T s; if (!ec) { unicode_traits::convert(val.data(), val.size(), s); } return s; } }; // std::pair template struct decode_traits, CharT> { template static std::pair decode(basic_staj_cursor& cursor, json_decoder& decoder, std::error_code& ec) { using value_type = std::pair; cursor.array_expected(ec); if (JSONCONS_UNLIKELY(ec)) { return value_type{}; } if (cursor.current().event_type() != staj_event_type::begin_array) { ec = conv_errc::not_pair; return value_type(); } cursor.next(ec); // skip past array if (JSONCONS_UNLIKELY(ec)) { return value_type(); } T1 v1 = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) {return value_type();} cursor.next(ec); if (JSONCONS_UNLIKELY(ec)) {return value_type();} T2 v2 = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) {return value_type();} cursor.next(ec); if (cursor.current().event_type() != staj_event_type::end_array) { ec = conv_errc::not_pair; return value_type(); } return std::make_pair(v1, v2); } }; // vector like template struct decode_traits::value && extension_traits::is_array_like::value && extension_traits::is_back_insertable::value && !extension_traits::is_typed_array::value >::type> { using value_type = typename T::value_type; template static T decode(basic_staj_cursor& cursor, json_decoder& decoder, std::error_code& ec) { T v; cursor.array_expected(ec); if (JSONCONS_UNLIKELY(ec)) { return T{}; } if (cursor.current().event_type() != staj_event_type::begin_array) { ec = conv_errc::not_vector; return v; } cursor.next(ec); while (cursor.current().event_type() != staj_event_type::end_array && !ec) { v.push_back(decode_traits::decode(cursor, decoder, ec)); if (JSONCONS_UNLIKELY(ec)) {return T{};} //std::cout << "read next 10\n"; cursor.next(ec); } return v; } }; template struct typed_array_visitor : public default_json_visitor { T& v_; int level_{0}; public: using value_type = typename T::value_type; typed_array_visitor(T& v) : default_json_visitor(), v_(v) { } private: JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag, const ser_context&, std::error_code& ec) override { if (++level_ != 1) { ec = conv_errc::not_vector; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(std::size_t size, semantic_tag, const ser_context&, std::error_code& ec) override { if (++level_ != 1) { ec = conv_errc::not_vector; JSONCONS_VISITOR_RETURN; } if (size > 0) { reserve_storage(typename std::integral_constant::value>::type(), v_, size); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context&, std::error_code& ec) override { if (level_ != 1) { ec = conv_errc::not_vector; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t value, semantic_tag, const ser_context&, std::error_code&) override { v_.push_back(static_cast(value)); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t value, semantic_tag, const ser_context&, std::error_code&) override { v_.push_back(static_cast(value)); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_half(uint16_t value, semantic_tag, const ser_context&, std::error_code&) override { visit_half_(typename std::integral_constant::value>::type(), value); JSONCONS_VISITOR_RETURN; } void visit_half_(std::true_type, uint16_t value) { v_.push_back(static_cast(value)); } void visit_half_(std::false_type, uint16_t value) { v_.push_back(static_cast(binary::decode_half(value))); } JSONCONS_VISITOR_RETURN_TYPE visit_double(double value, semantic_tag, const ser_context&, std::error_code&) override { v_.push_back(static_cast(value)); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag, const ser_context&, std::error_code&) override { v_ = std::vector(data.begin(),data.end()); JSONCONS_VISITOR_RETURN; } static void reserve_storage(std::true_type, T& v, std::size_t new_cap) { v.reserve(new_cap); } static void reserve_storage(std::false_type, T&, std::size_t) { } }; template struct decode_traits::value && extension_traits::is_array_like::value && extension_traits::is_back_insertable_byte_container::value && extension_traits::is_typed_array::value >::type> { using value_type = typename T::value_type; template static T decode(basic_staj_cursor& cursor, json_decoder&, std::error_code& ec) { cursor.array_expected(ec); if (JSONCONS_UNLIKELY(ec)) { return T{}; } switch (cursor.current().event_type()) { case staj_event_type::byte_string_value: { auto bytes = cursor.current().template get(ec); if (!ec) { T v; if (cursor.current().size() > 0) { reserve_storage(typename std::integral_constant::value>::type(), v, cursor.current().size()); } for (auto ch : bytes) { v.push_back(static_cast(ch)); } cursor.next(ec); return v; } else { return T{}; } } case staj_event_type::begin_array: { T v; if (cursor.current().size() > 0) { reserve_storage(typename std::integral_constant::value>::type(), v, cursor.current().size()); } typed_array_visitor visitor(v); cursor.read_to(visitor, ec); return v; } default: { ec = conv_errc::not_vector; return T{}; } } } static void reserve_storage(std::true_type, T& v, std::size_t new_cap) { v.reserve(new_cap); } static void reserve_storage(std::false_type, T&, std::size_t) { } }; template struct decode_traits::value && extension_traits::is_array_like::value && extension_traits::is_back_insertable::value && !extension_traits::is_back_insertable_byte_container::value && extension_traits::is_typed_array::value >::type> { using value_type = typename T::value_type; template static T decode(basic_staj_cursor& cursor, json_decoder&, std::error_code& ec) { cursor.array_expected(ec); if (JSONCONS_UNLIKELY(ec)) { return T{}; } switch (cursor.current().event_type()) { case staj_event_type::begin_array: { T v; if (cursor.current().size() > 0) { reserve_storage(typename std::integral_constant::value>::type(), v, cursor.current().size()); } typed_array_visitor visitor(v); cursor.read_to(visitor, ec); return v; } default: { ec = conv_errc::not_vector; return T{}; } } } static void reserve_storage(std::true_type, T& v, std::size_t new_cap) { v.reserve(new_cap); } static void reserve_storage(std::false_type, T&, std::size_t) { } }; // set like template struct decode_traits::value && extension_traits::is_array_like::value && !extension_traits::is_back_insertable::value && extension_traits::is_insertable::value >::type> { using value_type = typename T::value_type; template static T decode(basic_staj_cursor& cursor, json_decoder& decoder, std::error_code& ec) { T v; cursor.array_expected(ec); if (JSONCONS_UNLIKELY(ec)) { return T{}; } if (cursor.current().event_type() != staj_event_type::begin_array) { ec = conv_errc::not_vector; return v; } if (cursor.current().size() > 0) { reserve_storage(typename std::integral_constant::value>::type(), v, cursor.current().size()); } cursor.next(ec); while (cursor.current().event_type() != staj_event_type::end_array && !ec) { v.insert(decode_traits::decode(cursor, decoder, ec)); if (JSONCONS_UNLIKELY(ec)) {return T{};} //std::cout << "cursor.next 20\n"; cursor.next(ec); if (JSONCONS_UNLIKELY(ec)) {return T{};} } return v; } static void reserve_storage(std::true_type, T& v, std::size_t new_cap) { v.reserve(new_cap); } static void reserve_storage(std::false_type, T&, std::size_t) { } }; // std::array template struct decode_traits,CharT> { using value_type = typename std::array::value_type; template static std::array decode(basic_staj_cursor& cursor, json_decoder& decoder, std::error_code& ec) { std::array v; cursor.array_expected(ec); if (JSONCONS_UNLIKELY(ec)) { v.fill(T()); return v; } v.fill(T{}); if (cursor.current().event_type() != staj_event_type::begin_array) { ec = conv_errc::not_vector; return v; } cursor.next(ec); for (std::size_t i = 0; i < N && cursor.current().event_type() != staj_event_type::end_array && !ec; ++i) { v[i] = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) {return v;} //std::cout << "cursor.next 100\n"; cursor.next(ec); if (JSONCONS_UNLIKELY(ec)) {return v;} } return v; } }; // map like template struct decode_traits::value && extension_traits::is_map_like::value && extension_traits::is_constructible_from_const_pointer_and_size::value >::type> { using mapped_type = typename T::mapped_type; using value_type = typename T::value_type; using key_type = typename T::key_type; template static T decode(basic_staj_cursor& cursor, json_decoder& decoder, std::error_code& ec) { T val; if (cursor.current().event_type() != staj_event_type::begin_object) { ec = conv_errc::not_map; return val; } if (cursor.current().size() > 0) { reserve_storage(typename std::integral_constant::value>::type(), val, cursor.current().size()); } cursor.next(ec); while (cursor.current().event_type() != staj_event_type::end_object && !ec) { if (cursor.current().event_type() != staj_event_type::key) { ec = json_errc::expected_key; return val; } auto key = cursor.current().template get(ec); if (JSONCONS_UNLIKELY(ec)) {return val;} //std::cout << "cursor.next 200\n"; cursor.next(ec); if (JSONCONS_UNLIKELY(ec)) {return val;} val.emplace(std::move(key),decode_traits::decode(cursor, decoder, ec)); if (JSONCONS_UNLIKELY(ec)) {return val;} //std::cout << "cursor.next 300\n"; cursor.next(ec); if (JSONCONS_UNLIKELY(ec)) {return val;} } return val; } static void reserve_storage(std::true_type, T& v, std::size_t new_cap) { v.reserve(new_cap); } static void reserve_storage(std::false_type, T&, std::size_t) { } }; template struct decode_traits::value && extension_traits::is_map_like::value && std::is_integral::value >::type> { using mapped_type = typename T::mapped_type; using value_type = typename T::value_type; using key_type = typename T::key_type; template static T decode(basic_staj_cursor& cursor, json_decoder& decoder, std::error_code& ec) { T val; if (cursor.current().event_type() != staj_event_type::begin_object) { ec = conv_errc::not_map; return val; } if (cursor.current().size() > 0) { reserve_storage(typename std::integral_constant::value>::type(), val, cursor.current().size()); } cursor.next(ec); while (cursor.current().event_type() != staj_event_type::end_object && !ec) { if (cursor.current().event_type() != staj_event_type::key) { ec = json_errc::expected_key; return val; } auto s = cursor.current().template get>(ec); if (JSONCONS_UNLIKELY(ec)) {return val;} key_type n{0}; auto r = jsoncons::detail::to_integer(s.data(), s.size(), n); if (r.ec != jsoncons::detail::to_integer_errc()) { ec = json_errc::invalid_number; return val; } //std::cout << "cursor.next 500\n"; cursor.next(ec); if (JSONCONS_UNLIKELY(ec)) {return val;} val.emplace(n, decode_traits::decode(cursor, decoder, ec)); if (JSONCONS_UNLIKELY(ec)) {return val;} //std::cout << "cursor.next 600\n"; cursor.next(ec); if (JSONCONS_UNLIKELY(ec)) {return val;} } return val; } static void reserve_storage(std::true_type, T& v, std::size_t new_cap) { v.reserve(new_cap); } static void reserve_storage(std::false_type, T&, std::size_t) { } }; } // namespace jsoncons #endif // JSONCONS_DECODE_TRAITS_HPP jsoncons-1.3.2/include/jsoncons/detail/000077500000000000000000000000001477700171100200775ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons/detail/endian.hpp000066400000000000000000000023131477700171100220450ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_DETAIL_ENDIAN_HPP #define JSONCONS_DETAIL_ENDIAN_HPP #if defined(__sun) # include #endif namespace jsoncons { namespace detail { enum class endian { #if defined(_MSC_VER) // MSVC, which implies Windows, which implies little-endian little = 0, big = 1, native = little #elif defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) && defined(__BYTE_ORDER__) little = __ORDER_LITTLE_ENDIAN__, big = __ORDER_BIG_ENDIAN__, native = __BYTE_ORDER__ #elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) little = 0, big = 1, native = big #elif !defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN) little = 0, big = 1, native = little #else #error "Unable to determine byte order!" #endif }; } // namespace detail } // namespace jsoncons #endif // JSONCONS_DETAIL_ENDIAN_HPP jsoncons-1.3.2/include/jsoncons/detail/grisu3.hpp000066400000000000000000000626561477700171100220430ustar00rootroot00000000000000/* Implements the Grisu3 algorithm for printing floating-point numbers. Follows Florian Loitsch's grisu3_59_56 implementation, available at http://florian.loitsch.com/publications, in bench.tar.gz, with minor modifications. */ /* Copyright (c) 2009 Florian Loitsch 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 JSONCONS_DETAIL_GRISU3_HPP #define JSONCONS_DETAIL_GRISU3_HPP #include #include #include #include #include // std::memmove #include namespace jsoncons { namespace detail { // diy_fp typedef struct diy_fp_t { uint64_t f; int e; } diy_fp_t; inline diy_fp_t minus(diy_fp_t x, diy_fp_t y) { assert(x.e == y.e); assert(x.f >= y.f); diy_fp_t r = { x.f = x.f - y.f, x.e }; return r; } inline diy_fp_t multiply(diy_fp_t x, diy_fp_t y) { uint64_t a, b, c, d, ac, bc, ad, bd, tmp; diy_fp_t r; uint64_t M32 = 0xFFFFFFFF; a = x.f >> 32; b = x.f & M32; c = y.f >> 32; d = y.f & M32; ac = a * c; bc = b * c; ad = a * d; bd = b * d; tmp = (bd >> 32) + (ad & M32) + (bc & M32); tmp += 1U << 31; /// mult_round r.f = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32); r.e = x.e + y.e + 64; return r; } // k_comp inline int k_comp(int e, int alpha, int /*gamma*/) { constexpr double d_1_log2_10 = 0.30102999566398114; // 1 / lg(10) int x = alpha - e + 63; return static_cast(std::ceil(x * d_1_log2_10)); } // powers_ten_round64 constexpr int diy_significand_size = 64; static constexpr uint64_t powers_ten[] = { 0xbf29dcaba82fdeae, 0xeef453d6923bd65a, 0x9558b4661b6565f8, 0xbaaee17fa23ebf76, 0xe95a99df8ace6f54, 0x91d8a02bb6c10594, 0xb64ec836a47146fa, 0xe3e27a444d8d98b8, 0x8e6d8c6ab0787f73, 0xb208ef855c969f50, 0xde8b2b66b3bc4724, 0x8b16fb203055ac76, 0xaddcb9e83c6b1794, 0xd953e8624b85dd79, 0x87d4713d6f33aa6c, 0xa9c98d8ccb009506, 0xd43bf0effdc0ba48, 0x84a57695fe98746d, 0xa5ced43b7e3e9188, 0xcf42894a5dce35ea, 0x818995ce7aa0e1b2, 0xa1ebfb4219491a1f, 0xca66fa129f9b60a7, 0xfd00b897478238d1, 0x9e20735e8cb16382, 0xc5a890362fddbc63, 0xf712b443bbd52b7c, 0x9a6bb0aa55653b2d, 0xc1069cd4eabe89f9, 0xf148440a256e2c77, 0x96cd2a865764dbca, 0xbc807527ed3e12bd, 0xeba09271e88d976c, 0x93445b8731587ea3, 0xb8157268fdae9e4c, 0xe61acf033d1a45df, 0x8fd0c16206306bac, 0xb3c4f1ba87bc8697, 0xe0b62e2929aba83c, 0x8c71dcd9ba0b4926, 0xaf8e5410288e1b6f, 0xdb71e91432b1a24b, 0x892731ac9faf056f, 0xab70fe17c79ac6ca, 0xd64d3d9db981787d, 0x85f0468293f0eb4e, 0xa76c582338ed2622, 0xd1476e2c07286faa, 0x82cca4db847945ca, 0xa37fce126597973d, 0xcc5fc196fefd7d0c, 0xff77b1fcbebcdc4f, 0x9faacf3df73609b1, 0xc795830d75038c1e, 0xf97ae3d0d2446f25, 0x9becce62836ac577, 0xc2e801fb244576d5, 0xf3a20279ed56d48a, 0x9845418c345644d7, 0xbe5691ef416bd60c, 0xedec366b11c6cb8f, 0x94b3a202eb1c3f39, 0xb9e08a83a5e34f08, 0xe858ad248f5c22ca, 0x91376c36d99995be, 0xb58547448ffffb2e, 0xe2e69915b3fff9f9, 0x8dd01fad907ffc3c, 0xb1442798f49ffb4b, 0xdd95317f31c7fa1d, 0x8a7d3eef7f1cfc52, 0xad1c8eab5ee43b67, 0xd863b256369d4a41, 0x873e4f75e2224e68, 0xa90de3535aaae202, 0xd3515c2831559a83, 0x8412d9991ed58092, 0xa5178fff668ae0b6, 0xce5d73ff402d98e4, 0x80fa687f881c7f8e, 0xa139029f6a239f72, 0xc987434744ac874f, 0xfbe9141915d7a922, 0x9d71ac8fada6c9b5, 0xc4ce17b399107c23, 0xf6019da07f549b2b, 0x99c102844f94e0fb, 0xc0314325637a193a, 0xf03d93eebc589f88, 0x96267c7535b763b5, 0xbbb01b9283253ca3, 0xea9c227723ee8bcb, 0x92a1958a7675175f, 0xb749faed14125d37, 0xe51c79a85916f485, 0x8f31cc0937ae58d3, 0xb2fe3f0b8599ef08, 0xdfbdcece67006ac9, 0x8bd6a141006042be, 0xaecc49914078536d, 0xda7f5bf590966849, 0x888f99797a5e012d, 0xaab37fd7d8f58179, 0xd5605fcdcf32e1d7, 0x855c3be0a17fcd26, 0xa6b34ad8c9dfc070, 0xd0601d8efc57b08c, 0x823c12795db6ce57, 0xa2cb1717b52481ed, 0xcb7ddcdda26da269, 0xfe5d54150b090b03, 0x9efa548d26e5a6e2, 0xc6b8e9b0709f109a, 0xf867241c8cc6d4c1, 0x9b407691d7fc44f8, 0xc21094364dfb5637, 0xf294b943e17a2bc4, 0x979cf3ca6cec5b5b, 0xbd8430bd08277231, 0xece53cec4a314ebe, 0x940f4613ae5ed137, 0xb913179899f68584, 0xe757dd7ec07426e5, 0x9096ea6f3848984f, 0xb4bca50b065abe63, 0xe1ebce4dc7f16dfc, 0x8d3360f09cf6e4bd, 0xb080392cc4349ded, 0xdca04777f541c568, 0x89e42caaf9491b61, 0xac5d37d5b79b6239, 0xd77485cb25823ac7, 0x86a8d39ef77164bd, 0xa8530886b54dbdec, 0xd267caa862a12d67, 0x8380dea93da4bc60, 0xa46116538d0deb78, 0xcd795be870516656, 0x806bd9714632dff6, 0xa086cfcd97bf97f4, 0xc8a883c0fdaf7df0, 0xfad2a4b13d1b5d6c, 0x9cc3a6eec6311a64, 0xc3f490aa77bd60fd, 0xf4f1b4d515acb93c, 0x991711052d8bf3c5, 0xbf5cd54678eef0b7, 0xef340a98172aace5, 0x9580869f0e7aac0f, 0xbae0a846d2195713, 0xe998d258869facd7, 0x91ff83775423cc06, 0xb67f6455292cbf08, 0xe41f3d6a7377eeca, 0x8e938662882af53e, 0xb23867fb2a35b28e, 0xdec681f9f4c31f31, 0x8b3c113c38f9f37f, 0xae0b158b4738705f, 0xd98ddaee19068c76, 0x87f8a8d4cfa417ca, 0xa9f6d30a038d1dbc, 0xd47487cc8470652b, 0x84c8d4dfd2c63f3b, 0xa5fb0a17c777cf0a, 0xcf79cc9db955c2cc, 0x81ac1fe293d599c0, 0xa21727db38cb0030, 0xca9cf1d206fdc03c, 0xfd442e4688bd304b, 0x9e4a9cec15763e2f, 0xc5dd44271ad3cdba, 0xf7549530e188c129, 0x9a94dd3e8cf578ba, 0xc13a148e3032d6e8, 0xf18899b1bc3f8ca2, 0x96f5600f15a7b7e5, 0xbcb2b812db11a5de, 0xebdf661791d60f56, 0x936b9fcebb25c996, 0xb84687c269ef3bfb, 0xe65829b3046b0afa, 0x8ff71a0fe2c2e6dc, 0xb3f4e093db73a093, 0xe0f218b8d25088b8, 0x8c974f7383725573, 0xafbd2350644eead0, 0xdbac6c247d62a584, 0x894bc396ce5da772, 0xab9eb47c81f5114f, 0xd686619ba27255a3, 0x8613fd0145877586, 0xa798fc4196e952e7, 0xd17f3b51fca3a7a1, 0x82ef85133de648c5, 0xa3ab66580d5fdaf6, 0xcc963fee10b7d1b3, 0xffbbcfe994e5c620, 0x9fd561f1fd0f9bd4, 0xc7caba6e7c5382c9, 0xf9bd690a1b68637b, 0x9c1661a651213e2d, 0xc31bfa0fe5698db8, 0xf3e2f893dec3f126, 0x986ddb5c6b3a76b8, 0xbe89523386091466, 0xee2ba6c0678b597f, 0x94db483840b717f0, 0xba121a4650e4ddec, 0xe896a0d7e51e1566, 0x915e2486ef32cd60, 0xb5b5ada8aaff80b8, 0xe3231912d5bf60e6, 0x8df5efabc5979c90, 0xb1736b96b6fd83b4, 0xddd0467c64bce4a1, 0x8aa22c0dbef60ee4, 0xad4ab7112eb3929e, 0xd89d64d57a607745, 0x87625f056c7c4a8b, 0xa93af6c6c79b5d2e, 0xd389b47879823479, 0x843610cb4bf160cc, 0xa54394fe1eedb8ff, 0xce947a3da6a9273e, 0x811ccc668829b887, 0xa163ff802a3426a9, 0xc9bcff6034c13053, 0xfc2c3f3841f17c68, 0x9d9ba7832936edc1, 0xc5029163f384a931, 0xf64335bcf065d37d, 0x99ea0196163fa42e, 0xc06481fb9bcf8d3a, 0xf07da27a82c37088, 0x964e858c91ba2655, 0xbbe226efb628afeb, 0xeadab0aba3b2dbe5, 0x92c8ae6b464fc96f, 0xb77ada0617e3bbcb, 0xe55990879ddcaabe, 0x8f57fa54c2a9eab7, 0xb32df8e9f3546564, 0xdff9772470297ebd, 0x8bfbea76c619ef36, 0xaefae51477a06b04, 0xdab99e59958885c5, 0x88b402f7fd75539b, 0xaae103b5fcd2a882, 0xd59944a37c0752a2, 0x857fcae62d8493a5, 0xa6dfbd9fb8e5b88f, 0xd097ad07a71f26b2, 0x825ecc24c8737830, 0xa2f67f2dfa90563b, 0xcbb41ef979346bca, 0xfea126b7d78186bd, 0x9f24b832e6b0f436, 0xc6ede63fa05d3144, 0xf8a95fcf88747d94, 0x9b69dbe1b548ce7d, 0xc24452da229b021c, 0xf2d56790ab41c2a3, 0x97c560ba6b0919a6, 0xbdb6b8e905cb600f, 0xed246723473e3813, 0x9436c0760c86e30c, 0xb94470938fa89bcf, 0xe7958cb87392c2c3, 0x90bd77f3483bb9ba, 0xb4ecd5f01a4aa828, 0xe2280b6c20dd5232, 0x8d590723948a535f, 0xb0af48ec79ace837, 0xdcdb1b2798182245, 0x8a08f0f8bf0f156b, 0xac8b2d36eed2dac6, 0xd7adf884aa879177, 0x86ccbb52ea94baeb, 0xa87fea27a539e9a5, 0xd29fe4b18e88640f, 0x83a3eeeef9153e89, 0xa48ceaaab75a8e2b, 0xcdb02555653131b6, 0x808e17555f3ebf12, 0xa0b19d2ab70e6ed6, 0xc8de047564d20a8c, 0xfb158592be068d2f, 0x9ced737bb6c4183d, 0xc428d05aa4751e4d, 0xf53304714d9265e0, 0x993fe2c6d07b7fac, 0xbf8fdb78849a5f97, 0xef73d256a5c0f77d, 0x95a8637627989aae, 0xbb127c53b17ec159, 0xe9d71b689dde71b0, 0x9226712162ab070e, 0xb6b00d69bb55c8d1, 0xe45c10c42a2b3b06, 0x8eb98a7a9a5b04e3, 0xb267ed1940f1c61c, 0xdf01e85f912e37a3, 0x8b61313bbabce2c6, 0xae397d8aa96c1b78, 0xd9c7dced53c72256, 0x881cea14545c7575, 0xaa242499697392d3, 0xd4ad2dbfc3d07788, 0x84ec3c97da624ab5, 0xa6274bbdd0fadd62, 0xcfb11ead453994ba, 0x81ceb32c4b43fcf5, 0xa2425ff75e14fc32, 0xcad2f7f5359a3b3e, 0xfd87b5f28300ca0e, 0x9e74d1b791e07e48, 0xc612062576589ddb, 0xf79687aed3eec551, 0x9abe14cd44753b53, 0xc16d9a0095928a27, 0xf1c90080baf72cb1, 0x971da05074da7bef, 0xbce5086492111aeb, 0xec1e4a7db69561a5, 0x9392ee8e921d5d07, 0xb877aa3236a4b449, 0xe69594bec44de15b, 0x901d7cf73ab0acd9, 0xb424dc35095cd80f, 0xe12e13424bb40e13, 0x8cbccc096f5088cc, 0xafebff0bcb24aaff, 0xdbe6fecebdedd5bf, 0x89705f4136b4a597, 0xabcc77118461cefd, 0xd6bf94d5e57a42bc, 0x8637bd05af6c69b6, 0xa7c5ac471b478423, 0xd1b71758e219652c, 0x83126e978d4fdf3b, 0xa3d70a3d70a3d70a, 0xcccccccccccccccd, 0x8000000000000000, 0xa000000000000000, 0xc800000000000000, 0xfa00000000000000, 0x9c40000000000000, 0xc350000000000000, 0xf424000000000000, 0x9896800000000000, 0xbebc200000000000, 0xee6b280000000000, 0x9502f90000000000, 0xba43b74000000000, 0xe8d4a51000000000, 0x9184e72a00000000, 0xb5e620f480000000, 0xe35fa931a0000000, 0x8e1bc9bf04000000, 0xb1a2bc2ec5000000, 0xde0b6b3a76400000, 0x8ac7230489e80000, 0xad78ebc5ac620000, 0xd8d726b7177a8000, 0x878678326eac9000, 0xa968163f0a57b400, 0xd3c21bcecceda100, 0x84595161401484a0, 0xa56fa5b99019a5c8, 0xcecb8f27f4200f3a, 0x813f3978f8940984, 0xa18f07d736b90be5, 0xc9f2c9cd04674edf, 0xfc6f7c4045812296, 0x9dc5ada82b70b59e, 0xc5371912364ce305, 0xf684df56c3e01bc7, 0x9a130b963a6c115c, 0xc097ce7bc90715b3, 0xf0bdc21abb48db20, 0x96769950b50d88f4, 0xbc143fa4e250eb31, 0xeb194f8e1ae525fd, 0x92efd1b8d0cf37be, 0xb7abc627050305ae, 0xe596b7b0c643c719, 0x8f7e32ce7bea5c70, 0xb35dbf821ae4f38c, 0xe0352f62a19e306f, 0x8c213d9da502de45, 0xaf298d050e4395d7, 0xdaf3f04651d47b4c, 0x88d8762bf324cd10, 0xab0e93b6efee0054, 0xd5d238a4abe98068, 0x85a36366eb71f041, 0xa70c3c40a64e6c52, 0xd0cf4b50cfe20766, 0x82818f1281ed44a0, 0xa321f2d7226895c8, 0xcbea6f8ceb02bb3a, 0xfee50b7025c36a08, 0x9f4f2726179a2245, 0xc722f0ef9d80aad6, 0xf8ebad2b84e0d58c, 0x9b934c3b330c8577, 0xc2781f49ffcfa6d5, 0xf316271c7fc3908b, 0x97edd871cfda3a57, 0xbde94e8e43d0c8ec, 0xed63a231d4c4fb27, 0x945e455f24fb1cf9, 0xb975d6b6ee39e437, 0xe7d34c64a9c85d44, 0x90e40fbeea1d3a4b, 0xb51d13aea4a488dd, 0xe264589a4dcdab15, 0x8d7eb76070a08aed, 0xb0de65388cc8ada8, 0xdd15fe86affad912, 0x8a2dbf142dfcc7ab, 0xacb92ed9397bf996, 0xd7e77a8f87daf7fc, 0x86f0ac99b4e8dafd, 0xa8acd7c0222311bd, 0xd2d80db02aabd62c, 0x83c7088e1aab65db, 0xa4b8cab1a1563f52, 0xcde6fd5e09abcf27, 0x80b05e5ac60b6178, 0xa0dc75f1778e39d6, 0xc913936dd571c84c, 0xfb5878494ace3a5f, 0x9d174b2dcec0e47b, 0xc45d1df942711d9a, 0xf5746577930d6501, 0x9968bf6abbe85f20, 0xbfc2ef456ae276e9, 0xefb3ab16c59b14a3, 0x95d04aee3b80ece6, 0xbb445da9ca61281f, 0xea1575143cf97227, 0x924d692ca61be758, 0xb6e0c377cfa2e12e, 0xe498f455c38b997a, 0x8edf98b59a373fec, 0xb2977ee300c50fe7, 0xdf3d5e9bc0f653e1, 0x8b865b215899f46d, 0xae67f1e9aec07188, 0xda01ee641a708dea, 0x884134fe908658b2, 0xaa51823e34a7eedf, 0xd4e5e2cdc1d1ea96, 0x850fadc09923329e, 0xa6539930bf6bff46, 0xcfe87f7cef46ff17, 0x81f14fae158c5f6e, 0xa26da3999aef774a, 0xcb090c8001ab551c, 0xfdcb4fa002162a63, 0x9e9f11c4014dda7e, 0xc646d63501a1511e, 0xf7d88bc24209a565, 0x9ae757596946075f, 0xc1a12d2fc3978937, 0xf209787bb47d6b85, 0x9745eb4d50ce6333, 0xbd176620a501fc00, 0xec5d3fa8ce427b00, 0x93ba47c980e98ce0, 0xb8a8d9bbe123f018, 0xe6d3102ad96cec1e, 0x9043ea1ac7e41393, 0xb454e4a179dd1877, 0xe16a1dc9d8545e95, 0x8ce2529e2734bb1d, 0xb01ae745b101e9e4, 0xdc21a1171d42645d, 0x899504ae72497eba, 0xabfa45da0edbde69, 0xd6f8d7509292d603, 0x865b86925b9bc5c2, 0xa7f26836f282b733, 0xd1ef0244af2364ff, 0x8335616aed761f1f, 0xa402b9c5a8d3a6e7, 0xcd036837130890a1, 0x802221226be55a65, 0xa02aa96b06deb0fe, 0xc83553c5c8965d3d, 0xfa42a8b73abbf48d, 0x9c69a97284b578d8, 0xc38413cf25e2d70e, 0xf46518c2ef5b8cd1, 0x98bf2f79d5993803, 0xbeeefb584aff8604, 0xeeaaba2e5dbf6785, 0x952ab45cfa97a0b3, 0xba756174393d88e0, 0xe912b9d1478ceb17, 0x91abb422ccb812ef, 0xb616a12b7fe617aa, 0xe39c49765fdf9d95, 0x8e41ade9fbebc27d, 0xb1d219647ae6b31c, 0xde469fbd99a05fe3, 0x8aec23d680043bee, 0xada72ccc20054aea, 0xd910f7ff28069da4, 0x87aa9aff79042287, 0xa99541bf57452b28, 0xd3fa922f2d1675f2, 0x847c9b5d7c2e09b7, 0xa59bc234db398c25, 0xcf02b2c21207ef2f, 0x8161afb94b44f57d, 0xa1ba1ba79e1632dc, 0xca28a291859bbf93, 0xfcb2cb35e702af78, 0x9defbf01b061adab, 0xc56baec21c7a1916, 0xf6c69a72a3989f5c, 0x9a3c2087a63f6399, 0xc0cb28a98fcf3c80, 0xf0fdf2d3f3c30b9f, 0x969eb7c47859e744, 0xbc4665b596706115, 0xeb57ff22fc0c795a, 0x9316ff75dd87cbd8, 0xb7dcbf5354e9bece, 0xe5d3ef282a242e82, 0x8fa475791a569d11, 0xb38d92d760ec4455, 0xe070f78d3927556b, 0x8c469ab843b89563, 0xaf58416654a6babb, 0xdb2e51bfe9d0696a, 0x88fcf317f22241e2, 0xab3c2fddeeaad25b, 0xd60b3bd56a5586f2, 0x85c7056562757457, 0xa738c6bebb12d16d, 0xd106f86e69d785c8, 0x82a45b450226b39d, 0xa34d721642b06084, 0xcc20ce9bd35c78a5, 0xff290242c83396ce, 0x9f79a169bd203e41, 0xc75809c42c684dd1, 0xf92e0c3537826146, 0x9bbcc7a142b17ccc, 0xc2abf989935ddbfe, 0xf356f7ebf83552fe, 0x98165af37b2153df, 0xbe1bf1b059e9a8d6, 0xeda2ee1c7064130c, 0x9485d4d1c63e8be8, 0xb9a74a0637ce2ee1, 0xe8111c87c5c1ba9a, 0x910ab1d4db9914a0, 0xb54d5e4a127f59c8, 0xe2a0b5dc971f303a, 0x8da471a9de737e24, 0xb10d8e1456105dad, 0xdd50f1996b947519, 0x8a5296ffe33cc930, 0xace73cbfdc0bfb7b, 0xd8210befd30efa5a, 0x8714a775e3e95c78, 0xa8d9d1535ce3b396, 0xd31045a8341ca07c, 0x83ea2b892091e44e, 0xa4e4b66b68b65d61, 0xce1de40642e3f4b9, 0x80d2ae83e9ce78f4, 0xa1075a24e4421731, 0xc94930ae1d529cfd, 0xfb9b7cd9a4a7443c, 0x9d412e0806e88aa6, 0xc491798a08a2ad4f, 0xf5b5d7ec8acb58a3, 0x9991a6f3d6bf1766, 0xbff610b0cc6edd3f, 0xeff394dcff8a948f, 0x95f83d0a1fb69cd9, 0xbb764c4ca7a44410, 0xea53df5fd18d5514, 0x92746b9be2f8552c, 0xb7118682dbb66a77, 0xe4d5e82392a40515, 0x8f05b1163ba6832d, 0xb2c71d5bca9023f8, 0xdf78e4b2bd342cf7, 0x8bab8eefb6409c1a, 0xae9672aba3d0c321, 0xda3c0f568cc4f3e9, 0x8865899617fb1871, 0xaa7eebfb9df9de8e, 0xd51ea6fa85785631, 0x8533285c936b35df, 0xa67ff273b8460357, 0xd01fef10a657842c, 0x8213f56a67f6b29c, 0xa298f2c501f45f43, 0xcb3f2f7642717713, 0xfe0efb53d30dd4d8, 0x9ec95d1463e8a507, 0xc67bb4597ce2ce49, 0xf81aa16fdc1b81db, 0x9b10a4e5e9913129, 0xc1d4ce1f63f57d73, 0xf24a01a73cf2dcd0, 0x976e41088617ca02, 0xbd49d14aa79dbc82, 0xec9c459d51852ba3, 0x93e1ab8252f33b46, 0xb8da1662e7b00a17, 0xe7109bfba19c0c9d, 0x906a617d450187e2, 0xb484f9dc9641e9db, 0xe1a63853bbd26451, 0x8d07e33455637eb3, 0xb049dc016abc5e60, 0xdc5c5301c56b75f7, 0x89b9b3e11b6329bb, 0xac2820d9623bf429, 0xd732290fbacaf134, 0x867f59a9d4bed6c0, 0xa81f301449ee8c70, 0xd226fc195c6a2f8c, 0x83585d8fd9c25db8, 0xa42e74f3d032f526, 0xcd3a1230c43fb26f, 0x80444b5e7aa7cf85, 0xa0555e361951c367, 0xc86ab5c39fa63441, 0xfa856334878fc151, 0x9c935e00d4b9d8d2, 0xc3b8358109e84f07, 0xf4a642e14c6262c9, 0x98e7e9cccfbd7dbe, 0xbf21e44003acdd2d, 0xeeea5d5004981478, 0x95527a5202df0ccb, 0xbaa718e68396cffe, 0xe950df20247c83fd, 0x91d28b7416cdd27e, 0xb6472e511c81471e, 0xe3d8f9e563a198e5, 0x8e679c2f5e44ff8f, 0xb201833b35d63f73, 0xde81e40a034bcf50, 0x8b112e86420f6192, 0xadd57a27d29339f6, 0xd94ad8b1c7380874, 0x87cec76f1c830549, 0xa9c2794ae3a3c69b, 0xd433179d9c8cb841, 0x849feec281d7f329, 0xa5c7ea73224deff3, 0xcf39e50feae16bf0, 0x81842f29f2cce376, 0xa1e53af46f801c53, 0xca5e89b18b602368, 0xfcf62c1dee382c42, 0x9e19db92b4e31ba9, 0xc5a05277621be294, 0xf70867153aa2db39, 0x9a65406d44a5c903, 0xc0fe908895cf3b44, 0xf13e34aabb430a15, 0x96c6e0eab509e64d, 0xbc789925624c5fe1, 0xeb96bf6ebadf77d9, 0x933e37a534cbaae8, 0xb80dc58e81fe95a1, 0xe61136f2227e3b0a, 0x8fcac257558ee4e6, 0xb3bd72ed2af29e20, 0xe0accfa875af45a8, 0x8c6c01c9498d8b89, 0xaf87023b9bf0ee6b, 0xdb68c2ca82ed2a06, 0x892179be91d43a44, 0xab69d82e364948d4 }; static constexpr int powers_ten_e[] = { -1203, -1200, -1196, -1193, -1190, -1186, -1183, -1180, -1176, -1173, -1170, -1166, -1163, -1160, -1156, -1153, -1150, -1146, -1143, -1140, -1136, -1133, -1130, -1127, -1123, -1120, -1117, -1113, -1110, -1107, -1103, -1100, -1097, -1093, -1090, -1087, -1083, -1080, -1077, -1073, -1070, -1067, -1063, -1060, -1057, -1053, -1050, -1047, -1043, -1040, -1037, -1034, -1030, -1027, -1024, -1020, -1017, -1014, -1010, -1007, -1004, -1000, -997, -994, -990, -987, -984, -980, -977, -974, -970, -967, -964, -960, -957, -954, -950, -947, -944, -940, -937, -934, -931, -927, -924, -921, -917, -914, -911, -907, -904, -901, -897, -894, -891, -887, -884, -881, -877, -874, -871, -867, -864, -861, -857, -854, -851, -847, -844, -841, -838, -834, -831, -828, -824, -821, -818, -814, -811, -808, -804, -801, -798, -794, -791, -788, -784, -781, -778, -774, -771, -768, -764, -761, -758, -754, -751, -748, -744, -741, -738, -735, -731, -728, -725, -721, -718, -715, -711, -708, -705, -701, -698, -695, -691, -688, -685, -681, -678, -675, -671, -668, -665, -661, -658, -655, -651, -648, -645, -642, -638, -635, -632, -628, -625, -622, -618, -615, -612, -608, -605, -602, -598, -595, -592, -588, -585, -582, -578, -575, -572, -568, -565, -562, -558, -555, -552, -549, -545, -542, -539, -535, -532, -529, -525, -522, -519, -515, -512, -509, -505, -502, -499, -495, -492, -489, -485, -482, -479, -475, -472, -469, -465, -462, -459, -455, -452, -449, -446, -442, -439, -436, -432, -429, -426, -422, -419, -416, -412, -409, -406, -402, -399, -396, -392, -389, -386, -382, -379, -376, -372, -369, -366, -362, -359, -356, -353, -349, -346, -343, -339, -336, -333, -329, -326, -323, -319, -316, -313, -309, -306, -303, -299, -296, -293, -289, -286, -283, -279, -276, -273, -269, -266, -263, -259, -256, -253, -250, -246, -243, -240, -236, -233, -230, -226, -223, -220, -216, -213, -210, -206, -203, -200, -196, -193, -190, -186, -183, -180, -176, -173, -170, -166, -163, -160, -157, -153, -150, -147, -143, -140, -137, -133, -130, -127, -123, -120, -117, -113, -110, -107, -103, -100, -97, -93, -90, -87, -83, -80, -77, -73, -70, -67, -63, -60, -57, -54, -50, -47, -44, -40, -37, -34, -30, -27, -24, -20, -17, -14, -10, -7, -4, 0, 3, 6, 10, 13, 16, 20, 23, 26, 30, 33, 36, 39, 43, 46, 49, 53, 56, 59, 63, 66, 69, 73, 76, 79, 83, 86, 89, 93, 96, 99, 103, 106, 109, 113, 116, 119, 123, 126, 129, 132, 136, 139, 142, 146, 149, 152, 156, 159, 162, 166, 169, 172, 176, 179, 182, 186, 189, 192, 196, 199, 202, 206, 209, 212, 216, 219, 222, 226, 229, 232, 235, 239, 242, 245, 249, 252, 255, 259, 262, 265, 269, 272, 275, 279, 282, 285, 289, 292, 295, 299, 302, 305, 309, 312, 315, 319, 322, 325, 328, 332, 335, 338, 342, 345, 348, 352, 355, 358, 362, 365, 368, 372, 375, 378, 382, 385, 388, 392, 395, 398, 402, 405, 408, 412, 415, 418, 422, 425, 428, 431, 435, 438, 441, 445, 448, 451, 455, 458, 461, 465, 468, 471, 475, 478, 481, 485, 488, 491, 495, 498, 501, 505, 508, 511, 515, 518, 521, 524, 528, 531, 534, 538, 541, 544, 548, 551, 554, 558, 561, 564, 568, 571, 574, 578, 581, 584, 588, 591, 594, 598, 601, 604, 608, 611, 614, 617, 621, 624, 627, 631, 634, 637, 641, 644, 647, 651, 654, 657, 661, 664, 667, 671, 674, 677, 681, 684, 687, 691, 694, 697, 701, 704, 707, 711, 714, 717, 720, 724, 727, 730, 734, 737, 740, 744, 747, 750, 754, 757, 760, 764, 767, 770, 774, 777, 780, 784, 787, 790, 794, 797, 800, 804, 807, 810, 813, 817, 820, 823, 827, 830, 833, 837, 840, 843, 847, 850, 853, 857, 860, 863, 867, 870, 873, 877, 880, 883, 887, 890, 893, 897, 900, 903, 907, 910, 913, 916, 920, 923, 926, 930, 933, 936, 940, 943, 946, 950, 953, 956, 960, 963, 966, 970, 973, 976, 980, 983, 986, 990, 993, 996, 1000, 1003, 1006, 1009, 1013, 1016, 1019, 1023, 1026, 1029, 1033, 1036, 1039, 1043, 1046, 1049, 1053, 1056, 1059, 1063, 1066, 1069, 1073, 1076 }; inline diy_fp_t cached_power(int k) { diy_fp_t res; int index = 343 + k; res.f = powers_ten[index]; res.e = powers_ten_e[index]; return res; } // double /* typedef union { double d; uint64_t n; } converter_t; inline uint64_t double_to_uint64(double d) { converter_t tmp; tmp.d = d; return tmp.n; } inline double uint64_to_double(uint64_t d64) { converter_t tmp; tmp.n = d64; return tmp.d; } */ inline uint64_t double_to_uint64(double d) {uint64_t d64; std::memcpy(&d64,&d,sizeof(double)); return d64; } inline double uint64_to_double(uint64_t d64) {double d; std::memcpy(&d,&d64,sizeof(double)); return d; } constexpr int dp_significand_size = 52; constexpr int dp_exponent_bias = (0x3FF + dp_significand_size); constexpr int dp_min_exponent = (-dp_exponent_bias); constexpr uint64_t dp_exponent_mask = 0x7FF0000000000000; constexpr uint64_t dp_significand_mask = 0x000FFFFFFFFFFFFF; constexpr uint64_t dp_hidden_bit = 0x0010000000000000; inline diy_fp_t normalize_diy_fp(diy_fp_t in) { diy_fp_t res = in; /* Normalize now */ /* the original number could have been a denormal. */ while (!(res.f & dp_hidden_bit)) { res.f <<= 1; res.e--; } /* do the final shifts in one go. Don't forget the hidden bit (the '-1') */ res.f <<= (diy_significand_size - dp_significand_size - 1); res.e = res.e - (diy_significand_size - dp_significand_size - 1); return res; } inline diy_fp_t double2diy_fp(double d) { uint64_t d64 = double_to_uint64(d); int biased_e = (d64 & dp_exponent_mask) >> dp_significand_size; uint64_t significand = (d64 & dp_significand_mask); diy_fp_t res; if (biased_e != 0) { res.f = significand + dp_hidden_bit; res.e = biased_e - dp_exponent_bias; } else { res.f = significand; res.e = dp_min_exponent + 1; } return res; } inline diy_fp_t normalize_boundary(diy_fp_t in) { diy_fp_t res = in; /* Normalize now */ /* the original number could have been a denormal. */ while (!(res.f & (dp_hidden_bit << 1))) { res.f <<= 1; res.e--; } /* do the final shifts in one go. Don't forget the hidden bit (the '-1') */ res.f <<= (diy_significand_size - dp_significand_size - 2); res.e = res.e - (diy_significand_size - dp_significand_size - 2); return res; } inline void normalized_boundaries(double d, diy_fp_t *out_m_minus, diy_fp_t *out_m_plus) { diy_fp_t v = double2diy_fp(d); diy_fp_t pl, mi; bool significand_is_zero = v.f == dp_hidden_bit; pl.f = (v.f << 1) + 1; pl.e = v.e - 1; pl = normalize_boundary(pl); if (significand_is_zero) { mi.f = (v.f << 2) - 1; mi.e = v.e - 2; } else { mi.f = (v.f << 1) - 1; mi.e = v.e - 1; } int x = mi.e - pl.e; mi.f <<= x; mi.e = pl.e; *out_m_plus = pl; *out_m_minus = mi; } inline double random_double() { uint64_t tmp = 0; int i; for (i = 0; i < 8; i++) { tmp <<= 8; tmp += rand() % 256; } return uint64_to_double(tmp); } // grisu3 inline bool round_weed(char *buffer, int len, uint64_t wp_W, uint64_t Delta, uint64_t rest, uint64_t ten_kappa, uint64_t ulp) { uint64_t wp_Wup = wp_W - ulp; uint64_t wp_Wdown = wp_W + ulp; while (rest < wp_Wup && /// round1 Delta - rest >= ten_kappa && (rest + ten_kappa < wp_Wup || /// closer wp_Wup - rest >= rest + ten_kappa - wp_Wup)) { buffer[len - 1]--; rest += ten_kappa; } if (rest < wp_Wdown && /// round2 Delta - rest >= ten_kappa && (rest + ten_kappa < wp_Wdown || wp_Wdown - rest > rest + ten_kappa - wp_Wdown)) return 0; return 2 * ulp <= rest && rest <= Delta - 4 * ulp; /// weed } inline bool digit_gen(diy_fp_t Wm, diy_fp_t W, diy_fp_t Wp, char *buffer, int *len, int *K) { const uint32_t TEN2 = 100; uint32_t div, p1; uint64_t p2, tmp, unit = 1; int d, kappa; diy_fp_t one, wp_W, Delta; Delta = minus(Wp, Wm); Delta.f += 2 * unit; wp_W = minus(Wp, W); wp_W.f += unit; one.f = ((uint64_t)1) << -Wp.e; one.e = Wp.e; p1 = static_cast((Wp.f + 1) >> -one.e); p2 = (Wp.f + 1) & (one.f - 1); *len = 0; kappa = 3; div = TEN2; while (kappa > 0) { d = p1 / div; if (d || *len) buffer[(*len)++] = (char)('0' + d); p1 %= div; kappa--; tmp = (((uint64_t)p1) << -one.e) + p2; if (tmp < Delta.f) { *K += kappa; return round_weed(buffer, *len, wp_W.f, Delta.f, tmp, ((uint64_t)div) << -one.e, unit); } div /= 10; } while (1) { p2 *= 10; Delta.f *= 10; unit *= 10; d = static_cast(p2 >> -one.e); if (d || *len) buffer[(*len)++] = (char)('0' + d); p2 &= one.f - 1; kappa--; if (p2 < Delta.f) { *K += kappa; return round_weed(buffer, *len, wp_W.f * unit, Delta.f, p2, one.f, unit); } } } inline bool grisu3(double v, char *buffer, int *length, int *K) { diy_fp_t w_m, w_p; int q = 64, alpha = -59, gamma = -56; normalized_boundaries(v, &w_m, &w_p); diy_fp_t w = normalize_diy_fp(double2diy_fp(v)); int mk = k_comp(w_p.e + q, alpha, gamma); diy_fp_t c_mk = cached_power(mk); diy_fp_t W = multiply(w, c_mk); diy_fp_t Wp = multiply(w_p, c_mk); diy_fp_t Wm = multiply(w_m, c_mk); *K = -mk; bool result = digit_gen(Wm, W, Wp, buffer, length, K); buffer[*length] = 0; return result; } } // namespace detail } // namespace jsoncons #endif // JSONCONS_DETAIL_GRISU3_HPP jsoncons-1.3.2/include/jsoncons/detail/optional.hpp000066400000000000000000000372161477700171100224460ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_DETAIL_OPTIONAL_HPP #define JSONCONS_DETAIL_OPTIONAL_HPP #include #include #include #include // std::swap #include namespace jsoncons { namespace detail { template class optional; template struct is_constructible_or_convertible_from_optional : std::integral_constant< bool, std::is_constructible&>::value || std::is_constructible&&>::value || std::is_constructible&>::value || std::is_constructible&&>::value || std::is_convertible&, T1>::value || std::is_convertible&&, T1>::value || std::is_convertible&, T1>::value || std::is_convertible&&, T1>::value> {}; template struct is_constructible_convertible_or_assignable_from_optional : std::integral_constant< bool, is_constructible_or_convertible_from_optional::value || std::is_assignable&>::value || std::is_assignable&&>::value || std::is_assignable&>::value || std::is_assignable&&>::value> {}; template class optional { public: using value_type = T; private: bool has_value_; union { char dummy_; T value_; }; public: constexpr optional() noexcept : has_value_(false), dummy_{} { } // copy constructors optional(const optional& other) : has_value_(false), dummy_{} { if (other) { construct(*other); } } // converting template ::value && std::is_constructible::value && std::is_convertible::value && !is_constructible_or_convertible_from_optional::value && std::is_copy_constructible::type>::value,int>::type = 0> optional(const optional& other) : has_value_(false), dummy_{} { if (other) { construct(*other); } } template ::value && std::is_constructible::value && !std::is_convertible::value && !is_constructible_or_convertible_from_optional::value && std::is_copy_constructible::type>::value,int>::type = 0> explicit optional(const optional& other) : has_value_(false), dummy_{} { if (other) { construct(*other); } } // move constructors template optional(optional&& other, typename std::enable_if::type>::value>::type* = 0) : has_value_(false), dummy_{} { if (other) { construct(std::move(other.value_)); } } // converting template optional(optional&& value, typename std::enable_if::value && std::is_constructible::value && !is_constructible_or_convertible_from_optional::value && std::is_convertible::value,int>::type = 0) // (8) : has_value_(true), value_(std::forward(value)) { } template explicit optional(optional&& value, typename std::enable_if::value && std::is_constructible::value && !is_constructible_or_convertible_from_optional::value && !std::is_convertible::value,int>::type = 0) // (8) : has_value_(true), value_(std::forward(value)) { } // value constructors template optional(T2&& value, typename std::enable_if,typename std::decay::type>::value && std::is_constructible::value && std::is_convertible::value,int>::type = 0) // (8) : has_value_(true), value_(std::forward(value)) { } template explicit optional(T2&& value, typename std::enable_if,typename std::decay::type>::value && std::is_constructible::value && !std::is_convertible::value,int>::type = 0) // (8) : has_value_(true), value_(std::forward(value)) { } ~optional() noexcept { destroy(); } optional& operator=(const optional& other) { if (other) { assign(*other); } else { reset(); } return *this; } optional& operator=(optional&& other ) { if (other) { assign(std::move(*other)); } else { reset(); } return *this; } template typename std::enable_if, U>::value && std::is_constructible::value && !is_constructible_convertible_or_assignable_from_optional::value && std::is_assignable::value, optional&>::type operator=(const optional& other) { if (other) { assign(*other); } else { destroy(); } return *this; } template typename std::enable_if, U>::value && std::is_constructible::value && !is_constructible_convertible_or_assignable_from_optional::value && std::is_assignable::value, optional&>::type operator=(optional&& other) noexcept { if (other) { assign(std::move(*other)); } else { destroy(); } return *this; } // value assignment template typename std::enable_if,typename std::decay::type>::value && std::is_constructible::value && std::is_assignable::value && !(std::is_scalar::value && std::is_same::type>::value), optional&>::type operator=(T2&& v) { assign(std::forward(v)); return *this; } constexpr explicit operator bool() const noexcept { return has_value_; } constexpr bool has_value() const noexcept { return has_value_; } #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 4702) #endif // _MSC_VER T& value() & { if (has_value_) { return get(); } JSONCONS_THROW(std::runtime_error("Bad optional access")); } JSONCONS_CONSTEXPR const T& value() const & { if (has_value_) { return get(); } JSONCONS_THROW(std::runtime_error("Bad optional access")); } template constexpr T value_or(U&& default_value) const & { static_assert(std::is_copy_constructible::value, "get_value_or: T must be copy constructible"); static_assert(std::is_convertible::value, "get_value_or: U must be convertible to T"); return static_cast(*this) ? **this : static_cast(std::forward(default_value)); } template T value_or(U&& default_value) && { static_assert(std::is_move_constructible::value, "get_value_or: T must be move constructible"); static_assert(std::is_convertible::value, "get_value_or: U must be convertible to T"); return static_cast(*this) ? std::move(**this) : static_cast(std::forward(default_value)); } #ifdef _MSC_VER #pragma warning(pop) #endif // _MSC_VER const T* operator->() const { return std::addressof(this->value_); } T* operator->() { return std::addressof(this->value_); } JSONCONS_CONSTEXPR const T& operator*() const& { return value(); } T& operator*() & { return value(); } void reset() noexcept { destroy(); } void swap(optional& other) noexcept(std::is_nothrow_move_constructible::value /*&& std::is_nothrow_swappable::value*/) { const bool contains_a_value = has_value(); if (contains_a_value == other.has_value()) { if (contains_a_value) { using std::swap; swap(**this, *other); } } else { optional& source = contains_a_value ? *this : other; optional& target = contains_a_value ? other : *this; target = optional(*source); source.reset(); } } private: constexpr const T& get() const { return this->value_; } T& get() { return this->value_; } template void construct(Args&&... args) { ::new (static_cast(&this->value_)) T(std::forward(args)...); has_value_ = true; } void destroy() noexcept { if (has_value_) { value_.~T(); has_value_ = false; } } template void assign(U&& u) { if (has_value_) { value_ = std::forward(u); } else { construct(std::forward(u)); } } }; template typename std::enable_if::value,void>::type swap(optional& lhs, optional& rhs) noexcept { lhs.swap(rhs); } template constexpr bool operator==(const optional& lhs, const optional& rhs) noexcept { return lhs.has_value() == rhs.has_value() && (!lhs.has_value() || *lhs == *rhs); } template constexpr bool operator!=(const optional& lhs, const optional& rhs) noexcept { return lhs.has_value() != rhs.has_value() || (lhs.has_value() && *lhs != *rhs); } template constexpr bool operator<(const optional& lhs, const optional& rhs) noexcept { return rhs.has_value() && (!lhs.has_value() || *lhs < *rhs); } template constexpr bool operator>(const optional& lhs, const optional& rhs) noexcept { return lhs.has_value() && (!rhs.has_value() || *lhs > *rhs); } template constexpr bool operator<=(const optional& lhs, const optional& rhs) noexcept { return !lhs.has_value() || (rhs.has_value() && *lhs <= *rhs); } template constexpr bool operator>=(const optional& lhs, const optional& rhs) noexcept { return !rhs.has_value() || (lhs.has_value() && *lhs >= *rhs); } template constexpr bool operator==(const optional& lhs, const T2& rhs) noexcept { return lhs ? *lhs == rhs : false; } template constexpr bool operator==(const T1& lhs, const optional& rhs) noexcept { return rhs ? lhs == *rhs : false; } template constexpr bool operator!=(const optional& lhs, const T2& rhs) noexcept { return lhs ? *lhs != rhs : true; } template constexpr bool operator!=(const T1& lhs, const optional& rhs) noexcept { return rhs ? lhs != *rhs : true; } template constexpr bool operator<(const optional& lhs, const T2& rhs) noexcept { return lhs ? *lhs < rhs : true; } template constexpr bool operator<(const T1& lhs, const optional& rhs) noexcept { return rhs ? lhs < *rhs : false; } template constexpr bool operator<=(const optional& lhs, const T2& rhs) noexcept { return lhs ? *lhs <= rhs : true; } template constexpr bool operator<=(const T1& lhs, const optional& rhs) noexcept { return rhs ? lhs <= *rhs : false; } template constexpr bool operator>(const optional& lhs, const T2& rhs) noexcept { return lhs ? *lhs > rhs : false; } template constexpr bool operator>(const T1& lhs, const optional& rhs) noexcept { return rhs ? lhs > *rhs : true; } template constexpr bool operator>=(const optional& lhs, const T2& rhs) noexcept { return lhs ? *lhs >= rhs : false; } template constexpr bool operator>=(const T1& lhs, const optional& rhs) noexcept { return rhs ? lhs >= *rhs : true; } } // namespace detail } // namespace jsoncons #endif // JSONCONS_DETAIL_OPTIONAL_HPP jsoncons-1.3.2/include/jsoncons/detail/parse_number.hpp000066400000000000000000001007461477700171100233020ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_DETAIL_PARSE_NUMBER_HPP #define JSONCONS_DETAIL_PARSE_NUMBER_HPP #include #include #include #include #include #include #include #include // std::enable_if #include #include #include #include #include namespace jsoncons { namespace detail { enum class to_integer_errc : uint8_t {success=0, overflow, invalid_digit, invalid_number}; class to_integer_error_category_impl : public std::error_category { public: const char* name() const noexcept override { return "jsoncons/to_integer_unchecked"; } std::string message(int ev) const override { switch (static_cast(ev)) { case to_integer_errc::overflow: return "Integer overflow"; case to_integer_errc::invalid_digit: return "Invalid digit"; case to_integer_errc::invalid_number: return "Invalid number"; default: return "Unknown to_integer_unchecked error"; } } }; inline const std::error_category& to_integer_error_category() { static to_integer_error_category_impl instance; return instance; } inline std::error_code make_error_code(to_integer_errc e) { return std::error_code(static_cast(e),to_integer_error_category()); } } // namespace detail } // namespace jsoncons namespace std { template<> struct is_error_code_enum : public true_type { }; } // namespace std namespace jsoncons { namespace detail { template struct to_integer_result { const CharT* ptr; to_integer_errc ec; constexpr to_integer_result(const CharT* ptr_) : ptr(ptr_), ec(to_integer_errc()) { } constexpr to_integer_result(const CharT* ptr_, to_integer_errc ec_) : ptr(ptr_), ec(ec_) { } to_integer_result(const to_integer_result&) = default; to_integer_result& operator=(const to_integer_result&) = default; constexpr explicit operator bool() const noexcept { return ec == to_integer_errc(); } std::error_code error_code() const { return make_error_code(ec); } }; enum class integer_chars_format : uint8_t {decimal=1,hex}; enum class integer_chars_state {initial,minus,integer,binary,octal,decimal,base16}; template bool is_base10(const CharT* s, std::size_t length) { integer_chars_state state = integer_chars_state::initial; const CharT* end = s + length; for (;s < end; ++s) { switch(state) { case integer_chars_state::initial: { switch(*s) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': state = integer_chars_state::decimal; break; case '-': state = integer_chars_state::minus; break; default: return false; } break; } case integer_chars_state::minus: { switch(*s) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': state = integer_chars_state::decimal; break; default: return false; } break; } case integer_chars_state::decimal: { switch(*s) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': break; default: return false; } break; } default: break; } } return state == integer_chars_state::decimal ? true : false; } template bool is_base16(const CharT* s, std::size_t length) { integer_chars_state state = integer_chars_state::initial; const CharT* end = s + length; for (;s < end; ++s) { switch(state) { case integer_chars_state::initial: { switch(*s) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': // Must be base16 case 'a':case 'b':case 'c':case 'd':case 'e':case 'f': case 'A':case 'B':case 'C':case 'D':case 'E':case 'F': state = integer_chars_state::base16; break; default: return false; } break; } case integer_chars_state::base16: { switch(*s) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': // Must be base16 case 'a':case 'b':case 'c':case 'd':case 'e':case 'f': case 'A':case 'B':case 'C':case 'D':case 'E':case 'F': state = integer_chars_state::base16; break; default: return false; } break; } default: break; } } return state == integer_chars_state::base16 ? true : false; } template typename std::enable_if::is_specialized && !extension_traits::integer_limits::is_signed,to_integer_result>::type decimal_to_integer(const CharT* s, std::size_t length, T& n) { n = 0; integer_chars_state state = integer_chars_state::initial; const CharT* end = s + length; while (s < end) { switch(state) { case integer_chars_state::initial: { switch(*s) { case '0': if (++s == end) { return (++s == end) ? to_integer_result(s) : to_integer_result(s, to_integer_errc()); } else { return to_integer_result(s, to_integer_errc::invalid_digit); } case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': // Must be decimal state = integer_chars_state::decimal; break; default: return to_integer_result(s, to_integer_errc::invalid_digit); } break; } case integer_chars_state::decimal: { static constexpr T max_value = (extension_traits::integer_limits::max)(); static constexpr T max_value_div_10 = max_value / 10; for (; s < end; ++s) { T x = 0; switch(*s) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': x = static_cast(*s) - static_cast('0'); break; default: return to_integer_result(s, to_integer_errc::invalid_digit); } if (n > max_value_div_10) { return to_integer_result(s, to_integer_errc::overflow); } n = n * 10; if (n > max_value - x) { return to_integer_result(s, to_integer_errc::overflow); } n += x; } break; } default: JSONCONS_UNREACHABLE(); break; } } return (state == integer_chars_state::initial) ? to_integer_result(s, to_integer_errc::invalid_number) : to_integer_result(s, to_integer_errc()); } template typename std::enable_if::is_specialized && extension_traits::integer_limits::is_signed,to_integer_result>::type decimal_to_integer(const CharT* s, std::size_t length, T& n) { n = 0; if (length == 0) { return to_integer_result(s, to_integer_errc::invalid_number); } bool is_negative = *s == '-' ? true : false; if (is_negative) { ++s; --length; } using U = typename extension_traits::make_unsigned::type; U u; auto ru = decimal_to_integer(s, length, u); if (ru.ec != to_integer_errc()) { return to_integer_result(ru.ptr, ru.ec); } if (is_negative) { if (u > static_cast(-((extension_traits::integer_limits::lowest)()+T(1))) + U(1)) { return to_integer_result(ru.ptr, to_integer_errc::overflow); } else { n = static_cast(U(0) - u); return to_integer_result(ru.ptr, to_integer_errc()); } } else { if (u > static_cast((extension_traits::integer_limits::max)())) { return to_integer_result(ru.ptr, to_integer_errc::overflow); } else { n = static_cast(u); return to_integer_result(ru.ptr, to_integer_errc()); } } } template typename std::enable_if::is_specialized && !extension_traits::integer_limits::is_signed,to_integer_result>::type to_integer(const CharT* s, std::size_t length, T& n) { n = 0; integer_chars_state state = integer_chars_state::initial; const CharT* end = s + length; while (s < end) { switch(state) { case integer_chars_state::initial: { switch(*s) { case '0': state = integer_chars_state::integer; // Could be binary, octal, hex ++s; break; case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': // Must be decimal state = integer_chars_state::decimal; break; default: return to_integer_result(s, to_integer_errc::invalid_digit); } break; } case integer_chars_state::integer: { switch(*s) { case 'b':case 'B': { state = integer_chars_state::binary; ++s; break; } case 'x':case 'X': { state = integer_chars_state::base16; ++s; break; } case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': { state = integer_chars_state::octal; break; } default: return to_integer_result(s, to_integer_errc::invalid_digit); } break; } case integer_chars_state::binary: { static constexpr T max_value = (extension_traits::integer_limits::max)(); static constexpr T max_value_div_2 = max_value / 2; for (; s < end; ++s) { T x = 0; switch(*s) { case '0':case '1': x = static_cast(*s) - static_cast('0'); break; default: return to_integer_result(s, to_integer_errc::invalid_digit); } if (n > max_value_div_2) { return to_integer_result(s, to_integer_errc::overflow); } n = n * 2; if (n > max_value - x) { return to_integer_result(s, to_integer_errc::overflow); } n += x; } break; } case integer_chars_state::octal: { static constexpr T max_value = (extension_traits::integer_limits::max)(); static constexpr T max_value_div_8 = max_value / 8; for (; s < end; ++s) { T x = 0; switch(*s) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7': x = static_cast(*s) - static_cast('0'); break; default: return to_integer_result(s, to_integer_errc::invalid_digit); } if (n > max_value_div_8) { return to_integer_result(s, to_integer_errc::overflow); } n = n * 8; if (n > max_value - x) { return to_integer_result(s, to_integer_errc::overflow); } n += x; } break; } case integer_chars_state::decimal: { static constexpr T max_value = (extension_traits::integer_limits::max)(); static constexpr T max_value_div_10 = max_value / 10; for (; s < end; ++s) { T x = 0; switch(*s) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': x = static_cast(*s) - static_cast('0'); break; default: return to_integer_result(s, to_integer_errc::invalid_digit); } if (n > max_value_div_10) { return to_integer_result(s, to_integer_errc::overflow); } n = n * 10; if (n > max_value - x) { return to_integer_result(s, to_integer_errc::overflow); } n += x; } break; } case integer_chars_state::base16: { static constexpr T max_value = (extension_traits::integer_limits::max)(); static constexpr T max_value_div_16 = max_value / 16; for (; s < end; ++s) { CharT c = *s; T x = 0; switch (c) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': x = c - '0'; break; case 'a':case 'b':case 'c':case 'd':case 'e':case 'f': x = c - ('a' - 10); break; case 'A':case 'B':case 'C':case 'D':case 'E':case 'F': x = c - ('A' - 10); break; default: return to_integer_result(s, to_integer_errc::invalid_digit); } if (n > max_value_div_16) { return to_integer_result(s, to_integer_errc::overflow); } n = n * 16; if (n > max_value - x) { return to_integer_result(s, to_integer_errc::overflow); } n += x; } break; } default: JSONCONS_UNREACHABLE(); break; } } return (state == integer_chars_state::initial) ? to_integer_result(s, to_integer_errc::invalid_number) : to_integer_result(s, to_integer_errc()); } template typename std::enable_if::is_specialized && extension_traits::integer_limits::is_signed,to_integer_result>::type to_integer(const CharT* s, std::size_t length, T& n) { n = 0; if (length == 0) { return to_integer_result(s, to_integer_errc::invalid_number); } bool is_negative = *s == '-' ? true : false; if (is_negative) { ++s; --length; } using U = typename extension_traits::make_unsigned::type; U u; auto ru = to_integer(s, length, u); if (ru.ec != to_integer_errc()) { return to_integer_result(ru.ptr, ru.ec); } if (is_negative) { if (u > static_cast(-((extension_traits::integer_limits::lowest)()+T(1))) + U(1)) { return to_integer_result(ru.ptr, to_integer_errc::overflow); } else { n = static_cast(U(0) - u); return to_integer_result(ru.ptr, to_integer_errc()); } } else { if (u > static_cast((extension_traits::integer_limits::max)())) { return to_integer_result(ru.ptr, to_integer_errc::overflow); } else { n = static_cast(u); return to_integer_result(ru.ptr, to_integer_errc()); } } } template typename std::enable_if::is_specialized,to_integer_result>::type to_integer(const CharT* s, T& n) { return to_integer(s, std::char_traits::length(s), n); } // Precondition: s satisfies // digit // digit1-digits // - digit // - digit1-digits template typename std::enable_if::is_specialized && !extension_traits::integer_limits::is_signed,to_integer_result>::type to_integer_unchecked(const CharT* s, std::size_t length, T& n) { static_assert(extension_traits::integer_limits::is_specialized, "Integer type not specialized"); JSONCONS_ASSERT(length > 0); n = 0; const CharT* end = s + length; if (*s == '-') { static constexpr T min_value = (extension_traits::integer_limits::lowest)(); static constexpr T min_value_div_10 = min_value / 10; ++s; for (; s < end; ++s) { T x = (T)*s - (T)('0'); if (n < min_value_div_10) { return to_integer_result(s, to_integer_errc::overflow); } n = n * 10; if (n < min_value + x) { return to_integer_result(s, to_integer_errc::overflow); } n -= x; } } else { static constexpr T max_value = (extension_traits::integer_limits::max)(); static constexpr T max_value_div_10 = max_value / 10; for (; s < end; ++s) { T x = static_cast(*s) - static_cast('0'); if (n > max_value_div_10) { return to_integer_result(s, to_integer_errc::overflow); } n = n * 10; if (n > max_value - x) { return to_integer_result(s, to_integer_errc::overflow); } n += x; } } return to_integer_result(s, to_integer_errc()); } // Precondition: s satisfies // digit // digit1-digits // - digit // - digit1-digits template typename std::enable_if::is_specialized && extension_traits::integer_limits::is_signed,to_integer_result>::type to_integer_unchecked(const CharT* s, std::size_t length, T& n) { static_assert(extension_traits::integer_limits::is_specialized, "Integer type not specialized"); JSONCONS_ASSERT(length > 0); n = 0; const CharT* end = s + length; if (*s == '-') { static constexpr T min_value = (extension_traits::integer_limits::lowest)(); static constexpr T min_value_div_10 = min_value / 10; ++s; for (; s < end; ++s) { T x = (T)*s - (T)('0'); if (n < min_value_div_10) { return to_integer_result(s, to_integer_errc::overflow); } n = n * 10; if (n < min_value + x) { return to_integer_result(s, to_integer_errc::overflow); } n -= x; } } else { static constexpr T max_value = (extension_traits::integer_limits::max)(); static constexpr T max_value_div_10 = max_value / 10; for (; s < end; ++s) { T x = static_cast(*s) - static_cast('0'); if (n > max_value_div_10) { return to_integer_result(s, to_integer_errc::overflow); } n = n * 10; if (n > max_value - x) { return to_integer_result(s, to_integer_errc::overflow); } n += x; } } return to_integer_result(s, to_integer_errc()); } // hex_to_integer template typename std::enable_if::is_specialized && extension_traits::integer_limits::is_signed,to_integer_result>::type hex_to_integer(const CharT* s, std::size_t length, T& n) { static_assert(extension_traits::integer_limits::is_specialized, "Integer type not specialized"); JSONCONS_ASSERT(length > 0); n = 0; const CharT* end = s + length; if (*s == '-') { static constexpr T min_value = (extension_traits::integer_limits::lowest)(); static constexpr T min_value_div_16 = min_value / 16; ++s; for (; s < end; ++s) { CharT c = *s; T x = 0; switch (c) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': x = c - '0'; break; case 'a':case 'b':case 'c':case 'd':case 'e':case 'f': x = c - ('a' - 10); break; case 'A':case 'B':case 'C':case 'D':case 'E':case 'F': x = c - ('A' - 10); break; default: return to_integer_result(s, to_integer_errc::invalid_digit); } if (n < min_value_div_16) { return to_integer_result(s, to_integer_errc::overflow); } n = n * 16; if (n < min_value + x) { return to_integer_result(s, to_integer_errc::overflow); } n -= x; } } else { static constexpr T max_value = (extension_traits::integer_limits::max)(); static constexpr T max_value_div_16 = max_value / 16; for (; s < end; ++s) { CharT c = *s; T x = 0; switch (c) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': x = c - '0'; break; case 'a':case 'b':case 'c':case 'd':case 'e':case 'f': x = c - ('a' - 10); break; case 'A':case 'B':case 'C':case 'D':case 'E':case 'F': x = c - ('A' - 10); break; default: return to_integer_result(s, to_integer_errc::invalid_digit); } if (n > max_value_div_16) { return to_integer_result(s, to_integer_errc::overflow); } n = n * 16; if (n > max_value - x) { return to_integer_result(s, to_integer_errc::overflow); } n += x; } } return to_integer_result(s, to_integer_errc()); } template typename std::enable_if::is_specialized && !extension_traits::integer_limits::is_signed,to_integer_result>::type hex_to_integer(const CharT* s, std::size_t length, T& n) { static_assert(extension_traits::integer_limits::is_specialized, "Integer type not specialized"); JSONCONS_ASSERT(length > 0); n = 0; const CharT* end = s + length; static constexpr T max_value = (extension_traits::integer_limits::max)(); static constexpr T max_value_div_16 = max_value / 16; for (; s < end; ++s) { CharT c = *s; T x = *s; switch (c) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': x = c - '0'; break; case 'a':case 'b':case 'c':case 'd':case 'e':case 'f': x = c - ('a' - 10); break; case 'A':case 'B':case 'C':case 'D':case 'E':case 'F': x = c - ('A' - 10); break; default: return to_integer_result(s, to_integer_errc::invalid_digit); } if (n > max_value_div_16) { return to_integer_result(s, to_integer_errc::overflow); } n = n * 16; if (n > max_value - x) { return to_integer_result(s, to_integer_errc::overflow); } n += x; } return to_integer_result(s, to_integer_errc()); } #if defined(JSONCONS_HAS_STD_FROM_CHARS) && JSONCONS_HAS_STD_FROM_CHARS class chars_to { public: char get_decimal_point() const { return '.'; } template typename std::enable_if::value,double>::type operator()(const CharT* s, std::size_t len) const { double val = 0; const auto res = std::from_chars(s, s+len, val); if (res.ec != std::errc()) { JSONCONS_THROW(json_runtime_error("Convert chars to double failed")); } return val; } template typename std::enable_if::value,double>::type operator()(const CharT* s, std::size_t len) const { std::string input(len,'0'); for (size_t i = 0; i < len; ++i) { input[i] = static_cast(s[i]); } double val = 0; const auto res = std::from_chars(input.data(), input.data() + len, val); if (res.ec != std::errc()) { JSONCONS_THROW(json_runtime_error("Convert chars to double failed")); } return val; } }; #elif defined(JSONCONS_HAS_MSC_STRTOD_L) class chars_to { private: _locale_t locale_; public: chars_to() { locale_ = _create_locale(LC_NUMERIC, "C"); } ~chars_to() noexcept { _free_locale(locale_); } chars_to(const chars_to&) { locale_ = _create_locale(LC_NUMERIC, "C"); } chars_to& operator=(const chars_to&) { // Don't assign locale return *this; } char get_decimal_point() const { return '.'; } template typename std::enable_if::value,double>::type operator()(const CharT* s, std::size_t) const { CharT *end = nullptr; double val = _strtod_l(s, &end, locale_); if (s == end) { JSONCONS_THROW(json_runtime_error("Convert string to double failed")); } return val; } template typename std::enable_if::value,double>::type operator()(const CharT* s, std::size_t) const { CharT *end = nullptr; double val = _wcstod_l(s, &end, locale_); if (s == end) { JSONCONS_THROW(json_runtime_error("Convert string to double failed")); } return val; } }; #elif defined(JSONCONS_HAS_STRTOLD_L) class chars_to { private: locale_t locale_; public: chars_to() { locale_ = newlocale(LC_ALL_MASK, "C", (locale_t) 0); } ~chars_to() noexcept { freelocale(locale_); } chars_to(const chars_to&) { locale_ = newlocale(LC_ALL_MASK, "C", (locale_t) 0); } chars_to& operator=(const chars_to&) { return *this; } char get_decimal_point() const { return '.'; } template typename std::enable_if::value,double>::type operator()(const CharT* s, std::size_t) const { char *end = nullptr; double val = strtold_l(s, &end, locale_); if (s == end) { JSONCONS_THROW(json_runtime_error("Convert string to double failed")); } return val; } template typename std::enable_if::value,double>::type operator()(const CharT* s, std::size_t) const { CharT *end = nullptr; double val = wcstold_l(s, &end, locale_); if (s == end) { JSONCONS_THROW(json_runtime_error("Convert string to double failed")); } return val; } }; #else class chars_to { private: std::vector buffer_; char decimal_point_; public: chars_to() : buffer_() { struct lconv * lc = localeconv(); if (lc != nullptr && lc->decimal_point[0] != 0) { decimal_point_ = lc->decimal_point[0]; } else { decimal_point_ = '.'; } buffer_.reserve(100); } chars_to(const chars_to&) = default; chars_to& operator=(const chars_to&) = default; char get_decimal_point() const { return decimal_point_; } template typename std::enable_if::value,double>::type operator()(const CharT* s, std::size_t /*length*/) const { CharT *end = nullptr; double val = strtod(s, &end); if (s == end) { JSONCONS_THROW(json_runtime_error("Convert string to double failed")); } return val; } template typename std::enable_if::value,double>::type operator()(const CharT* s, std::size_t /*length*/) const { CharT *end = nullptr; double val = wcstod(s, &end); if (s == end) { JSONCONS_THROW(json_runtime_error("Convert string to double failed")); } return val; } }; #endif } // namespace detail } // namespace jsoncons #endif // JSONCONS_DETAIL_PARSE_NUMBER_HPP jsoncons-1.3.2/include/jsoncons/detail/span.hpp000066400000000000000000000135311477700171100215540ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_DETAIL_SPAN_HPP #define JSONCONS_DETAIL_SPAN_HPP #include #include #include #include #include // std::addressof #include // std::enable_if, std::true_type, std::false_type #include namespace jsoncons { namespace detail { constexpr std::size_t dynamic_extent = (std::numeric_limits::max)(); template< typename T, std::size_t Extent = dynamic_extent> class span; template struct is_span : std::false_type{}; template< typename T> struct is_span> : std::true_type{}; template< typename T, std::size_t Extent > class span { public: using element_type = T; using value_type = typename std::remove_const::type; using size_type = std::size_t; using difference_type = std::ptrdiff_t; using pointer = T*; using const_pointer = const T*; using reference = T&; using const_reference = const T&; using iterator = pointer; using const_iterator = const_pointer; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; private: pointer data_{nullptr}; size_type size_{0}; public: static constexpr std::size_t extent = Extent; constexpr span() noexcept { } constexpr span(pointer data, size_type size) : data_(data), size_(size) { } template constexpr span(C& c, typename std::enable_if::value && !extension_traits::is_std_array::value && extension_traits::is_compatible_element::value && extension_traits::has_data_and_size::value>::type* = 0) : data_(c.data()), size_(c.size()) { } template span(element_type (&arr)[N]) noexcept : data_(std::addressof(arr[0])), size_(N) { } template span(std::array& arr, typename std::enable_if<(extent == dynamic_extent || extent == N)>::type* = 0) noexcept : data_(arr.data()), size_(arr.size()) { } template span(const std::array& arr, typename std::enable_if<(extent == dynamic_extent || extent == N)>::type* = 0) noexcept : data_(arr.data()), size_(arr.size()) { } template constexpr span(const C& c, typename std::enable_if::value && !extension_traits::is_std_array::value && extension_traits::is_compatible_element::value && extension_traits::has_data_and_size::value>::type* = 0) : data_(c.data()), size_(c.size()) { } template constexpr span(const span& s, typename std::enable_if<(N == dynamic_extent || N == extent) && std::is_convertible::value>::type* = 0) noexcept : data_(s.data()), size_(s.size()) { } constexpr span(const span& other) = default; span& operator=( const span& other ) = default; constexpr pointer data() const noexcept { return data_; } constexpr size_type size() const noexcept { return size_; } constexpr bool empty() const noexcept { return size_ == 0; } constexpr reference operator[](size_type index) const { return data_[index]; } // iterator support const_iterator begin() const noexcept { return data_; } const_iterator end() const noexcept { return data_ + size_; } const_iterator cbegin() const noexcept { return data_; } const_iterator cend() const noexcept { return data_ + size_; } const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } span first(std::size_t count) const { JSONCONS_ASSERT(count <= size()); return span< element_type, dynamic_extent >( data(), count ); } span last(std::size_t count) const { JSONCONS_ASSERT(count <= size()); return span(data() + ( size() - count ), count); } span subspan(std::size_t offset, std::size_t count = dynamic_extent) const { //JSONCONS_ASSERT((offset <= size() && (count == dynamic_extent || (offset + count <= size())))); return span( data() + offset, count == dynamic_extent ? size() - offset : count ); } }; } // namespace detail } // namespace jsoncons #endif // JSONCONS_DETAIL_SPAN_HPP jsoncons-1.3.2/include/jsoncons/detail/string_view.hpp000066400000000000000000000442531477700171100231600ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_DETAIL_STRING_VIEW_HPP #define JSONCONS_DETAIL_STRING_VIEW_HPP #include // std::find, std::min, std::reverse #include #include #include #include #include #include #include #include namespace jsoncons { namespace detail { template > class basic_string_view { private: const CharT* data_{nullptr}; std::size_t length_{0}; public: using value_type = CharT; using const_reference = const CharT&; using traits_type = Traits; using size_type = std::size_t; static constexpr size_type npos = size_type(-1); using const_iterator = const CharT*; using iterator = const CharT*; using const_reverse_iterator = std::reverse_iterator; constexpr basic_string_view() noexcept = default; constexpr basic_string_view(const CharT* data, std::size_t length) : data_(data), length_(length) { } basic_string_view(const CharT* data) : data_(data), length_(Traits::length(data)) { } constexpr basic_string_view(const basic_string_view& other) = default; template JSONCONS_CPP14_CONSTEXPR basic_string_view(const std::basic_string& s) noexcept : data_(s.data()), length_(s.length()) { } ~basic_string_view() = default; JSONCONS_CPP14_CONSTEXPR basic_string_view& operator=( const basic_string_view& view ) noexcept { data_ = view.data(); length_ = view.length(); return *this; } template explicit operator std::basic_string() const { return std::basic_string(data_,length_); } // iterator support const_iterator begin() const noexcept { return data_; } const_iterator end() const noexcept { return data_ + length_; } const_iterator cbegin() const noexcept { return data_; } const_iterator cend() const noexcept { return data_ + length_; } const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } // capacity std::size_t size() const { return length_; } std::size_t length() const { return length_; } size_type max_size() const noexcept { return length_; } bool empty() const noexcept { return length_ == 0; } // element access const_reference operator[](size_type pos) const { return data_[pos]; } const_reference at(std::size_t pos) const { if (pos >= length_) { JSONCONS_THROW(std::out_of_range("pos exceeds length")); } return data_[pos]; } const_reference front() const { return data_[0]; } const_reference back() const { return data_[length_-1]; } const CharT* data() const { return data_; } // string operations basic_string_view substr(size_type pos, size_type n=npos) const { if (pos > length_) { JSONCONS_THROW(std::out_of_range("pos exceeds size")); } if (n == npos || pos + n > length_) { n = length_ - pos; } return basic_string_view(data_ + pos, n); } int compare(const basic_string_view& s) const noexcept { const int rc = Traits::compare(data_, s.data_, (std::min)(length_, s.length_)); return rc != 0 ? rc : (length_ == s.length_ ? 0 : length_ < s.length_ ? -1 : 1); } int compare(const CharT* data) const noexcept { const size_t length = Traits::length(data); const int rc = Traits::compare(data_, data, (std::min)(length_, length)); return rc != 0 ? rc : (length_ == length? 0 : length_ < length? -1 : 1); } template int compare(const std::basic_string& s) const noexcept { const int rc = Traits::compare(data_, s.data(), (std::min)(length_, s.length())); return rc != 0 ? rc : (length_ == s.length() ? 0 : length_ < s.length() ? -1 : 1); } size_type find(basic_string_view s, size_type pos = 0) const noexcept { if (pos > length_) { return npos; } if (s.length_ == 0) { return pos; } const_iterator it = std::search(cbegin() + pos, cend(), s.cbegin(), s.cend(), Traits::eq); return it == cend() ? npos : std::distance(cbegin(), it); } size_type find(CharT ch, size_type pos = 0) const noexcept { return find(basic_string_view(&ch, 1), pos); } size_type find(const CharT* s, size_type pos, size_type n) const noexcept { return find(basic_string_view(s, n), pos); } size_type find(const CharT* s, size_type pos = 0) const noexcept { return find(basic_string_view(s), pos); } size_type rfind(basic_string_view s, size_type pos = npos) const noexcept { if (length_ < s.length_) { return npos; } if (pos > length_ - s.length_) { pos = length_ - s.length_; } if (s.length_ == 0) { return pos; } for (const CharT* p = data_ + pos; true; --p) { if (Traits::compare(p, s.data_, s.length_) == 0) { return p - data_; } if (p == data_) { return npos; } }; } size_type rfind(CharT ch, size_type pos = npos) const noexcept { return rfind(basic_string_view(&ch, 1), pos); } size_type rfind(const CharT* s, size_type pos, size_type n) const noexcept { return rfind(basic_string_view(s, n), pos); } size_type rfind(const CharT* s, size_type pos = npos) const noexcept { return rfind(basic_string_view(s), pos); } size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept { if (pos >= length_ || s.length_ == 0) { return npos; } const_iterator it = std::find_first_of (cbegin() + pos, cend(), s.cbegin(), s.cend(), Traits::eq); return it == cend() ? npos : std::distance (cbegin(), it); } size_type find_first_of(CharT ch, size_type pos = 0) const noexcept { return find_first_of(basic_string_view(&ch, 1), pos); } size_type find_first_of(const CharT* s, size_type pos, size_type n) const noexcept { return find_first_of(basic_string_view(s, n), pos); } size_type find_first_of(const CharT* s, size_type pos = 0) const noexcept { return find_first_of(basic_string_view(s), pos); } size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept { if (s.length_ == 0) { return npos; } if (pos >= length_) { pos = 0; } else { pos = length_ - (pos+1); } const_reverse_iterator it = std::find_first_of (crbegin() + pos, crend(), s.cbegin(), s.cend(), Traits::eq); return it == crend() ? npos : (length_ - 1 - std::distance(crbegin(), it)); } size_type find_last_of(CharT ch, size_type pos = npos) const noexcept { return find_last_of(basic_string_view(&ch, 1), pos); } size_type find_last_of(const CharT* s, size_type pos, size_type n) const noexcept { return find_last_of(basic_string_view(s, n), pos); } size_type find_last_of(const CharT* s, size_type pos = npos) const noexcept { return find_last_of(basic_string_view(s), pos); } size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept { if (pos >= length_) return npos; if (s.length_ == 0) return pos; const_iterator it = cend(); for (auto p = cbegin()+pos; p != cend(); ++p) { if (Traits::find(s.data_, s.length_, *p) == 0) { it = p; break; } } return it == cend() ? npos : std::distance (cbegin(), it); } size_type find_first_not_of(CharT ch, size_type pos = 0) const noexcept { return find_first_not_of(basic_string_view(&ch, 1), pos); } size_type find_first_not_of(const CharT* s, size_type pos, size_type n) const noexcept { return find_first_not_of(basic_string_view(s, n), pos); } size_type find_first_not_of(const CharT* s, size_type pos = 0) const noexcept { return find_first_not_of(basic_string_view(s), pos); } size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept { if (pos >= length_) { pos = length_ - 1; } if (s.length_ == 0) { return pos; } pos = length_ - (pos+1); const_iterator it = crend(); for (auto p = crbegin()+pos; p != crend(); ++p) { if (Traits::find(s.data_, s.length_, *p) == 0) { it = p; break; } } return it == crend() ? npos : (length_ - 1 - std::distance(crbegin(), it)); } size_type find_last_not_of(CharT ch, size_type pos = npos) const noexcept { return find_last_not_of(basic_string_view(&ch, 1), pos); } size_type find_last_not_of(const CharT* s, size_type pos, size_type n) const noexcept { return find_last_not_of(basic_string_view(s, n), pos); } size_type find_last_not_of(const CharT* s, size_type pos = npos) const noexcept { return find_last_not_of(basic_string_view(s), pos); } friend std::basic_ostream& operator<<(std::basic_ostream& os, const basic_string_view& sv) { os.write(sv.data_,sv.length_); return os; } }; // == template bool operator==(const basic_string_view& lhs, const basic_string_view& rhs) noexcept { return lhs.compare(rhs) == 0; } template bool operator==(const basic_string_view& lhs, const std::basic_string& rhs) noexcept { return lhs.compare(rhs) == 0; } template bool operator==(const std::basic_string& lhs, const basic_string_view& rhs) noexcept { return rhs.compare(lhs) == 0; } template bool operator==(const basic_string_view& lhs, const CharT* rhs) noexcept { return lhs.compare(rhs) == 0; } template bool operator==(const CharT* lhs, const basic_string_view& rhs) noexcept { return rhs.compare(lhs) == 0; } // != template bool operator!=(const basic_string_view& lhs, const basic_string_view& rhs) noexcept { return lhs.compare(rhs) != 0; } template bool operator!=(const basic_string_view& lhs, const std::basic_string& rhs) noexcept { return lhs.compare(rhs) != 0; } template bool operator!=(const std::basic_string& lhs, const basic_string_view& rhs) noexcept { return rhs.compare(lhs) != 0; } template bool operator!=(const basic_string_view& lhs, const CharT* rhs) noexcept { return lhs.compare(rhs) != 0; } template bool operator!=(const CharT* lhs, const basic_string_view& rhs) noexcept { return rhs.compare(lhs) != 0; } // <= template bool operator<=(const basic_string_view& lhs, const basic_string_view& rhs) noexcept { return lhs.compare(rhs) <= 0; } template bool operator<=(const basic_string_view& lhs, const std::basic_string& rhs) noexcept { return lhs.compare(rhs) <= 0; } template bool operator<=(const std::basic_string& lhs, const basic_string_view& rhs) noexcept { return rhs.compare(lhs) >= 0; } // < template bool operator<(const basic_string_view& lhs, const basic_string_view& rhs) noexcept { return lhs.compare(rhs) < 0; } template bool operator<(const basic_string_view& lhs, const std::basic_string& rhs) noexcept { return lhs.compare(rhs) < 0; } template bool operator<(const std::basic_string& lhs, const basic_string_view& rhs) noexcept { return rhs.compare(lhs) > 0; } // >= template bool operator>=(const basic_string_view& lhs, const basic_string_view& rhs) noexcept { return lhs.compare(rhs) >= 0; } template bool operator>=(const basic_string_view& lhs, const std::basic_string& rhs) noexcept { return lhs.compare(rhs) >= 0; } template bool operator>=(const std::basic_string& lhs, const basic_string_view& rhs) noexcept { return rhs.compare(lhs) <= 0; } // > template bool operator>(const basic_string_view& lhs, const basic_string_view& rhs) noexcept { return lhs.compare(rhs) > 0; } template bool operator>(const basic_string_view& lhs, const std::basic_string& rhs) noexcept { return lhs.compare(rhs) > 0; } template bool operator>(const std::basic_string& lhs, const basic_string_view& rhs) noexcept { return rhs.compare(lhs) < 0; } using string_view = basic_string_view; using wstring_view = basic_string_view; } // namespace detail } // namespace jsoncons namespace std { template struct hash> { std::size_t operator()(const jsoncons::detail::basic_string_view& s) const noexcept { const int p = 53; const int m = 1000000009; std::size_t hash_value = 0; std::size_t p_pow = 1; for (CharT c : s) { hash_value = (hash_value + (c - 'a' + 1) * p_pow) % m; p_pow = (p_pow * p) % m; } return hash_value; } }; } // namespace std #endif // JSONCONS_DETAIL_STRING_VIEW_HPP jsoncons-1.3.2/include/jsoncons/detail/write_number.hpp000066400000000000000000000412141477700171100233140ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_DETAIL_WRITE_NUMBER_HPP #define JSONCONS_DETAIL_WRITE_NUMBER_HPP #include #include #include #include #include // std::numeric_limits #include #include #include // snprintf #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace detail { inline char to_hex_character(uint8_t c) { return (char)((c < 10) ? ('0' + c) : ('A' - 10 + c)); } // from_integer template typename std::enable_if::value,std::size_t>::type from_integer(Integer value, Result& result) { using char_type = typename Result::value_type; char_type buf[255]; char_type *p = buf; const char_type* last = buf+255; bool is_negative = value < 0; if (value < 0) { do { *p++ = static_cast(48 - (value % 10)); } while ((value /= 10) && (p < last)); } else { do { *p++ = static_cast(48 + value % 10); } while ((value /= 10) && (p < last)); } JSONCONS_ASSERT(p != last); std::size_t count = (p - buf); if (is_negative) { result.push_back('-'); ++count; } while (--p >= buf) { result.push_back(*p); } return count; } // integer_to_hex template typename std::enable_if::value,std::size_t>::type integer_to_hex(Integer value, Result& result) { using char_type = typename Result::value_type; char_type buf[255]; char_type *p = buf; const char_type* last = buf+255; bool is_negative = value < 0; if (value < 0) { do { *p++ = to_hex_character(0-(value % 16)); } while ((value /= 16) && (p < last)); } else { do { *p++ = to_hex_character(value % 16); } while ((value /= 16) && (p < last)); } JSONCONS_ASSERT(p != last); std::size_t count = (p - buf); if (is_negative) { result.push_back('-'); ++count; } while (--p >= buf) { result.push_back(*p); } return count; } // write_double // fast exponent template void fill_exponent(int K, Result& result) { if (K < 0) { result.push_back('-'); K = -K; } else { result.push_back('+'); // compatibility with sprintf } if (K < 10) { result.push_back('0'); // compatibility with sprintf result.push_back((char)('0' + K)); } else if (K < 100) { result.push_back((char)('0' + K / 10)); K %= 10; result.push_back((char)('0' + K)); } else if (K < 1000) { result.push_back((char)('0' + K / 100)); K %= 100; result.push_back((char)('0' + K / 10)); K %= 10; result.push_back((char)('0' + K)); } else { jsoncons::detail::from_integer(K, result); } } template void prettify_string(const char *buffer, std::size_t length, int k, int min_exp, int max_exp, Result& result) { int nb_digits = (int)length; int offset; /* v = buffer * 10^k kk is such that 10^(kk-1) <= v < 10^kk this way kk gives the position of the decimal point. */ int kk = nb_digits + k; if (nb_digits <= kk && kk <= max_exp) { /* the first digits are already in. Add some 0s and call it a day. */ /* the max_exp is a personal choice. Only 16 digits could possibly be relevant. * Basically we want to print 12340000000 rather than 1234.0e7 or 1.234e10 */ for (int i = 0; i < nb_digits; ++i) { result.push_back(buffer[i]); } for (int i = nb_digits; i < kk; ++i) { result.push_back('0'); } result.push_back('.'); result.push_back('0'); } else if (0 < kk && kk <= max_exp) { /* comma number. Just insert a '.' at the correct location. */ for (int i = 0; i < kk; ++i) { result.push_back(buffer[i]); } result.push_back('.'); for (int i = kk; i < nb_digits; ++i) { result.push_back(buffer[i]); } } else if (min_exp < kk && kk <= 0) { offset = 2 - kk; result.push_back('0'); result.push_back('.'); for (int i = 2; i < offset; ++i) result.push_back('0'); for (int i = 0; i < nb_digits; ++i) { result.push_back(buffer[i]); } } else if (nb_digits == 1) { result.push_back(buffer[0]); result.push_back('e'); fill_exponent(kk - 1, result); } else { result.push_back(buffer[0]); result.push_back('.'); for (int i = 1; i < nb_digits; ++i) { result.push_back(buffer[i]); } result.push_back('e'); fill_exponent(kk - 1, result); } } template void dump_buffer(const char *buffer, std::size_t length, char decimal_point, Result& result) { const char *sbeg = buffer; const char *send = sbeg + length; if (sbeg != send) { bool needs_dot = true; for (const char* q = sbeg; q < send; ++q) { switch (*q) { case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '+': result.push_back(*q); break; case 'e': case 'E': result.push_back('e'); needs_dot = false; break; default: if (*q == decimal_point) { needs_dot = false; result.push_back('.'); } break; } } if (needs_dot) { result.push_back('.'); result.push_back('0'); } } } template bool dtoa_scientific(double val, char decimal_point, Result& result) { if (val == 0) { result.push_back('0'); result.push_back('.'); result.push_back('0'); return true; } const jsoncons::detail::chars_to to_double; char buffer[100]; int precision = std::numeric_limits::digits10; int length = snprintf(buffer, sizeof(buffer), "%1.*e", precision, val); if (length < 0) { return false; } if (to_double(buffer, sizeof(buffer)) != val) { const int precision2 = std::numeric_limits::max_digits10; length = snprintf(buffer, sizeof(buffer), "%1.*e", precision2, val); if (length < 0) { return false; } } dump_buffer(buffer, static_cast(length), decimal_point, result); return true; } template bool dtoa_general(double val, char decimal_point, Result& result, std::false_type) { if (val == 0) { result.push_back('0'); result.push_back('.'); result.push_back('0'); return true; } const jsoncons::detail::chars_to to_double; char buffer[100]; int precision = std::numeric_limits::digits10; int length = snprintf(buffer, sizeof(buffer), "%1.*g", precision, val); if (length < 0) { return false; } if (to_double(buffer, sizeof(buffer)) != val) { const int precision2 = std::numeric_limits::max_digits10; length = snprintf(buffer, sizeof(buffer), "%1.*g", precision2, val); if (length < 0) { return false; } } dump_buffer(buffer, length, decimal_point, result); return true; } template bool dtoa_general(double v, char decimal_point, Result& result, std::true_type) { if (v == 0) { result.push_back('0'); result.push_back('.'); result.push_back('0'); return true; } int length = 0; int k; char buffer[100]; double u = std::signbit(v) ? -v : v; if (jsoncons::detail::grisu3(u, buffer, &length, &k)) { if (std::signbit(v)) { result.push_back('-'); } // min exp: -4 is consistent with sprintf // max exp: std::numeric_limits::max_digits10 jsoncons::detail::prettify_string(buffer, length, k, -4, std::numeric_limits::max_digits10, result); return true; } else { return dtoa_general(v, decimal_point, result, std::false_type()); } } template bool dtoa_fixed(double val, char decimal_point, Result& result, std::false_type) { if (val == 0) { result.push_back('0'); result.push_back('.'); result.push_back('0'); return true; } const jsoncons::detail::chars_to to_double; char buffer[100]; int precision = std::numeric_limits::digits10; int length = snprintf(buffer, sizeof(buffer), "%1.*f", precision, val); if (length < 0) { return false; } if (to_double(buffer, sizeof(buffer)) != val) { const int precision2 = std::numeric_limits::max_digits10; length = snprintf(buffer, sizeof(buffer), "%1.*f", precision2, val); if (length < 0) { return false; } } dump_buffer(buffer, length, decimal_point, result); return true; } template bool dtoa_fixed(double v, char decimal_point, Result& result, std::true_type) { if (v == 0) { result.push_back('0'); result.push_back('.'); result.push_back('0'); return true; } int length = 0; int k; char buffer[100]; double u = std::signbit(v) ? -v : v; if (jsoncons::detail::grisu3(u, buffer, &length, &k)) { if (std::signbit(v)) { result.push_back('-'); } jsoncons::detail::prettify_string(buffer, length, k, std::numeric_limits::lowest(), (std::numeric_limits::max)(), result); return true; } else { return dtoa_fixed(v, decimal_point, result, std::false_type()); } } template bool dtoa_fixed(double v, char decimal_point, Result& result) { return dtoa_fixed(v, decimal_point, result, std::integral_constant::is_iec559>()); } template bool dtoa_general(double v, char decimal_point, Result& result) { return dtoa_general(v, decimal_point, result, std::integral_constant::is_iec559>()); } class write_double { private: chars_to to_double_; float_chars_format float_format_; int precision_; char decimal_point_; public: write_double(float_chars_format float_format, int precision) : float_format_(float_format), precision_(precision), decimal_point_('.') { #if !defined(JSONCONS_NO_LOCALECONV) struct lconv *lc = localeconv(); if (lc != nullptr && lc->decimal_point[0] != 0) { decimal_point_ = lc->decimal_point[0]; } #endif } write_double(const write_double&) = default; write_double& operator=(const write_double&) = default; template std::size_t operator()(double val, Result& result) { std::size_t count = 0; char number_buffer[200]; int length = 0; switch (float_format_) { case float_chars_format::fixed: { if (precision_ > 0) { length = snprintf(number_buffer, sizeof(number_buffer), "%1.*f", precision_, val); if (length < 0) { JSONCONS_THROW(json_runtime_error("write_double failed.")); } dump_buffer(number_buffer, length, decimal_point_, result); } else { if (!dtoa_fixed(val, decimal_point_, result)) { JSONCONS_THROW(json_runtime_error("write_double failed.")); } } } break; case float_chars_format::scientific: { if (precision_ > 0) { length = snprintf(number_buffer, sizeof(number_buffer), "%1.*e", precision_, val); if (length < 0) { JSONCONS_THROW(json_runtime_error("write_double failed.")); } dump_buffer(number_buffer, length, decimal_point_, result); } else { if (!dtoa_scientific(val, decimal_point_, result)) { JSONCONS_THROW(json_runtime_error("write_double failed.")); } } } break; case float_chars_format::general: { if (precision_ > 0) { length = snprintf(number_buffer, sizeof(number_buffer), "%1.*g", precision_, val); if (length < 0) { JSONCONS_THROW(json_runtime_error("write_double failed.")); } dump_buffer(number_buffer, length, decimal_point_, result); } else { if (!dtoa_general(val, decimal_point_, result)) { JSONCONS_THROW(json_runtime_error("write_double failed.")); } } break; } default: JSONCONS_THROW(json_runtime_error("write_double failed.")); break; } return count; } }; } // namespace detail } // namespace jsoncons #endif // JSONCONS_DETAIL_WRITE_NUMBER_HPP jsoncons-1.3.2/include/jsoncons/encode_json.hpp000066400000000000000000000256301477700171100216420ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_ENCODE_JSON_HPP #define JSONCONS_ENCODE_JSON_HPP #include #include #include #include #include #include #include namespace jsoncons { // to string template typename std::enable_if::value && extension_traits::is_back_insertable_char_container::value>::type encode_json(const T& val, CharContainer& cont, const basic_json_encode_options& options = basic_json_encode_options(), indenting indent = indenting::no_indent) { using char_type = typename CharContainer::value_type; if (indent == indenting::no_indent) { basic_compact_json_encoder> encoder(cont, options); val.dump(encoder); } else { basic_json_encoder> encoder(cont, options); val.dump(encoder); } } template typename std::enable_if::value && extension_traits::is_back_insertable_char_container::value>::type encode_json(const T& val, CharContainer& cont, const basic_json_encode_options& options = basic_json_encode_options(), indenting indent = indenting::no_indent) { using char_type = typename CharContainer::value_type; if (indent == indenting::no_indent) { basic_compact_json_encoder> encoder(cont, options); encode_json(val, encoder); } else { basic_json_encoder> encoder(cont, options); encode_json(val, encoder); } } // to stream template typename std::enable_if::value>::type encode_json(const T& val, std::basic_ostream& os, const basic_json_encode_options& options = basic_json_encode_options(), indenting indent = indenting::no_indent) { if (indent == indenting::no_indent) { basic_compact_json_encoder encoder(os, options); val.dump(encoder); } else { basic_json_encoder encoder(os, options); val.dump(encoder); } } template typename std::enable_if::value>::type encode_json(const T& val, std::basic_ostream& os, const basic_json_encode_options& options = basic_json_encode_options(), indenting indent = indenting::no_indent) { if (indent == indenting::no_indent) { basic_compact_json_encoder encoder(os, options); encode_json(val, encoder); } else { basic_json_encoder encoder(os, options); encode_json(val, encoder); } } // to string with allocator_set template typename std::enable_if::value && extension_traits::is_back_insertable_char_container::value>::type encode_json(const allocator_set& alloc_set, const T& val, CharContainer& cont, const basic_json_encode_options& options = basic_json_encode_options(), indenting indent = indenting::no_indent) { using char_type = typename CharContainer::value_type; if (indent == indenting::no_indent) { basic_compact_json_encoder,TempAllocator> encoder(cont, options, alloc_set.get_temp_allocator()); val.dump(encoder); } else { basic_json_encoder,TempAllocator> encoder(cont, options, alloc_set.get_temp_allocator()); val.dump(encoder); } } template typename std::enable_if::value && extension_traits::is_back_insertable_char_container::value>::type encode_json(const allocator_set& alloc_set, const T& val, CharContainer& cont, const basic_json_encode_options& options = basic_json_encode_options(), indenting indent = indenting::no_indent) { using char_type = typename CharContainer::value_type; if (indent == indenting::no_indent) { basic_compact_json_encoder,TempAllocator> encoder(cont, options, alloc_set.get_temp_allocator()); encode_json(val, encoder); } else { basic_json_encoder, TempAllocator> encoder(cont, options, alloc_set.get_temp_allocator()); encode_json(val, encoder); } } // to stream with allocator_set template typename std::enable_if::value>::type encode_json(const allocator_set& alloc_set, const T& val, std::basic_ostream& os, const basic_json_encode_options& options = basic_json_encode_options(), indenting indent = indenting::no_indent) { if (indent == indenting::no_indent) { basic_compact_json_encoder encoder(os, options, alloc_set.get_temp_allocator()); val.dump(encoder); } else { basic_json_encoder encoder(os, options, alloc_set.get_temp_allocator()); val.dump(encoder); } } template typename std::enable_if::value>::type encode_json(const allocator_set& alloc_set, const T& val, std::basic_ostream& os, const basic_json_encode_options& options = basic_json_encode_options(), indenting indent = indenting::no_indent) { if (indent == indenting::no_indent) { basic_compact_json_encoder encoder(os, options, alloc_set.get_temp_allocator()); encode_json(val, encoder); } else { basic_json_encoder encoder(os, options, alloc_set.get_temp_allocator()); encode_json(val, encoder); } } // to encoder template void encode_json(const T& val, basic_json_visitor& encoder) { std::error_code ec; encode_traits::encode(val, encoder, basic_json(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } encoder.flush(); } // encode_json_pretty template typename std::enable_if::value && extension_traits::is_back_insertable_char_container::value>::type encode_json_pretty(const T& val, CharContainer& cont, const basic_json_encode_options& options = basic_json_encode_options()) { using char_type = typename CharContainer::value_type; basic_json_encoder> encoder(cont, options); val.dump(encoder); } template typename std::enable_if::value && extension_traits::is_back_insertable_char_container::value>::type encode_json_pretty(const T& val, CharContainer& cont, const basic_json_encode_options& options = basic_json_encode_options()) { using char_type = typename CharContainer::value_type; basic_json_encoder> encoder(cont, options); encode_json(val, encoder); } template typename std::enable_if::value>::type encode_json_pretty(const T& val, std::basic_ostream& os, const basic_json_encode_options& options = basic_json_encode_options()) { basic_json_encoder encoder(os, options); val.dump(encoder); } template typename std::enable_if::value>::type encode_json_pretty(const T& val, std::basic_ostream& os, const basic_json_encode_options& options = basic_json_encode_options()) { basic_json_encoder encoder(os, options); encode_json(val, encoder); } // legacy template void encode_json(const T& val, CharContainer& cont, indenting indent) { if (indent == indenting::indent) { encode_json_pretty(val,cont); } else { encode_json(val,cont); } } template void encode_json(const T& val, std::basic_ostream& os, indenting indent) { if (indent == indenting::indent) { encode_json_pretty(val, os); } else { encode_json(val, os); } } //end legacy } // namespace jsoncons #endif // JSONCONS_ENCODE_JSON_HPP jsoncons-1.3.2/include/jsoncons/encode_traits.hpp000066400000000000000000000333651477700171100222030ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_ENCODE_TRAITS_HPP #define JSONCONS_ENCODE_TRAITS_HPP #include #include #include #include #include #include #include #include // std::enable_if, std::true_type, std::false_type #include #include #include #include #include #include #include #include namespace jsoncons { // encode_traits template struct encode_traits { template static void encode(const T& val, basic_json_visitor& encoder, const Json& proto, std::error_code& ec) { encode(std::integral_constant::is_always_equal::value>(), val, encoder, proto, ec); } private: template static void encode(std::true_type, const T& val, basic_json_visitor& encoder, const Json& /*proto*/, std::error_code& ec) { auto j = json_type_traits::to_json(val); j.dump(encoder, ec); } template static void encode(std::false_type, const T& val, basic_json_visitor& encoder, const Json& proto, std::error_code& ec) { auto j = json_type_traits::to_json(val, proto.get_allocator()); j.dump(encoder, ec); } }; // specializations // bool template struct encode_traits::value >::type> { template static void encode(const T& val, basic_json_visitor& encoder, const Json&, std::error_code& ec) { encoder.bool_value(val,semantic_tag::none,ser_context(),ec); } }; // uint template struct encode_traits::value >::type> { template static void encode(const T& val, basic_json_visitor& encoder, const Json&, std::error_code& ec) { encoder.uint64_value(val,semantic_tag::none,ser_context(),ec); } }; // int template struct encode_traits::value >::type> { template static void encode(const T& val, basic_json_visitor& encoder, const Json&, std::error_code& ec) { encoder.int64_value(val,semantic_tag::none,ser_context(),ec); } }; // float or double template struct encode_traits::value >::type> { template static void encode(const T& val, basic_json_visitor& encoder, const Json&, std::error_code& ec) { encoder.double_value(val,semantic_tag::none,ser_context(),ec); } }; // string template struct encode_traits::value && std::is_same::value >::type> { template static void encode(const T& val, basic_json_visitor& encoder, const Json&, std::error_code& ec) { encoder.string_value(val,semantic_tag::none,ser_context(),ec); } }; template struct encode_traits::value && !std::is_same::value >::type> { template static void encode(const T& val, basic_json_visitor& encoder, const Json&, std::error_code& ec) { std::basic_string s; unicode_traits::convert(val.data(), val.size(), s); encoder.string_value(s,semantic_tag::none,ser_context(),ec); } }; // std::pair template struct encode_traits, CharT> { using value_type = std::pair; template static void encode(const value_type& val, basic_json_visitor& encoder, const Json& proto, std::error_code& ec) { encoder.begin_array(2,semantic_tag::none,ser_context(),ec); if (JSONCONS_UNLIKELY(ec)) {return;} encode_traits::encode(val.first, encoder, proto, ec); if (JSONCONS_UNLIKELY(ec)) {return;} encode_traits::encode(val.second, encoder, proto, ec); if (JSONCONS_UNLIKELY(ec)) {return;} encoder.end_array(ser_context(),ec); } }; // std::tuple namespace detail { template struct json_serialize_tuple_helper { using char_type = typename Json::char_type; using element_type = typename std::tuple_element::type; using next = json_serialize_tuple_helper; static void encode(const Tuple& tuple, basic_json_visitor& encoder, const Json& proto, std::error_code& ec) { encode_traits::encode(std::get(tuple), encoder, proto, ec); if (JSONCONS_UNLIKELY(ec)) {return;} next::encode(tuple, encoder, proto, ec); } }; template struct json_serialize_tuple_helper<0, Size, Json, Tuple> { using char_type = typename Json::char_type; static void encode(const Tuple&, basic_json_visitor&, const Json&, std::error_code&) { } }; } // namespace detail template struct encode_traits, CharT> { using value_type = std::tuple; static constexpr std::size_t size = sizeof...(E); template static void encode(const value_type& val, basic_json_visitor& encoder, const Json& proto, std::error_code& ec) { using helper = jsoncons::detail::json_serialize_tuple_helper>; encoder.begin_array(size,semantic_tag::none,ser_context(),ec); if (JSONCONS_UNLIKELY(ec)) {return;} helper::encode(val, encoder, proto, ec); if (JSONCONS_UNLIKELY(ec)) {return;} encoder.end_array(ser_context(),ec); } }; // vector like template struct encode_traits::value && extension_traits::is_array_like::value && !extension_traits::is_typed_array::value >::type> { using value_type = typename T::value_type; template static void encode(const T& val, basic_json_visitor& encoder, const Json& proto, std::error_code& ec) { encoder.begin_array(val.size(),semantic_tag::none,ser_context(),ec); if (JSONCONS_UNLIKELY(ec)) {return;} for (auto it = std::begin(val); it != std::end(val); ++it) { encode_traits::encode(*it, encoder, proto, ec); if (JSONCONS_UNLIKELY(ec)) {return;} } encoder.end_array(ser_context(), ec); } }; template struct encode_traits::value && extension_traits::is_array_like::value && extension_traits::is_typed_array::value >::type> { using value_type = typename T::value_type; template static void encode(const T& val, basic_json_visitor& encoder, const Json&, std::error_code& ec) { encoder.typed_array(jsoncons::span(val), semantic_tag::none, ser_context(), ec); } }; // std::array template struct encode_traits,CharT> { using value_type = typename std::array::value_type; template static void encode(const std::array& val, basic_json_visitor& encoder, const Json& proto, std::error_code& ec) { encoder.begin_array(val.size(),semantic_tag::none,ser_context(),ec); if (JSONCONS_UNLIKELY(ec)) {return;} for (auto it = std::begin(val); it != std::end(val); ++it) { encode_traits::encode(*it, encoder, proto, ec); if (JSONCONS_UNLIKELY(ec)) {return;} } encoder.end_array(ser_context(),ec); } }; // map like template struct encode_traits::value && extension_traits::is_map_like::value && extension_traits::is_constructible_from_const_pointer_and_size::value >::type> { using mapped_type = typename T::mapped_type; using value_type = typename T::value_type; using key_type = typename T::key_type; template static void encode(const T& val, basic_json_visitor& encoder, const Json& proto, std::error_code& ec) { encoder.begin_object(val.size(), semantic_tag::none, ser_context(), ec); if (JSONCONS_UNLIKELY(ec)) {return;} for (auto it = std::begin(val); it != std::end(val); ++it) { encoder.key((*it).first); encode_traits::encode((*it).second, encoder, proto, ec); if (JSONCONS_UNLIKELY(ec)) {return;} } encoder.end_object(ser_context(), ec); if (JSONCONS_UNLIKELY(ec)) {return;} } }; template struct encode_traits::value && extension_traits::is_map_like::value && std::is_integral::value >::type> { using mapped_type = typename T::mapped_type; using value_type = typename T::value_type; using key_type = typename T::key_type; template static void encode(const T& val, basic_json_visitor& encoder, const Json& proto, std::error_code& ec) { encoder.begin_object(val.size(), semantic_tag::none, ser_context(), ec); if (JSONCONS_UNLIKELY(ec)) {return;} for (auto it = std::begin(val); it != std::end(val); ++it) { std::basic_string s; jsoncons::detail::from_integer((*it).first,s); encoder.key(s); encode_traits::encode((*it).second, encoder, proto, ec); if (JSONCONS_UNLIKELY(ec)) {return;} } encoder.end_object(ser_context(), ec); if (JSONCONS_UNLIKELY(ec)) {return;} } }; } // namespace jsoncons #endif // JSONCONS_ENCODE_TRAITS_HPP jsoncons-1.3.2/include/jsoncons/item_event_visitor.hpp000066400000000000000000002256441477700171100233010ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_ITEM_EVENT_VISITOR_HPP #define JSONCONS_ITEM_EVENT_VISITOR_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { template > class basic_item_event_visitor_to_json_visitor; template class basic_item_event_visitor { template friend class basic_item_event_visitor_to_json_visitor; public: using char_type = CharT; using char_traits_type = std::char_traits; using string_view_type = jsoncons::basic_string_view; basic_item_event_visitor(basic_item_event_visitor&&) = default; basic_item_event_visitor& operator=(basic_item_event_visitor&&) = default; basic_item_event_visitor() = default; virtual ~basic_item_event_visitor() = default; void flush() { visit_flush(); } JSONCONS_VISITOR_RETURN_TYPE begin_object(semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_begin_object(tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE begin_object(std::size_t length, semantic_tag tag=semantic_tag::none, const ser_context& context = ser_context()) { std::error_code ec; visit_begin_object(length, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE end_object(const ser_context& context = ser_context()) { std::error_code ec; visit_end_object(context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE begin_array(semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_begin_array(tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE begin_array(std::size_t length, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_begin_array(length, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE end_array(const ser_context& context=ser_context()) { std::error_code ec; visit_end_array(context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE key(const string_view_type& name, const ser_context& context=ser_context()) { std::error_code ec; visit_string(name, semantic_tag::none, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE null_value(semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_null(tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE bool_value(bool value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_bool(value, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE string_value(const string_view_type& value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_string(value, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } template JSONCONS_VISITOR_RETURN_TYPE byte_string_value(const ByteStringLike& b, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context(), typename std::enable_if::value,int>::type = 0) { std::error_code ec; visit_byte_string(byte_string_view(reinterpret_cast(b.data()),b.size()), tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } template JSONCONS_VISITOR_RETURN_TYPE byte_string_value(const ByteStringLike& b, uint64_t ext_tag, const ser_context& context=ser_context(), typename std::enable_if::value,int>::type = 0) { std::error_code ec; visit_byte_string(byte_string_view(reinterpret_cast(b.data()),b.size()), ext_tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE uint64_value(uint64_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_uint64(value, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE int64_value(int64_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_int64(value, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE half_value(uint16_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_half(value, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE double_value(double value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_double(value, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE begin_object(semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_begin_object(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE begin_object(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_begin_object(length, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE end_object(const ser_context& context, std::error_code& ec) { visit_end_object(context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE begin_array(semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE begin_array(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_begin_array(length, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE end_array(const ser_context& context, std::error_code& ec) { visit_end_array(context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE key(const string_view_type& name, const ser_context& context, std::error_code& ec) { visit_string(name, semantic_tag::none, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE null_value(semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_null(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE bool_value(bool value, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_bool(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE string_value(const string_view_type& value, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_string(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } template JSONCONS_VISITOR_RETURN_TYPE byte_string_value(const Source& b, semantic_tag tag, const ser_context& context, std::error_code& ec, typename std::enable_if::value,int>::type = 0) { visit_byte_string(byte_string_view(reinterpret_cast(b.data()),b.size()), tag, context, ec); JSONCONS_VISITOR_RETURN; } template JSONCONS_VISITOR_RETURN_TYPE byte_string_value(const Source& b, uint64_t ext_tag, const ser_context& context, std::error_code& ec, typename std::enable_if::value,int>::type = 0) { visit_byte_string(byte_string_view(reinterpret_cast(b.data()),b.size()), ext_tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE uint64_value(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_uint64(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE int64_value(int64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_int64(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE half_value(uint16_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_half(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE double_value(double value, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_double(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } template JSONCONS_VISITOR_RETURN_TYPE typed_array(const jsoncons::span& data, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_typed_array(data, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } template JSONCONS_VISITOR_RETURN_TYPE typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_typed_array(data, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE typed_array(half_arg_t, const jsoncons::span& s, semantic_tag tag = semantic_tag::none, const ser_context& context = ser_context()) { std::error_code ec; visit_typed_array(half_arg, s, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE typed_array(half_arg_t, const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_typed_array(half_arg, s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE begin_multi_dim(const jsoncons::span& shape, semantic_tag tag = semantic_tag::multi_dim_row_major, const ser_context& context=ser_context()) { std::error_code ec; visit_begin_multi_dim(shape, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE begin_multi_dim(const jsoncons::span& shape, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_begin_multi_dim(shape, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE end_multi_dim(const ser_context& context=ser_context()) { std::error_code ec; visit_end_multi_dim(context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE end_multi_dim(const ser_context& context, std::error_code& ec) { visit_end_multi_dim(context, ec); JSONCONS_VISITOR_RETURN; } private: virtual void visit_flush() = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(std::size_t /*length*/, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_begin_object(tag, context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context& context, std::error_code& ec) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(std::size_t /*length*/, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context& context, std::error_code& ec) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool value, semantic_tag tag, const ser_context& context, std::error_code&) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& value, semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& value, semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& value, uint64_t /*ext_tag*/, const ser_context& context, std::error_code& ec) { visit_byte_string(value, semantic_tag::none, context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_half(uint16_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_double(binary::decode_half(value), tag, context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_double(double value, semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto p = s.begin(); p != s.end(); ++p) { uint64_value(*p, semantic_tag::none, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto p = s.begin(); p != s.end(); ++p) { uint64_value(*p, semantic_tag::none, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto p = s.begin(); p != s.end(); ++p) { uint64_value(*p, semantic_tag::none, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto p = s.begin(); p != s.end(); ++p) { uint64_value(*p,semantic_tag::none,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto p = s.begin(); p != s.end(); ++p) { int64_value(*p,semantic_tag::none,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto p = s.begin(); p != s.end(); ++p) { int64_value(*p,semantic_tag::none,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto p = s.begin(); p != s.end(); ++p) { int64_value(*p,semantic_tag::none,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto p = s.begin(); p != s.end(); ++p) { int64_value(*p,semantic_tag::none,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(half_arg_t, const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto p = s.begin(); p != s.end(); ++p) { half_value(*p, semantic_tag::none, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto p = s.begin(); p != s.end(); ++p) { double_value(*p,semantic_tag::none,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto p = s.begin(); p != s.end(); ++p) { double_value(*p,semantic_tag::none,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_begin_multi_dim(const jsoncons::span& shape, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_begin_array(2, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} visit_begin_array(shape.size(), tag, context, ec); for (auto it = shape.begin(); it != shape.end(); ++it) { visit_uint64(*it, semantic_tag::none, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } visit_end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_end_multi_dim(const ser_context& context, std::error_code& ec) { visit_end_array(context, ec); JSONCONS_VISITOR_RETURN; } }; template class basic_item_event_visitor_to_json_visitor : public basic_item_event_visitor { public: using typename basic_item_event_visitor::char_type; using typename basic_item_event_visitor::string_view_type; private: using char_allocator_type = typename std::allocator_traits:: template rebind_alloc; using string_type = std::basic_string,char_allocator_type>; enum class container_t {root, array, object}; enum class target_t {destination, buffer}; struct level { private: target_t state_; container_t type_; int even_odd_; std::size_t count_{0}; public: level(target_t state, container_t type) noexcept : state_(state), type_(type), even_odd_(type == container_t::object ? 0 : 1) { } void advance() { if (!is_key()) { ++count_; } if (is_object()) { even_odd_ = !even_odd_; } } bool is_key() const { return even_odd_ == 0; } bool is_object() const { return type_ == container_t::object; } target_t target() const { return state_; } std::size_t count() const { return count_; } }; using level_allocator_type = typename std::allocator_traits:: template rebind_alloc; basic_default_json_visitor default_visitor_; basic_json_visitor* destination_; string_type key_; string_type key_buffer_; std::vector level_stack_; const std::basic_string null_constant = {'n','u','l','l'}; const std::basic_string true_constant = { 't','r','u','e' }; const std::basic_string false_constant = { 'f', 'a', 'l', 's', 'e' }; // noncopyable and nonmoveable basic_item_event_visitor_to_json_visitor(const basic_item_event_visitor_to_json_visitor&) = delete; basic_item_event_visitor_to_json_visitor& operator=(const basic_item_event_visitor_to_json_visitor&) = delete; public: explicit basic_item_event_visitor_to_json_visitor(const Allocator& alloc = Allocator()) : default_visitor_(), destination_(std::addressof(default_visitor_)), key_(alloc), key_buffer_(alloc), level_stack_(alloc) { level_stack_.emplace_back(target_t::destination,container_t::root); // root } explicit basic_item_event_visitor_to_json_visitor(basic_json_visitor& visitor, const Allocator& alloc = Allocator()) : destination_(std::addressof(visitor)), key_(alloc), key_buffer_(alloc), level_stack_(alloc) { level_stack_.emplace_back(target_t::destination,container_t::root); // root } void reset() { key_.clear(); key_buffer_.clear(); level_stack_.clear(); level_stack_.emplace_back(target_t::destination,container_t::root); // root } basic_json_visitor& destination() { return *destination_; } void destination(basic_json_visitor& dest) { destination_ = std::addressof(dest); } private: void visit_flush() override { destination_->flush(); } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (level_stack_.back().is_key()) { if (level_stack_.back().target() == target_t::buffer && level_stack_.back().count() > 0) { key_buffer_.push_back(','); } level_stack_.emplace_back(target_t::buffer, container_t::object); key_buffer_.push_back('{'); } else { switch (level_stack_.back().target()) { case target_t::buffer: level_stack_.emplace_back(target_t::buffer, container_t::object); key_buffer_.push_back('{'); break; default: level_stack_.emplace_back(target_t::destination, container_t::object); destination_->begin_object(tag, context, ec); break; } } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (level_stack_.back().is_key()) { if (level_stack_.back().target() == target_t::buffer && level_stack_.back().count() > 0) { key_buffer_.push_back(','); } level_stack_.emplace_back(target_t::buffer, container_t::object); key_buffer_.push_back('{'); } else { switch (level_stack_.back().target()) { case target_t::buffer: if (!level_stack_.back().is_object() && level_stack_.back().count() > 0) { key_buffer_.push_back(','); } level_stack_.emplace_back(target_t::buffer, container_t::object); key_buffer_.push_back('{'); break; default: level_stack_.emplace_back(target_t::destination, container_t::object); destination_->begin_object(length, tag, context, ec); break; } } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context& context, std::error_code& ec) override { switch (level_stack_.back().target()) { case target_t::buffer: key_buffer_.push_back('}'); JSONCONS_ASSERT(level_stack_.size() > 1); level_stack_.pop_back(); if (level_stack_.back().target() == target_t::destination) { destination_->key(key_buffer_,context, ec); key_buffer_.clear(); } else if (level_stack_.back().is_key()) { key_buffer_.push_back(':'); } level_stack_.back().advance(); break; default: JSONCONS_ASSERT(level_stack_.size() > 1); level_stack_.pop_back(); level_stack_.back().advance(); destination_->end_object(context, ec); break; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (level_stack_.back().is_key()) { if (level_stack_.back().target() == target_t::buffer && level_stack_.back().count() > 0) { key_buffer_.push_back(','); } level_stack_.emplace_back(target_t::buffer, container_t::array); key_buffer_.push_back('['); } else { switch (level_stack_.back().target()) { case target_t::buffer: if (level_stack_.back().is_object() && level_stack_.back().count() > 0) { key_buffer_.push_back(','); } level_stack_.emplace_back(target_t::buffer, container_t::array); key_buffer_.push_back('['); break; default: level_stack_.emplace_back(target_t::destination, container_t::array); destination_->begin_array(tag, context, ec); break; } } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (level_stack_.back().is_key()) { if (level_stack_.back().target() == target_t::buffer && level_stack_.back().count() > 0) { key_buffer_.push_back(','); } level_stack_.emplace_back(target_t::buffer, container_t::array); key_buffer_.push_back('['); } else { switch (level_stack_.back().target()) { case target_t::buffer: if (!level_stack_.back().is_object() && level_stack_.back().count() > 0) { key_buffer_.push_back(','); } level_stack_.emplace_back(target_t::buffer, container_t::array); key_buffer_.push_back('['); break; default: level_stack_.emplace_back(target_t::destination, container_t::array); destination_->begin_array(length, tag, context, ec); break; } } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context& context, std::error_code& ec) override { switch (level_stack_.back().target()) { case target_t::buffer: key_buffer_.push_back(']'); JSONCONS_ASSERT(level_stack_.size() > 1); level_stack_.pop_back(); if (level_stack_.back().target() == target_t::destination) { destination_->key(key_buffer_, context, ec); key_buffer_.clear(); } else if (level_stack_.back().is_key()) { key_buffer_.push_back(':'); } level_stack_.back().advance(); break; default: JSONCONS_ASSERT(level_stack_.size() > 1); level_stack_.pop_back(); level_stack_.back().advance(); destination_->end_array(context, ec); break; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (level_stack_.back().is_key()) { switch (level_stack_.back().target()) { case target_t::buffer: if (level_stack_.back().count() > 0) { key_buffer_.push_back(','); } key_buffer_.push_back('\"'); key_buffer_.insert(key_buffer_.end(), value.begin(), value.end()); key_buffer_.push_back('\"'); key_buffer_.push_back(':'); break; default: destination_->key(value, context, ec); break; } } else { switch (level_stack_.back().target()) { case target_t::buffer: if (!level_stack_.back().is_object() && level_stack_.back().count() > 0) { key_buffer_.push_back(','); } key_buffer_.push_back('\"'); key_buffer_.insert(key_buffer_.end(), value.begin(), value.end()); key_buffer_.push_back('\"'); break; default: destination_->string_value(value, tag, context, ec); break; } } level_stack_.back().advance(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (level_stack_.back().is_key() || level_stack_.back().target() == target_t::buffer) { key_.clear(); switch (tag) { case semantic_tag::base64: encode_base64(value.begin(), value.end(), key_); break; case semantic_tag::base16: encode_base16(value.begin(), value.end(),key_); break; default: encode_base64url(value.begin(), value.end(),key_); break; } } if (level_stack_.back().is_key()) { switch (level_stack_.back().target()) { case target_t::buffer: if (level_stack_.back().count() > 0) { key_buffer_.push_back(','); } key_buffer_.push_back('\"'); key_buffer_.insert(key_buffer_.end(), key_.begin(), key_.end()); key_buffer_.push_back('\"'); key_buffer_.push_back(':'); break; default: destination_->key(key_, context, ec); break; } } else { switch (level_stack_.back().target()) { case target_t::buffer: if (!level_stack_.back().is_object() && level_stack_.back().count() > 0) { key_buffer_.push_back(','); } key_buffer_.push_back('\"'); key_buffer_.insert(key_buffer_.end(), key_.begin(), key_.end()); key_buffer_.push_back('\"'); break; default: destination_->byte_string_value(value, tag, context, ec); break; } } level_stack_.back().advance(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& value, uint64_t ext_tag, const ser_context& context, std::error_code& ec) override { if (level_stack_.back().is_key() || level_stack_.back().target() == target_t::buffer) { key_.clear(); encode_base64url(value.begin(), value.end(),key_); } if (level_stack_.back().is_key()) { switch (level_stack_.back().target()) { case target_t::buffer: if (level_stack_.back().count() > 0) { key_buffer_.push_back(','); } key_buffer_.push_back('\"'); key_buffer_.insert(key_buffer_.end(), key_.begin(), key_.end()); key_buffer_.push_back('\"'); key_buffer_.push_back(':'); break; default: destination_->key(key_, context, ec); break; } } else { switch (level_stack_.back().target()) { case target_t::buffer: if (!level_stack_.back().is_object() && level_stack_.back().count() > 0) { key_buffer_.push_back(','); } key_buffer_.push_back('\"'); key_buffer_.insert(key_buffer_.end(), key_.begin(), key_.end()); key_buffer_.push_back('\"'); break; default: destination_->byte_string_value(value, ext_tag, context, ec); break; } } level_stack_.back().advance(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (level_stack_.back().is_key() || level_stack_.back().target() == target_t::buffer) { key_.clear(); jsoncons::detail::from_integer(value,key_); } if (level_stack_.back().is_key()) { switch (level_stack_.back().target()) { case target_t::buffer: if (level_stack_.back().count() > 0) { key_buffer_.push_back(','); } key_buffer_.insert(key_buffer_.end(), key_.begin(), key_.end()); key_buffer_.push_back(':'); break; default: destination_->key(key_, context, ec); break; } } else { switch (level_stack_.back().target()) { case target_t::buffer: if (!level_stack_.back().is_object() && level_stack_.back().count() > 0) { key_buffer_.push_back(','); } key_buffer_.insert(key_buffer_.end(), key_.begin(), key_.end()); break; default: destination_->uint64_value(value, tag, context, ec); break; } } level_stack_.back().advance(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (level_stack_.back().is_key() || level_stack_.back().target() == target_t::buffer) { key_.clear(); jsoncons::detail::from_integer(value,key_); } if (level_stack_.back().is_key()) { switch (level_stack_.back().target()) { case target_t::buffer: if (level_stack_.back().count() > 0) { key_buffer_.push_back(','); } key_buffer_.insert(key_buffer_.end(), key_.begin(), key_.end()); key_buffer_.push_back(':'); break; default: destination_->key(key_, context, ec); break; } } else { switch (level_stack_.back().target()) { case target_t::buffer: if (!level_stack_.back().is_object() && level_stack_.back().count() > 0) { key_buffer_.push_back(','); } key_buffer_.insert(key_buffer_.end(), key_.begin(), key_.end()); break; default: destination_->int64_value(value, tag, context, ec); break; } } level_stack_.back().advance(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_half(uint16_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (level_stack_.back().is_key() || level_stack_.back().target() == target_t::buffer) { key_.clear(); jsoncons::string_sink sink(key_); jsoncons::detail::write_double f{float_chars_format::general,0}; double x = binary::decode_half(value); f(x, sink); } if (level_stack_.back().is_key()) { switch (level_stack_.back().target()) { case target_t::buffer: if (level_stack_.back().count() > 0) { key_buffer_.push_back(','); } key_buffer_.insert(key_buffer_.end(), key_.begin(), key_.end()); key_buffer_.push_back(':'); break; default: destination_->key(key_, context, ec); break; } } else { switch (level_stack_.back().target()) { case target_t::buffer: if (!level_stack_.back().is_object() && level_stack_.back().count() > 0) { key_buffer_.push_back(','); } key_buffer_.insert(key_buffer_.end(), key_.begin(), key_.end()); break; default: destination_->half_value(value, tag, context, ec); break; } } level_stack_.back().advance(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_double(double value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (level_stack_.back().is_key() || level_stack_.back().target() == target_t::buffer) { key_.clear(); string_sink sink(key_); jsoncons::detail::write_double f{float_chars_format::general,0}; f(value, sink); } if (level_stack_.back().is_key()) { switch (level_stack_.back().target()) { case target_t::buffer: if (level_stack_.back().count() > 0) { key_buffer_.push_back(','); } key_buffer_.insert(key_buffer_.end(), key_.begin(), key_.end()); key_buffer_.push_back(':'); break; default: destination_->key(key_, context, ec); break; } } else { switch (level_stack_.back().target()) { case target_t::buffer: if (!level_stack_.back().is_object() && level_stack_.back().count() > 0) { key_buffer_.push_back(','); } key_buffer_.insert(key_buffer_.end(), key_.begin(), key_.end()); break; default: destination_->double_value(value, tag, context, ec); break; } } level_stack_.back().advance(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (level_stack_.back().is_key() || level_stack_.back().target() == target_t::buffer) { key_.clear(); if (value) { key_.insert(key_.begin(), true_constant.begin(), true_constant.end()); } else { key_.insert(key_.begin(), false_constant.begin(), false_constant.end()); } } if (level_stack_.back().is_key()) { switch (level_stack_.back().target()) { case target_t::buffer: if (level_stack_.back().count() > 0) { key_buffer_.push_back(','); } key_buffer_.insert(key_buffer_.end(), key_.begin(), key_.end()); key_buffer_.push_back(':'); break; default: destination_->key(key_, context, ec); break; } } else { switch (level_stack_.back().target()) { case target_t::buffer: if (!level_stack_.back().is_object() && level_stack_.back().count() > 0) { key_buffer_.push_back(','); } key_buffer_.insert(key_buffer_.end(), key_.begin(), key_.end()); break; default: destination_->bool_value(value, tag, context, ec); break; } } level_stack_.back().advance(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (level_stack_.back().is_key() || level_stack_.back().target() == target_t::buffer) { key_.clear(); key_.insert(key_.begin(), null_constant.begin(), null_constant.end()); } if (level_stack_.back().is_key()) { switch (level_stack_.back().target()) { case target_t::buffer: if (level_stack_.back().count() > 0) { key_buffer_.push_back(','); } key_buffer_.insert(key_buffer_.end(), key_.begin(), key_.end()); key_buffer_.push_back(':'); break; default: destination_->key(key_, context, ec); break; } } else { switch (level_stack_.back().target()) { case target_t::buffer: if (!level_stack_.back().is_object() && level_stack_.back().count() > 0) { key_buffer_.push_back(','); } key_buffer_.insert(key_buffer_.end(), key_.begin(), key_.end()); break; default: destination_->null_value(tag, context, ec); break; } } level_stack_.back().advance(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { bool is_key = level_stack_.back().is_key(); level_stack_.back().advance(); if (is_key || level_stack_.back().target() == target_t::buffer) { basic_item_event_visitor::visit_typed_array(s,tag,context,ec); } else { destination_->typed_array(s, tag, context, ec); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { bool is_key = level_stack_.back().is_key(); level_stack_.back().advance(); if (is_key || level_stack_.back().target() == target_t::buffer) { basic_item_event_visitor::visit_typed_array(s,tag,context,ec); } else { destination_->typed_array(s, tag, context, ec); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { bool is_key = level_stack_.back().is_key(); level_stack_.back().advance(); if (is_key || level_stack_.back().target() == target_t::buffer) { basic_item_event_visitor::visit_typed_array(s,tag,context,ec); } else { destination_->typed_array(s, tag, context, ec); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { bool is_key = level_stack_.back().is_key(); level_stack_.back().advance(); if (is_key || level_stack_.back().target() == target_t::buffer) { basic_item_event_visitor::visit_typed_array(s,tag,context,ec); } else { destination_->typed_array(s, tag, context, ec); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { bool is_key = level_stack_.back().is_key(); level_stack_.back().advance(); if (is_key || level_stack_.back().target() == target_t::buffer) { basic_item_event_visitor::visit_typed_array(s,tag,context,ec); } else { destination_->typed_array(s, tag, context, ec); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { bool is_key = level_stack_.back().is_key(); level_stack_.back().advance(); if (is_key || level_stack_.back().target() == target_t::buffer) { basic_item_event_visitor::visit_typed_array(s,tag,context,ec); } else { destination_->typed_array(s, tag, context, ec); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { bool is_key = level_stack_.back().is_key(); level_stack_.back().advance(); if (is_key || level_stack_.back().target() == target_t::buffer) { basic_item_event_visitor::visit_typed_array(s,tag,context,ec); } else { destination_->typed_array(s, tag, context, ec); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { bool is_key = level_stack_.back().is_key(); level_stack_.back().advance(); if (is_key || level_stack_.back().target() == target_t::buffer) { basic_item_event_visitor::visit_typed_array(s,tag,context,ec); } else { destination_->typed_array(s, tag, context, ec); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(half_arg_t, const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { bool is_key = level_stack_.back().is_key(); level_stack_.back().advance(); if (is_key || level_stack_.back().target() == target_t::buffer) { basic_item_event_visitor::visit_typed_array(half_arg,s,tag,context,ec); } else { destination_->typed_array(half_arg, s, tag, context, ec); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { bool is_key = level_stack_.back().is_key(); level_stack_.back().advance(); if (is_key || level_stack_.back().target() == target_t::buffer) { basic_item_event_visitor::visit_typed_array(s,tag,context,ec); } else { destination_->typed_array(s, tag, context, ec); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { bool is_key = level_stack_.back().is_key(); level_stack_.back().advance(); if (is_key || level_stack_.back().target() == target_t::buffer) { basic_item_event_visitor::visit_typed_array(s,tag,context,ec); } else { destination_->typed_array(s, tag, context, ec); } JSONCONS_VISITOR_RETURN; } }; template class basic_default_item_event_visitor : public basic_item_event_visitor { public: using typename basic_item_event_visitor::string_view_type; basic_default_item_event_visitor() = default; private: void visit_flush() override { } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(std::size_t, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(std::size_t, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type&, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view&, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_half(uint16_t, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_double(double, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } }; // basic_json_visitor_to_item_event_visitor template class basic_json_visitor_to_item_event_visitor : public basic_json_visitor { public: using typename basic_json_visitor::char_type; using typename basic_json_visitor::string_view_type; private: basic_item_event_visitor& destination_; // noncopyable and nonmoveable basic_json_visitor_to_item_event_visitor(const basic_json_visitor_to_item_event_visitor&) = delete; basic_json_visitor_to_item_event_visitor& operator=(const basic_json_visitor_to_item_event_visitor&) = delete; public: basic_json_visitor_to_item_event_visitor(basic_item_event_visitor& visitor) : destination_(visitor) { } basic_item_event_visitor& destination() { destination_; } private: void visit_flush() override { destination_.flush(); } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_.begin_object(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_.begin_object(length, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context& context, std::error_code& ec) override { destination_.end_object(context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_.begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_.begin_array(length, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context& context, std::error_code& ec) override { destination_.end_array(context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type& name, const ser_context& context, std::error_code& ec) override { destination_.visit_string(name, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_.string_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& b, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_.byte_string_value(b, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_.uint64_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_.int64_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_half(uint16_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_.half_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_double(double value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_.double_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_.bool_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_.null_value(tag, context, ec); JSONCONS_VISITOR_RETURN; } }; class diagnostics_visitor2 : public basic_default_item_event_visitor { JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag, const ser_context&, std::error_code&) override { std::cout << "visit_begin_object" << '\n'; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(std::size_t length, semantic_tag, const ser_context&, std::error_code&) override { std::cout << "visit_begin_object " << length << '\n'; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context&, std::error_code&) override { std::cout << "visit_end_object" << '\n'; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag, const ser_context&, std::error_code&) override { std::cout << "visit_begin_array" << '\n'; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(std::size_t length, semantic_tag, const ser_context&, std::error_code&) override { std::cout << "visit_begin_array " << length << '\n'; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context&, std::error_code&) override { std::cout << "visit_end_array" << '\n'; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& s, semantic_tag, const ser_context&, std::error_code&) override { std::cout << "visit_string " << s << '\n'; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t val, semantic_tag, const ser_context&, std::error_code&) override { std::cout << "visit_int64 " << val << '\n'; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t val, semantic_tag, const ser_context&, std::error_code&) override { std::cout << "visit_uint64 " << val << '\n'; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool val, semantic_tag, const ser_context&, std::error_code&) override { std::cout << "visit_bool " << val << '\n'; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag, const ser_context&, std::error_code&) override { std::cout << "visit_null " << '\n'; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context&, std::error_code&) override { std::cout << "visit_typed_array uint16_t " << tag << '\n'; for (auto val : s) { std::cout << val << "" << '\n'; } std::cout << "" << '\n'; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(half_arg_t, const jsoncons::span& s, semantic_tag tag, const ser_context&, std::error_code&) override { std::cout << "visit_typed_array half_arg_t uint16_t " << tag << "" << '\n'; for (auto val : s) { std::cout << val << "" << '\n'; } std::cout << "" << '\n'; JSONCONS_VISITOR_RETURN; } }; using item_event_visitor = basic_item_event_visitor; using default_item_event_visitor = basic_default_item_event_visitor; using item_event_visitor_to_visitor_adaptor = basic_item_event_visitor_to_json_visitor; } // namespace jsoncons #endif // JSONCONS_ITEM_EVENT_VISITOR_HPP jsoncons-1.3.2/include/jsoncons/json.hpp000066400000000000000000000010121477700171100203110ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_JSON_HPP #define JSONCONS_JSON_HPP #include #include #include #include #include #endif // JSONCONS_JSON_HPP jsoncons-1.3.2/include/jsoncons/json_array.hpp000066400000000000000000000226731477700171100215270ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_JSON_ARRAY_HPP #define JSONCONS_JSON_ARRAY_HPP #include // std::sort, std::stable_sort, std::lower_bound, std::unique #include // assert #include #include #include // std::iterator_traits #include // std::allocator #include // std::enable_if #include #include // std::move #include #include #include namespace jsoncons { // json_array template class SequenceContainer = std::vector> class json_array : public allocator_holder { public: using allocator_type = typename Json::allocator_type; using value_type = Json; private: using value_allocator_type = typename std::allocator_traits:: template rebind_alloc; using value_container_type = SequenceContainer; value_container_type elements_; public: using iterator = typename value_container_type::iterator; using const_iterator = typename value_container_type::const_iterator; using reference = typename std::iterator_traits::reference; using const_reference = typename std::iterator_traits::reference; using allocator_holder::get_allocator; json_array() { } explicit json_array(const allocator_type& alloc) : allocator_holder(alloc), elements_(value_allocator_type(alloc)) { } explicit json_array(std::size_t n, const allocator_type& alloc = allocator_type()) : allocator_holder(alloc), elements_(n,Json(),value_allocator_type(alloc)) { } explicit json_array(std::size_t n, const Json& value, const allocator_type& alloc = allocator_type()) : allocator_holder(alloc), elements_(n,value,value_allocator_type(alloc)) { } template json_array(InputIterator begin, InputIterator end, const allocator_type& alloc = allocator_type()) : allocator_holder(alloc), elements_(begin,end,value_allocator_type(alloc)) { } json_array(const json_array& other) : allocator_holder(other.get_allocator()), elements_(other.elements_) { } json_array(const json_array& other, const allocator_type& alloc) : allocator_holder(alloc), elements_(other.elements_,value_allocator_type(alloc)) { } json_array(json_array&& other) noexcept : allocator_holder(other.get_allocator()), elements_(std::move(other.elements_)) { } json_array(json_array&& other, const allocator_type& alloc) : allocator_holder(alloc), elements_(std::move(other.elements_),value_allocator_type(alloc)) { } json_array(const std::initializer_list& init, const allocator_type& alloc = allocator_type()) : allocator_holder(alloc), elements_(init,value_allocator_type(alloc)) { } ~json_array() noexcept { flatten_and_destroy(); } reference back() { return elements_.back(); } const_reference back() const { return elements_.back(); } void pop_back() { elements_.pop_back(); } bool empty() const { return elements_.empty(); } void swap(json_array& other) noexcept { elements_.swap(other.elements_); } std::size_t size() const {return elements_.size();} std::size_t capacity() const {return elements_.capacity();} void clear() {elements_.clear();} void shrink_to_fit() { for (std::size_t i = 0; i < elements_.size(); ++i) { elements_[i].shrink_to_fit(); } elements_.shrink_to_fit(); } void reserve(std::size_t n) {elements_.reserve(n);} void resize(std::size_t n) {elements_.resize(n);} void resize(std::size_t n, const Json& val) {elements_.resize(n,val);} iterator erase(const_iterator pos) { return elements_.erase(pos); } iterator erase(const_iterator first, const_iterator last) { return elements_.erase(first,last); } Json& operator[](std::size_t i) {return elements_[i];} const Json& operator[](std::size_t i) const {return elements_[i];} // push_back template typename std::enable_if::is_always_equal::value,void>::type push_back(T&& value) { elements_.emplace_back(std::forward(value)); } template typename std::enable_if::is_always_equal::value,void>::type push_back(T&& value) { elements_.emplace_back(std::forward(value)); } template typename std::enable_if::is_always_equal::value,iterator>::type insert(const_iterator pos, T&& value) { return elements_.emplace(pos, std::forward(value)); } template typename std::enable_if::is_always_equal::value,iterator>::type insert(const_iterator pos, T&& value) { return elements_.emplace(pos, std::forward(value)); } template iterator insert(const_iterator pos, InputIt first, InputIt last) { return elements_.insert(pos, first, last); } template typename std::enable_if::is_always_equal::value,iterator>::type emplace(const_iterator pos, Args&&... args) { return elements_.emplace(pos, std::forward(args)...); } template Json& emplace_back(Args&&... args) { elements_.emplace_back(std::forward(args)...); return elements_.back(); } iterator begin() {return elements_.begin();} iterator end() {return elements_.end();} const_iterator begin() const {return elements_.begin();} const_iterator end() const {return elements_.end();} bool operator==(const json_array& rhs) const noexcept { return elements_ == rhs.elements_; } bool operator<(const json_array& rhs) const noexcept { return elements_ < rhs.elements_; } json_array& operator=(const json_array& other) { elements_ = other.elements_; return *this; } private: void flatten_and_destroy() noexcept { while (!elements_.empty()) { value_type current = std::move(elements_.back()); elements_.pop_back(); switch (current.storage_kind()) { case json_storage_kind::array: { for (auto&& item : current.array_range()) { if ((item.storage_kind() == json_storage_kind::array || item.storage_kind() == json_storage_kind::object) && !item.empty()) // non-empty object or array { elements_.push_back(std::move(item)); } } current.clear(); break; } case json_storage_kind::object: { for (auto&& kv : current.object_range()) { if ((kv.value().storage_kind() == json_storage_kind::array || kv.value().storage_kind() == json_storage_kind::object) && !kv.value().empty()) // non-empty object or array { elements_.push_back(std::move(kv.value())); } } current.clear(); break; } default: break; } } } }; } // namespace jsoncons #endif // JSONCONS_JSON_ARRAY_HPP jsoncons-1.3.2/include/jsoncons/json_cursor.hpp000066400000000000000000000344701477700171100217240ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_JSON_CURSOR_HPP #define JSONCONS_JSON_CURSOR_HPP #include #include #include #include // std::allocator #include #include #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { template ,typename Allocator=std::allocator> class basic_json_cursor : public basic_staj_cursor, private virtual ser_context { public: using source_type = Source; using char_type = CharT; using allocator_type = Allocator; using string_view_type = jsoncons::basic_string_view; private: using char_allocator_type = typename std::allocator_traits:: template rebind_alloc; static constexpr size_t default_max_buffer_size = 16384; json_source_adaptor source_; basic_json_parser parser_; basic_staj_visitor cursor_visitor_; bool done_{false}; public: // Constructors that throw parse exceptions template basic_json_cursor(Sourceable&& source, const basic_json_decode_options& options = basic_json_decode_options(), std::function err_handler = default_json_parsing(), const Allocator& alloc = Allocator(), typename std::enable_if,Sourceable>::value>::type* = 0) : source_(std::forward(source)), parser_(options,err_handler,alloc) { parser_.cursor_mode(true); if (!done()) { std::error_code local_ec; read_next(local_ec); if (local_ec) { if (local_ec == json_errc::unexpected_eof) { done_ = true; } else { JSONCONS_THROW(ser_error(local_ec, 1, 1)); } } } } template basic_json_cursor(Sourceable&& source, const basic_json_decode_options& options = basic_json_decode_options(), std::function err_handler = default_json_parsing(), const Allocator& alloc = Allocator(), typename std::enable_if,Sourceable>::value>::type* = 0) : source_(), parser_(options, err_handler, alloc) { parser_.cursor_mode(true); initialize_with_string_view(std::forward(source)); } // Constructors that set parse error codes template basic_json_cursor(Sourceable&& source, std::error_code& ec) : basic_json_cursor(std::allocator_arg, Allocator(), std::forward(source), basic_json_decode_options(), default_json_parsing(), ec) { } template basic_json_cursor(Sourceable&& source, const basic_json_decode_options& options, std::error_code& ec) : basic_json_cursor(std::allocator_arg, Allocator(), std::forward(source), options, default_json_parsing(), ec) { } template basic_json_cursor(Sourceable&& source, const basic_json_decode_options& options, std::function err_handler, std::error_code& ec) : basic_json_cursor(std::allocator_arg, Allocator(), std::forward(source), options, err_handler, ec) { } template basic_json_cursor(std::allocator_arg_t, const Allocator& alloc, Sourceable&& source, const basic_json_decode_options& options, std::function err_handler, std::error_code& ec, typename std::enable_if,Sourceable>::value>::type* = 0) : source_(std::forward(source)), parser_(options,err_handler,alloc) { parser_.cursor_mode(true); if (!done()) { std::error_code local_ec; read_next(local_ec); if (local_ec) { if (local_ec == json_errc::unexpected_eof) { done_ = true; } else { ec = local_ec; } } } } template basic_json_cursor(std::allocator_arg_t, const Allocator& alloc, Sourceable&& source, const basic_json_decode_options& options, std::function err_handler, std::error_code& ec, typename std::enable_if,Sourceable>::value>::type* = 0) : source_(), parser_(options, err_handler, alloc) { parser_.cursor_mode(true); initialize_with_string_view(std::forward(source), ec); } basic_json_cursor(const basic_json_cursor&) = delete; basic_json_cursor(basic_json_cursor&&) = default; ~basic_json_cursor() = default; // Noncopyable and nonmoveable basic_json_cursor& operator=(const basic_json_cursor&) = delete; basic_json_cursor& operator=(basic_json_cursor&&) = default; void reset() { parser_.reset(); cursor_visitor_.reset(); done_ = false; if (!done()) { next(); } } template typename std::enable_if,Sourceable>::value>::type reset(Sourceable&& source) { source_ = std::forward(source); parser_.reinitialize(); cursor_visitor_.reset(); done_ = false; if (!done()) { next(); } } template typename std::enable_if,Sourceable>::value>::type reset(Sourceable&& source) { source_ = {}; parser_.reinitialize(); cursor_visitor_.reset(); done_ = false; initialize_with_string_view(std::forward(source)); } void reset(std::error_code& ec) { parser_.reset(); cursor_visitor_.reset(); done_ = false; if (!done()) { next(ec); } } template typename std::enable_if,Sourceable>::value>::type reset(Sourceable&& source, std::error_code& ec) { source_ = std::forward(source); parser_.reinitialize(); cursor_visitor_.reset(); done_ = false; if (!done()) { next(ec); } } template typename std::enable_if,Sourceable>::value>::type reset(Sourceable&& source, std::error_code& ec) { source_ = {}; parser_.reinitialize(); done_ = false; initialize_with_string_view(std::forward(source), ec); } bool done() const override { return parser_.done() || done_; } const basic_staj_event& current() const override { return cursor_visitor_.event(); } void read_to(basic_json_visitor& visitor) override { std::error_code ec; read_to(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); } } void read_to(basic_json_visitor& visitor, std::error_code& ec) override { if (is_begin_container(current().event_type())) { parser_.cursor_mode(false); parser_.mark_level(parser_.level()); cursor_visitor_.event().send_json_event(visitor, *this, ec); if (JSONCONS_UNLIKELY(ec)) { return; } read_next(visitor, ec); parser_.cursor_mode(true); parser_.mark_level(0); if (current().event_type() == staj_event_type::begin_object) { cursor_visitor_.end_object(*this); } else { cursor_visitor_.end_array(*this); } } else { cursor_visitor_.event().send_json_event(visitor, *this, ec); } } void next() override { std::error_code ec; next(ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); } } void next(std::error_code& ec) override { read_next(ec); } void check_done() { std::error_code ec; check_done(ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); } } const ser_context& context() const override { return *this; } void check_done(std::error_code& ec) { if (source_.is_error()) { ec = json_errc::source_error; return; } if (source_.eof()) { parser_.check_done(ec); if (JSONCONS_UNLIKELY(ec)) {return;} } else { do { if (parser_.source_exhausted()) { auto s = source_.read_buffer(ec); if (JSONCONS_UNLIKELY(ec)) {return;} if (s.size() > 0) { parser_.update(s.data(),s.size()); } } if (!parser_.source_exhausted()) { parser_.check_done(ec); if (JSONCONS_UNLIKELY(ec)) {return;} } } while (!eof()); } } bool eof() const { return parser_.source_exhausted() && source_.eof(); } std::size_t line() const override { return parser_.line(); } std::size_t column() const override { return parser_.column(); } friend basic_staj_filter_view operator|(basic_json_cursor& cursor, std::function&, const ser_context&)> pred) { return basic_staj_filter_view(cursor, pred); } private: void initialize_with_string_view(string_view_type sv) { std::error_code local_ec; initialize_with_string_view(sv, local_ec); if (local_ec) { JSONCONS_THROW(ser_error(local_ec, 1, 1)); } } void initialize_with_string_view(string_view_type sv, std::error_code& ec) { auto r = unicode_traits::detect_json_encoding(sv.data(), sv.size()); if (!(r.encoding == unicode_traits::encoding_kind::utf8 || r.encoding == unicode_traits::encoding_kind::undetected)) { ec = json_errc::illegal_unicode_character; return; } std::size_t offset = (r.ptr - sv.data()); parser_.update(sv.data()+offset,sv.size()-offset); bool is_done = parser_.done() || done_; if (!is_done) { std::error_code local_ec; read_next(local_ec); if (local_ec) { if (local_ec == json_errc::unexpected_eof) { done_ = true; } else { ec = local_ec; } } } } void read_next() { std::error_code ec; read_next(cursor_visitor_, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); } } void read_next(std::error_code& ec) { read_next(cursor_visitor_, ec); } void read_next(basic_json_visitor& visitor, std::error_code& ec) { parser_.restart(); while (!parser_.stopped()) { if (parser_.source_exhausted()) { auto s = source_.read_buffer(ec); if (JSONCONS_UNLIKELY(ec)) {return;} if (s.size() > 0) { parser_.update(s.data(),s.size()); if (JSONCONS_UNLIKELY(ec)) {return;} } } bool eof = parser_.source_exhausted() && source_.eof(); parser_.parse_some(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} if (eof) { if (parser_.enter()) { done_ = true; break; } else if (!parser_.accept()) { ec = json_errc::unexpected_eof; return; } } } } }; using json_stream_cursor = basic_json_cursor>; using json_string_cursor = basic_json_cursor>; using wjson_stream_cursor = basic_json_cursor>; using wjson_string_cursor = basic_json_cursor>; } // namespace jsoncons #endif // JSONCONS_JSON_CURSOR_HPP jsoncons-1.3.2/include/jsoncons/json_decoder.hpp000066400000000000000000000314721477700171100220130ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_JSON_DECODER_HPP #define JSONCONS_JSON_DECODER_HPP #include #include #include // std::allocator #include #include // std::move #include #include #include #include #include namespace jsoncons { template > class json_decoder final : public basic_json_visitor { public: using char_type = typename Json::char_type; using typename basic_json_visitor::string_view_type; using key_value_type = typename Json::key_value_type; using key_type = typename Json::key_type; using array = typename Json::array; using object = typename Json::object; using allocator_type = typename Json::allocator_type; using json_string_allocator = typename key_type::allocator_type; using json_array_allocator = typename array::allocator_type; using json_object_allocator = typename object::allocator_type; using json_byte_allocator_type = typename std::allocator_traits:: template rebind_alloc; private: enum class structure_type {root_t, array_t, object_t}; struct structure_info { structure_type type_; std::size_t container_index_{0}; structure_info(structure_type type, std::size_t offset) noexcept : type_(type), container_index_(offset) { } ~structure_info() = default; }; using temp_allocator_type = TempAllocator; using stack_item_allocator_type = typename std::allocator_traits:: template rebind_alloc>; using structure_info_allocator_type = typename std::allocator_traits:: template rebind_alloc; allocator_type allocator_; Json result_; std::size_t index_{0}; key_type name_; std::vector,stack_item_allocator_type> item_stack_; std::vector structure_stack_; bool is_valid_{false}; public: json_decoder(const allocator_type& alloc = allocator_type(), const temp_allocator_type& temp_alloc = temp_allocator_type()) : allocator_(alloc), result_(), name_(alloc), item_stack_(alloc), structure_stack_(temp_alloc) { item_stack_.reserve(1000); structure_stack_.reserve(100); structure_stack_.emplace_back(structure_type::root_t, 0); } json_decoder(temp_allocator_arg_t, const temp_allocator_type& temp_alloc = temp_allocator_type()) : allocator_(), result_(), name_(), item_stack_(), structure_stack_(temp_alloc) { item_stack_.reserve(1000); structure_stack_.reserve(100); structure_stack_.emplace_back(structure_type::root_t, 0); } void reset() { is_valid_ = false; index_ = 0; item_stack_.clear(); structure_stack_.clear(); structure_stack_.emplace_back(structure_type::root_t, 0); } bool is_valid() const { return is_valid_; } Json get_result() { JSONCONS_ASSERT(is_valid_); is_valid_ = false; return std::move(result_); } private: void visit_flush() override { } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag tag, const ser_context&, std::error_code&) override { if (structure_stack_.back().type_ == structure_type::root_t) { index_ = 0; item_stack_.clear(); is_valid_ = false; } item_stack_.emplace_back(std::move(name_), index_++, json_object_arg, tag); structure_stack_.emplace_back(structure_type::object_t, item_stack_.size()-1); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context&, std::error_code&) override { JSONCONS_ASSERT(structure_stack_.size() > 0); JSONCONS_ASSERT(structure_stack_.back().type_ == structure_type::object_t); const size_t structure_index = structure_stack_.back().container_index_; JSONCONS_ASSERT(item_stack_.size() > structure_index); const size_t count = item_stack_.size() - (structure_index + 1); auto first = item_stack_.begin() + (structure_index+1); if (count > 0) { item_stack_[structure_index].value.template cast().value().uninitialized_init( &item_stack_[structure_index+1], count); } item_stack_.erase(first, item_stack_.end()); structure_stack_.pop_back(); if (structure_stack_.back().type_ == structure_type::root_t) { result_.swap(item_stack_.front().value); item_stack_.pop_back(); is_valid_ = true; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag tag, const ser_context&, std::error_code&) override { if (structure_stack_.back().type_ == structure_type::root_t) { index_ = 0; item_stack_.clear(); is_valid_ = false; } item_stack_.emplace_back(std::move(name_), index_++, json_array_arg, tag); structure_stack_.emplace_back(structure_type::array_t, item_stack_.size()-1); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context&, std::error_code&) override { JSONCONS_ASSERT(structure_stack_.size() > 1); JSONCONS_ASSERT(structure_stack_.back().type_ == structure_type::array_t); const size_t container_index = structure_stack_.back().container_index_; JSONCONS_ASSERT(item_stack_.size() > container_index); auto& container = item_stack_[container_index].value; const size_t size = item_stack_.size() - (container_index + 1); //std::cout << "size on item stack: " << size << "\n"; if (size > 0) { container.reserve(size); auto first = item_stack_.begin() + (container_index+1); auto last = first + size; for (auto it = first; it != last; ++it) { container.push_back(std::move((*it).value)); } item_stack_.erase(first, item_stack_.end()); } structure_stack_.pop_back(); if (structure_stack_.back().type_ == structure_type::root_t) { result_.swap(item_stack_.front().value); item_stack_.pop_back(); is_valid_ = true; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type& name, const ser_context&, std::error_code&) override { name_ = key_type(name.data(),name.length(),allocator_); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& sv, semantic_tag tag, const ser_context&, std::error_code&) override { switch (structure_stack_.back().type_) { case structure_type::object_t: case structure_type::array_t: item_stack_.emplace_back(std::move(name_), index_++, sv, tag); break; case structure_type::root_t: result_ = Json(sv, tag, allocator_); is_valid_ = true; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& b, semantic_tag tag, const ser_context&, std::error_code&) override { switch (structure_stack_.back().type_) { case structure_type::object_t: case structure_type::array_t: item_stack_.emplace_back(std::move(name_), index_++, byte_string_arg, b, tag); break; case structure_type::root_t: result_ = Json(byte_string_arg, b, tag, allocator_); is_valid_ = true; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& b, uint64_t ext_tag, const ser_context&, std::error_code&) override { switch (structure_stack_.back().type_) { case structure_type::object_t: case structure_type::array_t: item_stack_.emplace_back(std::move(name_), index_++, byte_string_arg, b, ext_tag); break; case structure_type::root_t: result_ = Json(byte_string_arg, b, ext_tag, allocator_); is_valid_ = true; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t value, semantic_tag tag, const ser_context&, std::error_code&) override { switch (structure_stack_.back().type_) { case structure_type::object_t: case structure_type::array_t: item_stack_.emplace_back(std::move(name_), index_++, value, tag); break; case structure_type::root_t: result_ = Json(value,tag); is_valid_ = true; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t value, semantic_tag tag, const ser_context&, std::error_code&) override { switch (structure_stack_.back().type_) { case structure_type::object_t: case structure_type::array_t: item_stack_.emplace_back(std::move(name_), index_++, value, tag); break; case structure_type::root_t: result_ = Json(value,tag); is_valid_ = true; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_half(uint16_t value, semantic_tag tag, const ser_context&, std::error_code&) override { switch (structure_stack_.back().type_) { case structure_type::object_t: case structure_type::array_t: item_stack_.emplace_back(std::move(name_), index_++, half_arg, value, tag); break; case structure_type::root_t: result_ = Json(half_arg, value, tag); is_valid_ = true; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_double(double value, semantic_tag tag, const ser_context&, std::error_code&) override { switch (structure_stack_.back().type_) { case structure_type::object_t: case structure_type::array_t: item_stack_.emplace_back(std::move(name_), index_++, value, tag); break; case structure_type::root_t: result_ = Json(value, tag); is_valid_ = true; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool value, semantic_tag tag, const ser_context&, std::error_code&) override { switch (structure_stack_.back().type_) { case structure_type::object_t: case structure_type::array_t: item_stack_.emplace_back(std::move(name_), index_++, value, tag); break; case structure_type::root_t: result_ = Json(value, tag); is_valid_ = true; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag tag, const ser_context&, std::error_code&) override { switch (structure_stack_.back().type_) { case structure_type::object_t: case structure_type::array_t: item_stack_.emplace_back(std::move(name_), index_++, null_type(), tag); break; case structure_type::root_t: result_ = Json(null_type(), tag); is_valid_ = true; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN; } }; } // namespace jsoncons #endif // JSONCONS_JSON_DECODER_HPP jsoncons-1.3.2/include/jsoncons/json_encoder.hpp000066400000000000000000001623341477700171100220270ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_JSON_ENCODER_HPP #define JSONCONS_JSON_ENCODER_HPP #include // std::array #include #include #include // std::isfinite, std::isnan #include // std::numeric_limits #include #include #include // std::move #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace detail { inline bool is_control_character(uint32_t c) { return c <= 0x1F || c == 0x7f; } inline bool is_non_ascii_codepoint(uint32_t cp) { return cp >= 0x80; } template std::size_t escape_string(const CharT* s, std::size_t length, bool escape_all_non_ascii, bool escape_solidus, Sink& sink) { std::size_t count = 0; const CharT* begin = s; const CharT* end = s + length; for (const CharT* it = begin; it != end; ++it) { CharT c = *it; switch (c) { case '\\': sink.push_back('\\'); sink.push_back('\\'); count += 2; break; case '"': sink.push_back('\\'); sink.push_back('\"'); count += 2; break; case '\b': sink.push_back('\\'); sink.push_back('b'); count += 2; break; case '\f': sink.push_back('\\'); sink.push_back('f'); count += 2; break; case '\n': sink.push_back('\\'); sink.push_back('n'); count += 2; break; case '\r': sink.push_back('\\'); sink.push_back('r'); count += 2; break; case '\t': sink.push_back('\\'); sink.push_back('t'); count += 2; break; default: if (escape_solidus && c == '/') { sink.push_back('\\'); sink.push_back('/'); count += 2; } else if (is_control_character(c) || escape_all_non_ascii) { // convert to codepoint uint32_t cp; auto r = unicode_traits::to_codepoint(it, end, cp, unicode_traits::conv_flags::strict); if (r.ec != unicode_traits::conv_errc()) { JSONCONS_THROW(ser_error(json_errc::illegal_codepoint)); } it = r.ptr - 1; if (is_non_ascii_codepoint(cp) || is_control_character(c)) { if (cp > 0xFFFF) { cp -= 0x10000; uint32_t first = (cp >> 10) + 0xD800; uint32_t second = ((cp & 0x03FF) + 0xDC00); sink.push_back('\\'); sink.push_back('u'); sink.push_back(jsoncons::detail::to_hex_character(first >> 12 & 0x000F)); sink.push_back(jsoncons::detail::to_hex_character(first >> 8 & 0x000F)); sink.push_back(jsoncons::detail::to_hex_character(first >> 4 & 0x000F)); sink.push_back(jsoncons::detail::to_hex_character(first & 0x000F)); sink.push_back('\\'); sink.push_back('u'); sink.push_back(jsoncons::detail::to_hex_character(second >> 12 & 0x000F)); sink.push_back(jsoncons::detail::to_hex_character(second >> 8 & 0x000F)); sink.push_back(jsoncons::detail::to_hex_character(second >> 4 & 0x000F)); sink.push_back(jsoncons::detail::to_hex_character(second & 0x000F)); count += 12; } else { sink.push_back('\\'); sink.push_back('u'); sink.push_back(jsoncons::detail::to_hex_character(cp >> 12 & 0x000F)); sink.push_back(jsoncons::detail::to_hex_character(cp >> 8 & 0x000F)); sink.push_back(jsoncons::detail::to_hex_character(cp >> 4 & 0x000F)); sink.push_back(jsoncons::detail::to_hex_character(cp & 0x000F)); count += 6; } } else { sink.push_back(c); ++count; } } else { sink.push_back(c); ++count; } break; } } return count; } inline byte_string_chars_format resolve_byte_string_chars_format(byte_string_chars_format format1, byte_string_chars_format format2, byte_string_chars_format default_format = byte_string_chars_format::base64url) { byte_string_chars_format sink; switch (format1) { case byte_string_chars_format::base16: case byte_string_chars_format::base64: case byte_string_chars_format::base64url: sink = format1; break; default: switch (format2) { case byte_string_chars_format::base64url: case byte_string_chars_format::base64: case byte_string_chars_format::base16: sink = format2; break; default: // base64url { sink = default_format; break; } } break; } return sink; } } // namespace detail template ,typename Allocator=std::allocator> class basic_json_encoder final : public basic_json_visitor { static const jsoncons::basic_string_view null_constant() { static const jsoncons::basic_string_view k = JSONCONS_STRING_VIEW_CONSTANT(CharT, "null"); return k; } static const jsoncons::basic_string_view true_constant() { static const jsoncons::basic_string_view k = JSONCONS_STRING_VIEW_CONSTANT(CharT, "true"); return k; } static const jsoncons::basic_string_view false_constant() { static const jsoncons::basic_string_view k = JSONCONS_STRING_VIEW_CONSTANT(CharT, "false"); return k; } public: using allocator_type = Allocator; using char_type = CharT; using typename basic_json_visitor::string_view_type; using sink_type = Sink; using string_type = typename basic_json_encode_options::string_type; private: enum class container_type {object, array}; class encoding_context { container_type type_; line_split_kind line_splits_; bool indent_before_; bool new_line_after_; std::size_t begin_pos_{0}; std::size_t data_pos_{0}; std::size_t count_{0}; public: encoding_context(container_type type, line_split_kind split_lines, bool indent_once, std::size_t begin_pos, std::size_t data_pos) noexcept : type_(type), line_splits_(split_lines), indent_before_(indent_once), new_line_after_(false), begin_pos_(begin_pos), data_pos_(data_pos) { } encoding_context(const encoding_context&) = default; ~encoding_context() = default; encoding_context& operator=(const encoding_context&) = default; void set_position(std::size_t pos) { data_pos_ = pos; } std::size_t begin_pos() const { return begin_pos_; } std::size_t data_pos() const { return data_pos_; } std::size_t count() const { return count_; } void increment_count() { ++count_; } bool new_line_after() const { return new_line_after_; } void new_line_after(bool value) { new_line_after_ = value; } bool is_object() const { return type_ == container_type::object; } bool is_array() const { return type_ == container_type::array; } bool is_same_line() const { return line_splits_ == line_split_kind::same_line; } bool is_new_line() const { return line_splits_ == line_split_kind::new_line; } bool is_multi_line() const { return line_splits_ == line_split_kind::multi_line; } bool is_indent_once() const { return count_ == 0 ? indent_before_ : false; } }; using encoding_context_allocator_type = typename std::allocator_traits:: template rebind_alloc; Sink sink_; basic_json_encode_options options_; jsoncons::detail::write_double fp_; std::vector stack_; int indent_amount_{0}; std::size_t column_{0}; std::basic_string colon_str_; std::basic_string comma_str_; std::basic_string open_object_brace_str_; std::basic_string close_object_brace_str_; std::basic_string open_array_bracket_str_; std::basic_string close_array_bracket_str_; int nesting_depth_{0}; public: // Noncopyable and nonmoveable basic_json_encoder(const basic_json_encoder&) = delete; basic_json_encoder(basic_json_encoder&&) = delete; basic_json_encoder(Sink&& sink, const Allocator& alloc = Allocator()) : basic_json_encoder(std::forward(sink), basic_json_encode_options(), alloc) { } basic_json_encoder(Sink&& sink, const basic_json_encode_options& options, const Allocator& alloc = Allocator()) : sink_(std::forward(sink)), options_(options), fp_(options.float_format(), options.precision()), stack_(alloc) { switch (options.spaces_around_colon()) { case spaces_option::space_after: colon_str_ = std::basic_string({':',' '}); break; case spaces_option::space_before: colon_str_ = std::basic_string({' ',':'}); break; case spaces_option::space_before_and_after: colon_str_ = std::basic_string({' ',':',' '}); break; default: colon_str_.push_back(':'); break; } switch (options.spaces_around_comma()) { case spaces_option::space_after: comma_str_ = std::basic_string({',',' '}); break; case spaces_option::space_before: comma_str_ = std::basic_string({' ',','}); break; case spaces_option::space_before_and_after: comma_str_ = std::basic_string({' ',',',' '}); break; default: comma_str_.push_back(','); break; } if (options.pad_inside_object_braces()) { open_object_brace_str_ = std::basic_string({'{', ' '}); close_object_brace_str_ = std::basic_string({' ', '}'}); } else { open_object_brace_str_.push_back('{'); close_object_brace_str_.push_back('}'); } if (options.pad_inside_array_brackets()) { open_array_bracket_str_ = std::basic_string({'[', ' '}); close_array_bracket_str_ = std::basic_string({' ', ']'}); } else { open_array_bracket_str_.push_back('['); close_array_bracket_str_.push_back(']'); } } ~basic_json_encoder() noexcept { JSONCONS_TRY { sink_.flush(); } JSONCONS_CATCH(...) { } } basic_json_encoder& operator=(const basic_json_encoder&) = delete; basic_json_encoder& operator=(basic_json_encoder&&) = delete; void reset() { stack_.clear(); indent_amount_ = 0; column_ = 0; nesting_depth_ = 0; } void reset(Sink&& sink) { sink_ = std::move(sink); reset(); } private: // Implementing methods void visit_flush() final { sink_.flush(); } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag, const ser_context&, std::error_code& ec) final { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = json_errc::max_nesting_depth_exceeded; JSONCONS_VISITOR_RETURN; } if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) { sink_.append(comma_str_.data(),comma_str_.length()); column_ += comma_str_.length(); } if (!stack_.empty()) // object or array { if (stack_.back().is_object()) { switch (options_.object_object_line_splits()) { case line_split_kind::same_line: case line_split_kind::new_line: if (column_ >= options_.line_length_limit()) { break_line(); } break; default: // multi_line break; } stack_.emplace_back(container_type::object,options_.object_object_line_splits(), false, column_, column_+open_object_brace_str_.length()); } else // array { switch (options_.array_object_line_splits()) { case line_split_kind::same_line: if (column_ >= options_.line_length_limit()) { //stack_.back().new_line_after(true); new_line(); } else { stack_.back().new_line_after(true); new_line(); } break; case line_split_kind::new_line: stack_.back().new_line_after(true); new_line(); break; default: // multi_line stack_.back().new_line_after(true); new_line(); break; } stack_.emplace_back(container_type::object,options_.array_object_line_splits(), false, column_, column_+open_object_brace_str_.length()); } } else { stack_.emplace_back(container_type::object, options_.line_splits(), false, column_, column_+open_object_brace_str_.length()); } indent(); sink_.append(open_object_brace_str_.data(), open_object_brace_str_.length()); column_ += open_object_brace_str_.length(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context&, std::error_code&) final { JSONCONS_ASSERT(!stack_.empty()); --nesting_depth_; unindent(); if (stack_.back().new_line_after()) { new_line(); } stack_.pop_back(); sink_.append(close_object_brace_str_.data(), close_object_brace_str_.length()); column_ += close_object_brace_str_.length(); end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag, const ser_context&, std::error_code& ec) final { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = json_errc::max_nesting_depth_exceeded; JSONCONS_VISITOR_RETURN; } if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) { sink_.append(comma_str_.data(),comma_str_.length()); column_ += comma_str_.length(); } if (!stack_.empty()) { if (stack_.back().is_object()) { switch (options_.object_array_line_splits()) { case line_split_kind::same_line: stack_.emplace_back(container_type::array,options_.object_array_line_splits(),false, column_, column_ + open_array_bracket_str_.length()); break; case line_split_kind::new_line: { stack_.emplace_back(container_type::array,options_.object_array_line_splits(),true, column_, column_+open_array_bracket_str_.length()); break; } default: // multi_line stack_.emplace_back(container_type::array,options_.object_array_line_splits(),true, column_, column_+open_array_bracket_str_.length()); break; } } else // array { switch (options_.array_array_line_splits()) { case line_split_kind::same_line: if (stack_.back().is_multi_line()) { stack_.back().new_line_after(true); new_line(); } stack_.emplace_back(container_type::array,options_.array_array_line_splits(), false, column_, column_+open_array_bracket_str_.length()); break; case line_split_kind::new_line: stack_.back().new_line_after(true); new_line(); stack_.emplace_back(container_type::array,options_.array_array_line_splits(), false, column_, column_+open_array_bracket_str_.length()); break; default: // multi_line stack_.back().new_line_after(true); new_line(); stack_.emplace_back(container_type::array,options_.array_array_line_splits(), false, column_, column_+open_array_bracket_str_.length()); //new_line(); break; } } } else { stack_.emplace_back(container_type::array, options_.line_splits(), false, column_, column_+open_array_bracket_str_.length()); } indent(); sink_.append(open_array_bracket_str_.data(), open_array_bracket_str_.length()); column_ += open_array_bracket_str_.length(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context&, std::error_code&) final { JSONCONS_ASSERT(!stack_.empty()); --nesting_depth_; unindent(); if (stack_.back().new_line_after()) { new_line(); } stack_.pop_back(); sink_.append(close_array_bracket_str_.data(), close_array_bracket_str_.length()); column_ += close_array_bracket_str_.length(); end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type& name, const ser_context&, std::error_code&) final { JSONCONS_ASSERT(!stack_.empty()); if (stack_.back().count() > 0) { sink_.append(comma_str_.data(),comma_str_.length()); column_ += comma_str_.length(); } if (stack_.back().is_multi_line()) { stack_.back().new_line_after(true); new_line(); } else if (stack_.back().count() > 0 && column_ >= options_.line_length_limit()) { //stack_.back().new_line_after(true); new_line(stack_.back().data_pos()); } if (stack_.back().count() == 0) { stack_.back().set_position(column_); } sink_.push_back('\"'); std::size_t length = jsoncons::detail::escape_string(name.data(), name.length(),options_.escape_all_non_ascii(),options_.escape_solidus(),sink_); sink_.push_back('\"'); sink_.append(colon_str_.data(),colon_str_.length()); column_ += (length+2+colon_str_.length()); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag, const ser_context&, std::error_code&) final { if (!stack_.empty()) { if (stack_.back().is_array()) { begin_scalar_value(); } if (!stack_.back().is_multi_line() && column_ >= options_.line_length_limit()) { break_line(); } } sink_.append(null_constant().data(), null_constant().size()); column_ += null_constant().size(); end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& sv, semantic_tag tag, const ser_context& context, std::error_code& ec) final { if (!stack_.empty()) { if (stack_.back().is_array()) { begin_scalar_value(); } if (!stack_.back().is_multi_line() && column_ >= options_.line_length_limit()) { break_line(); } } write_string(sv, tag, context, ec); end_value(); JSONCONS_VISITOR_RETURN; } void write_string(const string_view_type& sv, semantic_tag tag, const ser_context&, std::error_code&) { switch (tag) { case semantic_tag::bigint: write_bigint_value(sv); break; case semantic_tag::bigdec: { // output lossless number if (options_.bignum_format() == bignum_format_kind::raw) { write_bigint_value(sv); break; } JSONCONS_FALLTHROUGH; } default: { sink_.push_back('\"'); std::size_t length = jsoncons::detail::escape_string(sv.data(), sv.length(),options_.escape_all_non_ascii(),options_.escape_solidus(),sink_); sink_.push_back('\"'); column_ += (length+2); break; } } } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& b, semantic_tag tag, const ser_context&, std::error_code&) final { if (!stack_.empty()) { if (stack_.back().is_array()) { begin_scalar_value(); } if (!stack_.back().is_multi_line() && column_ >= options_.line_length_limit()) { break_line(); } } byte_string_chars_format encoding_hint; switch (tag) { case semantic_tag::base16: encoding_hint = byte_string_chars_format::base16; break; case semantic_tag::base64: encoding_hint = byte_string_chars_format::base64; break; case semantic_tag::base64url: encoding_hint = byte_string_chars_format::base64url; break; default: encoding_hint = byte_string_chars_format::none; break; } byte_string_chars_format format = jsoncons::detail::resolve_byte_string_chars_format(options_.byte_string_format(), encoding_hint, byte_string_chars_format::base64url); switch (format) { case byte_string_chars_format::base16: { sink_.push_back('\"'); std::size_t length = encode_base16(b.begin(),b.end(),sink_); sink_.push_back('\"'); column_ += (length + 2); break; } case byte_string_chars_format::base64: { sink_.push_back('\"'); std::size_t length = encode_base64(b.begin(), b.end(), sink_); sink_.push_back('\"'); column_ += (length + 2); break; } case byte_string_chars_format::base64url: { sink_.push_back('\"'); std::size_t length = encode_base64url(b.begin(),b.end(),sink_); sink_.push_back('\"'); column_ += (length + 2); break; } default: { JSONCONS_UNREACHABLE(); } } end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_double(double value, semantic_tag, const ser_context& context, std::error_code& ec) final { if (!stack_.empty()) { if (stack_.back().is_array()) { begin_scalar_value(); } if (!stack_.back().is_multi_line() && column_ >= options_.line_length_limit()) { break_line(); } } if (!std::isfinite(value)) { if ((std::isnan)(value)) { if (options_.enable_nan_to_num()) { sink_.append(options_.nan_to_num().data(), options_.nan_to_num().length()); column_ += options_.nan_to_num().length(); } else if (options_.enable_nan_to_str()) { write_string(options_.nan_to_str(), semantic_tag::none, context, ec); } else { sink_.append(null_constant().data(), null_constant().size()); column_ += null_constant().size(); } } else if (value == std::numeric_limits::infinity()) { if (options_.enable_inf_to_num()) { sink_.append(options_.inf_to_num().data(), options_.inf_to_num().length()); column_ += options_.inf_to_num().length(); } else if (options_.enable_inf_to_str()) { write_string(options_.inf_to_str(), semantic_tag::none, context, ec); } else { sink_.append(null_constant().data(), null_constant().size()); column_ += null_constant().size(); } } else { if (options_.enable_neginf_to_num()) { sink_.append(options_.neginf_to_num().data(), options_.neginf_to_num().length()); column_ += options_.neginf_to_num().length(); } else if (options_.enable_neginf_to_str()) { write_string(options_.neginf_to_str(), semantic_tag::none, context, ec); } else { sink_.append(null_constant().data(), null_constant().size()); column_ += null_constant().size(); } } } else { std::size_t length = fp_(value, sink_); column_ += length; } end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t value, semantic_tag, const ser_context&, std::error_code&) final { if (!stack_.empty()) { if (stack_.back().is_array()) { begin_scalar_value(); } if (!stack_.back().is_multi_line() && column_ >= options_.line_length_limit()) { break_line(); } } std::size_t length = jsoncons::detail::from_integer(value, sink_); column_ += length; end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t value, semantic_tag, const ser_context&, std::error_code&) final { if (!stack_.empty()) { if (stack_.back().is_array()) { begin_scalar_value(); } if (!stack_.back().is_multi_line() && column_ >= options_.line_length_limit()) { break_line(); } } std::size_t length = jsoncons::detail::from_integer(value, sink_); column_ += length; end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool value, semantic_tag, const ser_context&, std::error_code&) final { if (!stack_.empty()) { if (stack_.back().is_array()) { begin_scalar_value(); } if (!stack_.back().is_multi_line() && column_ >= options_.line_length_limit()) { break_line(); } } if (value) { sink_.append(true_constant().data(), true_constant().size()); column_ += true_constant().size(); } else { sink_.append(false_constant().data(), false_constant().size()); column_ += false_constant().size(); } end_value(); JSONCONS_VISITOR_RETURN; } void begin_scalar_value() { if (!stack_.empty()) { if (stack_.back().count() > 0) { sink_.append(comma_str_.data(),comma_str_.length()); column_ += comma_str_.length(); } if (stack_.back().is_multi_line() || stack_.back().is_indent_once()) { stack_.back().new_line_after(true); new_line(); } } } void write_bigint_value(const string_view_type& sv) { switch (options_.bignum_format()) { case bignum_format_kind::raw: { sink_.append(sv.data(),sv.size()); column_ += sv.size(); break; } case bignum_format_kind::base64: { bigint n = bigint::from_string(sv.data(), sv.length()); bool is_neg = n < 0; if (is_neg) { n = - n -1; } int signum; std::vector v; n.write_bytes_be(signum, v); sink_.push_back('\"'); if (is_neg) { sink_.push_back('~'); ++column_; } std::size_t length = encode_base64(v.begin(), v.end(), sink_); sink_.push_back('\"'); column_ += (length+2); break; } case bignum_format_kind::base64url: { bigint n = bigint::from_string(sv.data(), sv.length()); bool is_neg = n < 0; if (is_neg) { n = - n -1; } int signum; std::vector v; n.write_bytes_be(signum, v); sink_.push_back('\"'); if (is_neg) { sink_.push_back('~'); ++column_; } std::size_t length = encode_base64url(v.begin(), v.end(), sink_); sink_.push_back('\"'); column_ += (length+2); break; } default: { sink_.push_back('\"'); sink_.append(sv.data(),sv.size()); sink_.push_back('\"'); column_ += (sv.size() + 2); break; } } } void end_value() { if (!stack_.empty()) { stack_.back().increment_count(); } } void indent() { indent_amount_ += static_cast(options_.indent_size()); } void unindent() { indent_amount_ -= static_cast(options_.indent_size()); } void new_line() { sink_.append(options_.new_line_chars().data(),options_.new_line_chars().length()); for (int i = 0; i < indent_amount_; ++i) { sink_.push_back(' '); } column_ = indent_amount_; } void new_line(std::size_t len) { sink_.append(options_.new_line_chars().data(),options_.new_line_chars().length()); for (std::size_t i = 0; i < len; ++i) { sink_.push_back(' '); } column_ = len; } void break_line() { stack_.back().new_line_after(true); new_line(); } }; template ,typename Allocator=std::allocator> class basic_compact_json_encoder final : public basic_json_visitor { static const std::array& null_constant() { static constexpr std::array k{{'n','u','l','l'}}; return k; } static const std::array& true_constant() { static constexpr std::array k{{'t','r','u','e'}}; return k; } static const std::array& false_constant() { static constexpr std::array k{{'f','a','l','s','e'}}; return k; } public: using allocator_type = Allocator; using char_type = CharT; using typename basic_json_visitor::string_view_type; using sink_type = Sink; using string_type = typename basic_json_encode_options::string_type; private: enum class container_type {object, array}; class encoding_context { container_type type_; std::size_t count_{0}; public: encoding_context(container_type type) noexcept : type_(type) { } std::size_t count() const { return count_; } void increment_count() { ++count_; } bool is_array() const { return type_ == container_type::array; } }; using encoding_context_allocator_type = typename std::allocator_traits:: template rebind_alloc; Sink sink_; basic_json_encode_options options_; jsoncons::detail::write_double fp_; std::vector stack_; int nesting_depth_; public: // Noncopyable and nonmoveable basic_compact_json_encoder(const basic_compact_json_encoder&) = delete; basic_compact_json_encoder(basic_compact_json_encoder&&) = delete; basic_compact_json_encoder(Sink&& sink, const Allocator& alloc = Allocator()) : basic_compact_json_encoder(std::forward(sink), basic_json_encode_options(), alloc) { } basic_compact_json_encoder(Sink&& sink, const basic_json_encode_options& options, const Allocator& alloc = Allocator()) : sink_(std::forward(sink)), options_(options), fp_(options.float_format(), options.precision()), stack_(alloc), nesting_depth_(0) { } ~basic_compact_json_encoder() noexcept { JSONCONS_TRY { sink_.flush(); } JSONCONS_CATCH(...) { } } basic_compact_json_encoder& operator=(const basic_compact_json_encoder&) = delete; basic_compact_json_encoder& operator=(basic_compact_json_encoder&&) = delete; void reset() { stack_.clear(); nesting_depth_ = 0; } void reset(Sink&& sink) { sink_ = std::move(sink); reset(); } private: // Implementing methods void visit_flush() final { sink_.flush(); } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag, const ser_context&, std::error_code& ec) final { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = json_errc::max_nesting_depth_exceeded; JSONCONS_VISITOR_RETURN; } if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) { sink_.push_back(','); } stack_.emplace_back(container_type::object); sink_.push_back('{'); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context&, std::error_code&) final { JSONCONS_ASSERT(!stack_.empty()); --nesting_depth_; stack_.pop_back(); sink_.push_back('}'); if (!stack_.empty()) { stack_.back().increment_count(); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag, const ser_context&, std::error_code& ec) final { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = json_errc::max_nesting_depth_exceeded; JSONCONS_VISITOR_RETURN; } if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) { sink_.push_back(','); } stack_.emplace_back(container_type::array); sink_.push_back('['); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context&, std::error_code&) final { JSONCONS_ASSERT(!stack_.empty()); --nesting_depth_; stack_.pop_back(); sink_.push_back(']'); if (!stack_.empty()) { stack_.back().increment_count(); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type& name, const ser_context&, std::error_code&) final { if (!stack_.empty() && stack_.back().count() > 0) { sink_.push_back(','); } sink_.push_back('\"'); jsoncons::detail::escape_string(name.data(), name.length(),options_.escape_all_non_ascii(),options_.escape_solidus(),sink_); sink_.push_back('\"'); sink_.push_back(':'); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag, const ser_context&, std::error_code&) final { if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) { sink_.push_back(','); } sink_.append(null_constant().data(), null_constant().size()); if (!stack_.empty()) { stack_.back().increment_count(); } JSONCONS_VISITOR_RETURN; } void write_bigint_value(const string_view_type& sv) { switch (options_.bignum_format()) { case bignum_format_kind::raw: { sink_.append(sv.data(),sv.size()); break; } case bignum_format_kind::base64: { bigint n = bigint::from_string(sv.data(), sv.length()); bool is_neg = n < 0; if (is_neg) { n = - n -1; } int signum; std::vector v; n.write_bytes_be(signum, v); sink_.push_back('\"'); if (is_neg) { sink_.push_back('~'); } encode_base64(v.begin(), v.end(), sink_); sink_.push_back('\"'); break; } case bignum_format_kind::base64url: { bigint n = bigint::from_string(sv.data(), sv.length()); bool is_neg = n < 0; if (is_neg) { n = - n -1; } int signum; std::vector v; n.write_bytes_be(signum, v); sink_.push_back('\"'); if (is_neg) { sink_.push_back('~'); } encode_base64url(v.begin(), v.end(), sink_); sink_.push_back('\"'); break; } default: { sink_.push_back('\"'); sink_.append(sv.data(),sv.size()); sink_.push_back('\"'); break; } } } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& sv, semantic_tag tag, const ser_context&, std::error_code&) final { if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) { sink_.push_back(','); } switch (tag) { case semantic_tag::bigint: write_bigint_value(sv); break; case semantic_tag::bigdec: { // output lossless number if (options_.bignum_format() == bignum_format_kind::raw) { write_bigint_value(sv); break; } JSONCONS_FALLTHROUGH; } default: { sink_.push_back('\"'); jsoncons::detail::escape_string(sv.data(), sv.length(),options_.escape_all_non_ascii(),options_.escape_solidus(),sink_); sink_.push_back('\"'); break; } } if (!stack_.empty()) { stack_.back().increment_count(); } JSONCONS_VISITOR_RETURN; } void write_string(const string_view_type& sv, semantic_tag tag, const ser_context&, std::error_code&) { switch (tag) { case semantic_tag::bigint: write_bigint_value(sv); break; case semantic_tag::bigdec: { // output lossless number if (options_.bignum_format() == bignum_format_kind::raw) { write_bigint_value(sv); break; } JSONCONS_FALLTHROUGH; } default: { sink_.push_back('\"'); jsoncons::detail::escape_string(sv.data(), sv.length(),options_.escape_all_non_ascii(),options_.escape_solidus(),sink_); sink_.push_back('\"'); break; } } } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& b, semantic_tag tag, const ser_context&, std::error_code&) final { if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) { sink_.push_back(','); } byte_string_chars_format encoding_hint; switch (tag) { case semantic_tag::base16: encoding_hint = byte_string_chars_format::base16; break; case semantic_tag::base64: encoding_hint = byte_string_chars_format::base64; break; case semantic_tag::base64url: encoding_hint = byte_string_chars_format::base64url; break; default: encoding_hint = byte_string_chars_format::none; break; } byte_string_chars_format format = jsoncons::detail::resolve_byte_string_chars_format(options_.byte_string_format(), encoding_hint, byte_string_chars_format::base64url); switch (format) { case byte_string_chars_format::base16: { sink_.push_back('\"'); encode_base16(b.begin(),b.end(),sink_); sink_.push_back('\"'); break; } case byte_string_chars_format::base64: { sink_.push_back('\"'); encode_base64(b.begin(), b.end(), sink_); sink_.push_back('\"'); break; } case byte_string_chars_format::base64url: { sink_.push_back('\"'); encode_base64url(b.begin(),b.end(),sink_); sink_.push_back('\"'); break; } default: { JSONCONS_UNREACHABLE(); } } if (!stack_.empty()) { stack_.back().increment_count(); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_double(double value, semantic_tag, const ser_context& context, std::error_code& ec) final { if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) { sink_.push_back(','); } if (JSONCONS_UNLIKELY(!std::isfinite(value))) { if ((std::isnan)(value)) { if (options_.enable_nan_to_num()) { sink_.append(options_.nan_to_num().data(), options_.nan_to_num().length()); } else if (options_.enable_nan_to_str()) { write_string(options_.nan_to_str(), semantic_tag::none, context, ec); } else { sink_.append(null_constant().data(), null_constant().size()); } } else if (value == std::numeric_limits::infinity()) { if (options_.enable_inf_to_num()) { sink_.append(options_.inf_to_num().data(), options_.inf_to_num().length()); } else if (options_.enable_inf_to_str()) { write_string(options_.inf_to_str(), semantic_tag::none, context, ec); } else { sink_.append(null_constant().data(), null_constant().size()); } } else { if (options_.enable_neginf_to_num()) { sink_.append(options_.neginf_to_num().data(), options_.neginf_to_num().length()); } else if (options_.enable_neginf_to_str()) { write_string(options_.neginf_to_str(), semantic_tag::none, context, ec); } else { sink_.append(null_constant().data(), null_constant().size()); } } } else { fp_(value, sink_); } if (!stack_.empty()) { stack_.back().increment_count(); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t value, semantic_tag, const ser_context&, std::error_code&) final { if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) { sink_.push_back(','); } jsoncons::detail::from_integer(value, sink_); if (!stack_.empty()) { stack_.back().increment_count(); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t value, semantic_tag, const ser_context&, std::error_code&) final { if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) { sink_.push_back(','); } jsoncons::detail::from_integer(value, sink_); if (!stack_.empty()) { stack_.back().increment_count(); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool value, semantic_tag, const ser_context&, std::error_code&) final { if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) { sink_.push_back(','); } if (value) { sink_.append(true_constant().data(), true_constant().size()); } else { sink_.append(false_constant().data(), false_constant().size()); } if (!stack_.empty()) { stack_.back().increment_count(); } JSONCONS_VISITOR_RETURN; } }; using json_stream_encoder = basic_json_encoder>; using wjson_stream_encoder = basic_json_encoder>; using compact_json_stream_encoder = basic_compact_json_encoder>; using compact_wjson_stream_encoder = basic_compact_json_encoder>; using json_string_encoder = basic_json_encoder>; using wjson_string_encoder = basic_json_encoder>; using compact_json_string_encoder = basic_compact_json_encoder>; using compact_wjson_string_encoder = basic_compact_json_encoder>; } // namespace jsoncons #endif // JSONCONS_JSON_ENCODER_HPP jsoncons-1.3.2/include/jsoncons/json_error.hpp000066400000000000000000000133311477700171100215310ustar00rootroot00000000000000/// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_JSON_ERROR_HPP #define JSONCONS_JSON_ERROR_HPP #include #include #include #include namespace jsoncons { enum class json_errc { success = 0, unexpected_eof = 1, source_error, syntax_error, extra_character, max_nesting_depth_exceeded, single_quote, illegal_character_in_string, extra_comma, expected_key, expected_value, invalid_value, expected_colon, illegal_control_character, illegal_escaped_character, expected_codepoint_surrogate_pair, invalid_hex_escape_sequence, invalid_unicode_escape_sequence, leading_zero, invalid_number, expected_comma_or_rbrace, expected_comma_or_rbracket, unexpected_rbracket, unexpected_rbrace, illegal_comment, expected_continuation_byte, over_long_utf8_sequence, illegal_codepoint, illegal_surrogate_value, unpaired_high_surrogate, illegal_unicode_character }; class json_error_category_impl : public std::error_category { public: const char* name() const noexcept final { return "jsoncons/json"; } std::string message(int ev) const final { switch (static_cast(ev)) { case json_errc::unexpected_eof: return "Unexpected end of file"; case json_errc::source_error: return "Source error"; case json_errc::syntax_error: return "JSON syntax_error"; case json_errc::extra_character: return "Unexpected non-whitespace character after JSON text"; case json_errc::max_nesting_depth_exceeded: return "Data item nesting exceeds limit in options"; case json_errc::single_quote: return "JSON strings cannot be quoted with single quotes"; case json_errc::illegal_character_in_string: return "Illegal character in string"; case json_errc::extra_comma: return "Extra comma"; case json_errc::expected_key: return "Expected object member key"; case json_errc::expected_value: return "Expected value"; case json_errc::invalid_value: return "Invalid value"; case json_errc::expected_colon: return "Expected name separator ':'"; case json_errc::illegal_control_character: return "Illegal control character in string"; case json_errc::illegal_escaped_character: return "Illegal escaped character in string"; case json_errc::expected_codepoint_surrogate_pair: return "Invalid codepoint, expected another \\u token to begin the second half of a codepoint surrogate pair."; case json_errc::invalid_hex_escape_sequence: return "Invalid codepoint, expected hexadecimal digit."; case json_errc::invalid_unicode_escape_sequence: return "Invalid codepoint, expected four hexadecimal digits."; case json_errc::leading_zero: return "A number cannot have a leading zero"; case json_errc::invalid_number: return "Invalid number"; case json_errc::expected_comma_or_rbrace: return "Expected comma or right brace '}'"; case json_errc::expected_comma_or_rbracket: return "Expected comma or right bracket ']'"; case json_errc::unexpected_rbrace: return "Unexpected right brace '}'"; case json_errc::unexpected_rbracket: return "Unexpected right bracket ']'"; case json_errc::illegal_comment: return "Illegal comment"; case json_errc::expected_continuation_byte: return "Expected continuation byte"; case json_errc::over_long_utf8_sequence: return "Over long UTF-8 sequence"; case json_errc::illegal_codepoint: return "Illegal codepoint (>= 0xd800 && <= 0xdfff)"; case json_errc::illegal_surrogate_value: return "UTF-16 surrogate values are illegal in UTF-32"; case json_errc::unpaired_high_surrogate: return "Expected low surrogate following the high surrogate"; case json_errc::illegal_unicode_character: return "Illegal unicode character"; default: return "Unknown JSON parser error"; } } }; inline const std::error_category& json_error_category() { static json_error_category_impl instance; return instance; } inline std::error_code make_error_code(json_errc result) { return std::error_code(static_cast(result),json_error_category()); } } // namespace jsoncons namespace std { template<> struct is_error_code_enum : public true_type { }; } // namespace std #endif // JSONCONS_JSON_ERROR_HPP jsoncons-1.3.2/include/jsoncons/json_exception.hpp000066400000000000000000000144141477700171100224010ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_JSON_EXCEPTION_HPP #define JSONCONS_JSON_EXCEPTION_HPP #include #include #include #include // std::string #include // std::error_code #include #include #include // unicode_traits::convert namespace jsoncons { // json_exception class json_exception { public: virtual ~json_exception() = default; virtual const char* what() const noexcept = 0; }; // json_runtime_error template class json_runtime_error { }; template class json_runtime_error::value && extension_traits::is_constructible_from_string::value>::type> : public Base, public virtual json_exception { public: json_runtime_error(const std::string& s) noexcept : Base(s) { } ~json_runtime_error() noexcept { } const char* what() const noexcept override { return Base::what(); } }; class key_not_found : public std::out_of_range, public virtual json_exception { std::string name_; mutable std::string what_; public: template explicit key_not_found(const CharT* key, std::size_t length) noexcept : std::out_of_range("Key not found") { JSONCONS_TRY { unicode_traits::convert(key, length, name_, unicode_traits::conv_flags::strict); } JSONCONS_CATCH(...) { } } virtual ~key_not_found() noexcept { } const char* what() const noexcept override { if (what_.empty()) { JSONCONS_TRY { what_.append(std::out_of_range::what()); what_.append(": '"); what_.append(name_); what_.append("'"); return what_.c_str(); } JSONCONS_CATCH(...) { return std::out_of_range::what(); } } else { return what_.c_str(); } } }; class not_an_object : public std::runtime_error, public virtual json_exception { std::string name_; mutable std::string what_; public: template explicit not_an_object(const CharT* key, std::size_t length) noexcept : std::runtime_error("Attempting to access a member of a value that is not an object") { JSONCONS_TRY { unicode_traits::convert(key, length, name_, unicode_traits::conv_flags::strict); } JSONCONS_CATCH(...) { } } virtual ~not_an_object() noexcept { } const char* what() const noexcept override { if (what_.empty()) { JSONCONS_TRY { what_.append(std::runtime_error::what()); what_.append(": '"); what_.append(name_); what_.append("'"); return what_.c_str(); } JSONCONS_CATCH(...) { return std::runtime_error::what(); } } else { return what_.c_str(); } } }; class ser_error : public std::system_error, public virtual json_exception { std::size_t line_number_{0}; std::size_t column_number_{0}; mutable std::string what_; public: ser_error(std::error_code ec) : std::system_error(ec) { } ser_error(std::error_code ec, const std::string& what_arg) : std::system_error(ec, what_arg) { } ser_error(std::error_code ec, std::size_t position) : std::system_error(ec), column_number_(position) { } ser_error(std::error_code ec, std::size_t line, std::size_t column) : std::system_error(ec), line_number_(line), column_number_(column) { } ser_error(const ser_error& other) = default; ser_error(ser_error&& other) = default; const char* what() const noexcept override { if (what_.empty()) { JSONCONS_TRY { what_.append(std::system_error::what()); if (line_number_ != 0 && column_number_ != 0) { what_.append(" at line "); what_.append(std::to_string(line_number_)); what_.append(" and column "); what_.append(std::to_string(column_number_)); } else if (column_number_ != 0) { what_.append(" at position "); what_.append(std::to_string(column_number_)); } return what_.c_str(); } JSONCONS_CATCH(...) { return std::system_error::what(); } } else { return what_.c_str(); } } std::size_t line() const noexcept { return line_number_; } std::size_t column() const noexcept { return column_number_; } }; } // namespace jsoncons #endif // JSONCONS_JSON_EXCEPTION_HPP jsoncons-1.3.2/include/jsoncons/json_filter.hpp000066400000000000000000001043621477700171100216720ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_JSON_FILTER_HPP #define JSONCONS_JSON_FILTER_HPP #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { template class basic_json_filter : public basic_json_visitor { public: using typename basic_json_visitor::char_type; using typename basic_json_visitor::string_view_type; private: basic_json_visitor* destination_; public: basic_json_filter(basic_json_visitor& visitor) : destination_(std::addressof(visitor)) { } basic_json_visitor& destination() { return *destination_; } private: void visit_flush() override { destination_->flush(); } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->begin_object(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->begin_object(length, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context& context, std::error_code& ec) override { destination_->end_object(context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->begin_array(length, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context& context, std::error_code& ec) override { destination_->end_array(context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type& name, const ser_context& context, std::error_code& ec) override { destination_->key(name, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->string_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& b, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->byte_string_value(b, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& b, uint64_t ext_tag, const ser_context& context, std::error_code& ec) override { destination_->byte_string_value(b, ext_tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->uint64_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->int64_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_half(uint16_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->half_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_double(double value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->double_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->bool_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->null_value(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(half_arg_t, const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->typed_array(half_arg, s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_multi_dim(const jsoncons::span& shape, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination_->begin_multi_dim(shape, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_multi_dim(const ser_context& context, std::error_code& ec) override { destination_->end_multi_dim(context, ec); JSONCONS_VISITOR_RETURN; } }; template class basic_json_tee : public basic_json_visitor { public: using typename basic_json_visitor::char_type; using typename basic_json_visitor::string_view_type; private: basic_json_visitor* destination1_; basic_json_visitor* destination2_; public: basic_json_tee(basic_json_visitor& visitor1, basic_json_visitor& visitor2) : destination1_(std::addressof(visitor1)), destination2_(std::addressof(visitor2)) { } basic_json_visitor& destination() { return *destination1_; } private: void visit_flush() override { destination1_->flush(); destination2_->flush(); } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->begin_object(tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->begin_object(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->begin_object(length, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->begin_object(length, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context& context, std::error_code& ec) override { destination1_->end_object(context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->end_object(context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->begin_array(tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->begin_array(length, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->begin_array(length, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context& context, std::error_code& ec) override { destination1_->end_array(context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->end_array(context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type& name, const ser_context& context, std::error_code& ec) override { destination1_->key(name, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->key(name, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->string_value(value, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->string_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& b, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->byte_string_value(b, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->byte_string_value(b, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& b, uint64_t ext_tag, const ser_context& context, std::error_code& ec) override { destination1_->byte_string_value(b, ext_tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->byte_string_value(b, ext_tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->uint64_value(value, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->uint64_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->int64_value(value, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->int64_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_half(uint16_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->half_value(value, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->half_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_double(double value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->double_value(value, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->double_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->bool_value(value, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->bool_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->null_value(tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->null_value(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(s, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(s, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(s, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(s, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(s, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(s, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(s, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(s, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(half_arg_t, const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(half_arg, s, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->typed_array(half_arg, s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(s, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(s, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_multi_dim(const jsoncons::span& shape, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->begin_multi_dim(shape, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->begin_multi_dim(shape, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_multi_dim(const ser_context& context, std::error_code& ec) override { destination1_->end_multi_dim(context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } destination2_->end_multi_dim(context, ec); JSONCONS_VISITOR_RETURN; } }; template class basic_rename_object_key_filter : public basic_json_filter { public: using typename basic_json_filter::string_view_type; private: std::basic_string name_; std::basic_string new_name_; public: basic_rename_object_key_filter(const std::basic_string& name, const std::basic_string& new_name, basic_json_visitor& visitor) : basic_json_filter(visitor), name_(name), new_name_(new_name) { } private: JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type& name, const ser_context& context, std::error_code& ec) override { if (name == name_) { this->destination().key(new_name_,context, ec); } else { this->destination().key(name,context,ec); } JSONCONS_VISITOR_RETURN; } }; template class json_visitor_adaptor_base : public From { public: using typename From::string_view_type; private: To* destination1_; public: // noncopyable json_visitor_adaptor_base(const json_visitor_adaptor_base&) = delete; json_visitor_adaptor_base(To& visitor) : destination1_(std::addressof(visitor)) { } // moveable json_visitor_adaptor_base(json_visitor_adaptor_base&&) = default; json_visitor_adaptor_base& operator=(const json_visitor_adaptor_base&) = delete; json_visitor_adaptor_base& operator=(json_visitor_adaptor_base&&) = default; To& destination() { return *destination1_; } private: void visit_flush() override { destination1_->flush(); } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->begin_object(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->begin_object(length, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context& context, std::error_code& ec) override { destination1_->end_object(context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->begin_array(length, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context& context, std::error_code& ec) override { destination1_->end_array(context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& b, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->byte_string_value(b, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& b, uint64_t ext_tag, const ser_context& context, std::error_code& ec) override { destination1_->byte_string_value(b, ext_tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_half(uint16_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->half_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_double(double value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->double_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->int64_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->uint64_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->bool_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->null_value(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(half_arg_t, const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(half_arg, s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->typed_array(s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_multi_dim(const jsoncons::span& shape, semantic_tag tag, const ser_context& context, std::error_code& ec) override { destination1_->begin_multi_dim(shape, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_multi_dim(const ser_context& context, std::error_code& ec) override { destination1_->end_multi_dim(context, ec); JSONCONS_VISITOR_RETURN; } }; template class json_visitor_adaptor { }; template class json_visitor_adaptor::value && extension_traits::is_narrow_character::value>::type> : public json_visitor_adaptor_base { using supertype = json_visitor_adaptor_base; using to_char_type = typename To::char_type; using from_char_type = typename From::char_type; public: using typename From::string_view_type; using supertype::destination; public: // noncopyable json_visitor_adaptor(const json_visitor_adaptor&) = delete; // moveable json_visitor_adaptor(json_visitor_adaptor&&) = default; json_visitor_adaptor(To& visitor) : supertype(visitor) { } json_visitor_adaptor& operator=(const json_visitor_adaptor&) = delete; json_visitor_adaptor& operator=(json_visitor_adaptor&&) = default; private: JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type& key, const ser_context& context, std::error_code& ec) override { return destination().key(string_view_type(reinterpret_cast(key.data()),key.size()), context, ec); } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { return destination().string_value(string_view_type(reinterpret_cast(value.data()),value.size()), tag, context, ec); } }; template class json_visitor_adaptor::value && extension_traits::is_narrow_character::value)>::type> : public json_visitor_adaptor_base { using supertype = json_visitor_adaptor_base; public: using typename From::string_view_type; using supertype::destination; public: // noncopyable json_visitor_adaptor(const json_visitor_adaptor&) = delete; // moveable json_visitor_adaptor(json_visitor_adaptor&&) = default; json_visitor_adaptor(To& visitor) : supertype(visitor) { } json_visitor_adaptor& operator=(const json_visitor_adaptor&) = delete; json_visitor_adaptor& operator=(json_visitor_adaptor&&) = default; private: JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type& name, const ser_context& context, std::error_code& ec) override { std::basic_string target; auto result = unicode_traits::convert(name.data(), name.size(), target, unicode_traits::conv_flags::strict); if (result.ec != unicode_traits::conv_errc()) { ec = result.ec; } return destination().key(target, context, ec); } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { std::basic_string target; auto result = unicode_traits::convert(value.data(), value.size(), target,unicode_traits::conv_flags::strict); if (result.ec != unicode_traits::conv_errc()) { JSONCONS_THROW(ser_error(result.ec)); } return destination().string_value(target, tag, context, ec); } }; template json_visitor_adaptor make_json_visitor_adaptor(To& to) { return json_visitor_adaptor(to); } using json_filter = basic_json_filter; using wjson_filter = basic_json_filter; using rename_object_key_filter = basic_rename_object_key_filter; using wrename_object_key_filter = basic_rename_object_key_filter; } // namespace jsoncons #endif // JSONCONS_JSON_FILTER_HPP jsoncons-1.3.2/include/jsoncons/json_fwd.hpp000066400000000000000000000011531477700171100211570ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_JSON_FWD_HPP #define JSONCONS_JSON_FWD_HPP #include // std::allocator namespace jsoncons { struct sorted_policy; template > class basic_json; } // namespace jsoncons #endif // JSONCONS_JSON_FWD_HPP jsoncons-1.3.2/include/jsoncons/json_object.hpp000066400000000000000000001603571477700171100216610ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_JSON_OBJECT_HPP #define JSONCONS_JSON_OBJECT_HPP #include // std::sort, std::stable_sort, std::lower_bound, std::unique #include // assert #include #include #include // std::iterator_traits #include // std::allocator #include #include #include // std::enable_if #include #include #include // std::move #include #include #include #include #include namespace jsoncons { template struct index_key_value { using key_type = typename Json::key_type; using allocator_type = typename Json::allocator_type; key_type name; int64_t index; Json value; template index_key_value(key_type&& Name, int64_t Index, Args&& ... args) : name(std::move(Name)), index(Index), value(std::forward(args)...) { } index_key_value() = default; index_key_value(const index_key_value&) = default; index_key_value(index_key_value&&) = default; index_key_value(const index_key_value& other, const allocator_type& alloc) : name(other.name, alloc), index(0), value(other.value, alloc) { } index_key_value(index_key_value&& other, const allocator_type& alloc) : name(std::move(other.name), alloc), index(0), value(std::move(other.value), alloc) { } index_key_value& operator=(const index_key_value&) = default; index_key_value& operator=(index_key_value&&) = default; }; struct sorted_unique_range_tag { explicit sorted_unique_range_tag() = default; }; // key_value template class key_value { public: using key_type = KeyT; using value_type = ValueT; using string_view_type = typename value_type::string_view_type; using allocator_type = typename ValueT::allocator_type; private: key_type key_; value_type value_; public: key_value() noexcept { } template key_value(key_type&& name, Args&& ... args) : key_(std::move(name)), value_(std::forward(args)...) { } key_value(const key_value& member) : key_(member.key_), value_(member.value_) { } key_value(const key_value& member, const allocator_type& alloc) : key_(member.key_, alloc), value_(member.value_, alloc) { } key_value(key_value&& member) noexcept : key_(std::move(member.key_)), value_(std::move(member.value_)) { } key_value(key_value&& member, const allocator_type& alloc) noexcept : key_(std::move(member.key_), alloc), value_(std::move(member.value_), alloc) { } const key_type& key() const { return key_; } value_type& value() { return value_; } const value_type& value() const { return value_; } template void value(T&& newValue) { value_ = std::forward(newValue); } void swap(key_value& member) noexcept { key_.swap(member.key_); value_.swap(member.value_); } key_value& operator=(const key_value& member) { if (this != & member) { key_ = member.key_; value_ = member.value_; } return *this; } key_value& operator=(key_value&& member) noexcept { if (this != &member) { key_.swap(member.key_); value_.swap(member.value_); } return *this; } void shrink_to_fit() { key_.shrink_to_fit(); value_.shrink_to_fit(); } friend bool operator==(const key_value& lhs, const key_value& rhs) noexcept { return lhs.key_ == rhs.key_ && lhs.value_ == rhs.value_; } friend bool operator!=(const key_value& lhs, const key_value& rhs) noexcept { return !(lhs == rhs); } friend bool operator<(const key_value& lhs, const key_value& rhs) noexcept { if (lhs.key_ < rhs.key_) { return true; } if (lhs.key_ == rhs.key_ && lhs.value_ < rhs.value_) { return true; } return false; } friend bool operator<=(const key_value& lhs, const key_value& rhs) noexcept { return !(rhs < lhs); } friend bool operator>(const key_value& lhs, const key_value& rhs) noexcept { return !(lhs <= rhs); } friend bool operator>=(const key_value& lhs, const key_value& rhs) noexcept { return !(lhs < rhs); } friend void swap(key_value& a, key_value& b) noexcept( noexcept(std::declval().swap(std::declval()))) { a.swap(b); } }; // Structured Bindings Support // See https://blog.tartanllama.xyz/structured-bindings/ template::type = 0> auto get(const key_value& i) -> decltype(i.key()) { return i.key(); } // Structured Bindings Support // See https://blog.tartanllama.xyz/structured-bindings/ template::type = 0> auto get(const key_value& i) -> decltype(i.value()) { return i.value(); } } // namespace jsoncons namespace std { #if defined(__clang__) // Fix: https://github.com/nlohmann/json/issues/1401 #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmismatched-tags" #endif template struct tuple_size> : public std::integral_constant {}; template struct tuple_element<0, jsoncons::key_value> { using type = Key; }; template struct tuple_element<1, jsoncons::key_value> { using type = Value; }; #if defined(__clang__) #pragma clang diagnostic pop #endif } // namespace std namespace jsoncons { template struct get_key_value { using key_value_type = key_value; template key_value_type operator()(const std::pair& p) // Remove { return key_value_type(p.first,p.second); } template key_value_type operator()(std::pair&& p) { return key_value_type(std::forward(p.first),std::forward(p.second)); } template const key_value_type& operator()(const key_value& p) { return p; } template key_value_type operator()(key_value&& p) { return std::move(p); } }; struct sort_key_order { explicit sort_key_order() = default; }; struct preserve_key_order { explicit preserve_key_order() = default; }; // Sort keys template class SequenceContainer = std::vector> class sorted_json_object : public allocator_holder { public: using allocator_type = typename Json::allocator_type; using key_type = KeyT; using key_value_type = key_value; using char_type = typename Json::char_type; using string_view_type = typename Json::string_view_type; private: struct Comp { bool operator() (const key_value_type& kv, string_view_type k) const { return kv.key() < k; } bool operator() (string_view_type k, const key_value_type& kv) const { return k < kv.key(); } }; using key_value_allocator_type = typename std::allocator_traits:: template rebind_alloc; using key_value_container_type = SequenceContainer; key_value_container_type members_; public: using iterator = typename key_value_container_type::iterator; using const_iterator = typename key_value_container_type::const_iterator; using allocator_holder::get_allocator; sorted_json_object() { } explicit sorted_json_object(const allocator_type& alloc) : allocator_holder(alloc), members_(key_value_allocator_type(alloc)) { } sorted_json_object(const sorted_json_object& other) : allocator_holder(other.get_allocator()), members_(other.members_) { } sorted_json_object(const sorted_json_object& other, const allocator_type& alloc) : allocator_holder(alloc), members_(other.members_,key_value_allocator_type(alloc)) { } sorted_json_object(sorted_json_object&& other) noexcept : allocator_holder(other.get_allocator()), members_(std::move(other.members_)) { } sorted_json_object(sorted_json_object&& other,const allocator_type& alloc) : allocator_holder(alloc), members_(std::move(other.members_),key_value_allocator_type(alloc)) { } sorted_json_object& operator=(const sorted_json_object& other) { members_ = other.members_; return *this; } sorted_json_object& operator=(sorted_json_object&& other) noexcept { other.swap(*this); return *this; } template sorted_json_object(InputIt first, InputIt last) { std::size_t count = std::distance(first,last); members_.reserve(count); for (auto it = first; it != last; ++it) { members_.emplace_back(key_type((*it).first,get_allocator()), (*it).second); } std::stable_sort(members_.begin(),members_.end(), [](const key_value_type& a, const key_value_type& b) -> bool {return a.key().compare(b.key()) < 0;}); auto last2 = std::unique(members_.begin(), members_.end(), [](const key_value_type& a, const key_value_type& b) -> bool { return !(a.key().compare(b.key()));}); members_.erase(last2, members_.end()); } template sorted_json_object(InputIt first, InputIt last, const allocator_type& alloc) : allocator_holder(alloc), members_(key_value_allocator_type(alloc)) { std::size_t count = std::distance(first,last); members_.reserve(count); for (auto it = first; it != last; ++it) { members_.emplace_back(key_type((*it).first.c_str(), (*it).first.size(), get_allocator()), (*it).second); } std::stable_sort(members_.begin(), members_.end(), [](const key_value_type& a, const key_value_type& b) -> bool {return a.key().compare(b.key()) < 0;}); auto last2 = std::unique(members_.begin(), members_.end(), [](const key_value_type& a, const key_value_type& b) -> bool { return !(a.key().compare(b.key()));}); members_.erase(last2, members_.end()); } sorted_json_object(const std::initializer_list,Json>>& init, const allocator_type& alloc = allocator_type()) : allocator_holder(alloc), members_(key_value_allocator_type(alloc)) { members_.reserve(init.size()); for (auto& item : init) { insert_or_assign(item.first, item.second); } } ~sorted_json_object() noexcept { flatten_and_destroy(); } bool empty() const { return members_.empty(); } void swap(sorted_json_object& other) noexcept { members_.swap(other.members_); } iterator begin() { return members_.begin(); } iterator end() { return members_.end(); } const_iterator begin() const { return members_.begin(); } const_iterator end() const { return members_.end(); } std::size_t size() const {return members_.size();} std::size_t capacity() const {return members_.capacity();} void clear() {members_.clear();} void shrink_to_fit() { for (std::size_t i = 0; i < members_.size(); ++i) { members_[i].shrink_to_fit(); } members_.shrink_to_fit(); } void reserve(std::size_t n) {members_.reserve(n);} Json& at(std::size_t i) { if (i >= members_.size()) { JSONCONS_THROW(json_runtime_error("Invalid array subscript")); } return members_[i].value(); } const Json& at(std::size_t i) const { if (i >= members_.size()) { JSONCONS_THROW(json_runtime_error("Invalid array subscript")); } return members_[i].value(); } iterator find(const string_view_type& name) noexcept { auto p = std::equal_range(members_.begin(),members_.end(), name, Comp()); return p.first == p.second ? members_.end() : p.first; } const_iterator find(const string_view_type& name) const noexcept { auto p = std::equal_range(members_.begin(),members_.end(), name, Comp()); return p.first == p.second ? members_.end() : p.first; } iterator erase(const_iterator pos) { return members_.erase(pos); } iterator erase(const_iterator first, const_iterator last) { return members_.erase(first,last); } void erase(const string_view_type& name) { auto it = find(name); if (it != members_.end()) { members_.erase(it); } } static bool compare(const index_key_value& item1, const index_key_value& item2) { int comp = item1.name.compare(item2.name); if (comp < 0) return true; if (comp == 0) return item1.index < item2.index; return false; } void uninitialized_init(index_key_value* items, std::size_t count) { if (count > 0) { members_.reserve(count); std::sort(items, items+count, compare); members_.emplace_back(key_type(items[0].name.data(), items[0].name.size(), get_allocator()), std::move(items[0].value)); for (std::size_t i = 1; i < count; ++i) { auto& item = items[i]; if (item.name != items[i-1].name) { members_.emplace_back(key_type(item.name.data(), item.name.size(), get_allocator()), std::move(item.value)); } } } } template void insert(InputIt first, InputIt last) { for (auto it = first; it != last; ++it) { members_.emplace_back(key_type((*it).first.c_str(), (*it).first.size(), get_allocator()), (*it).second); } std::stable_sort(members_.begin(),members_.end(), [](const key_value_type& a, const key_value_type& b) -> bool {return a.key().compare(b.key()) < 0;}); auto last2 = std::unique(members_.begin(), members_.end(), [](const key_value_type& a, const key_value_type& b) -> bool { return !(a.key().compare(b.key()));}); members_.erase(last2, members_.end()); } template void insert(sorted_unique_range_tag, InputIt first, InputIt last) { if (first != last) { auto it = find(convert(*first).key()); if (it != members_.end()) { for (auto s = first; s != last; ++s) { it = members_.emplace(it, key_type(s->first, get_allocator()), s->second); } } else { for (auto s = first; s != last; ++s) { members_.emplace_back(convert(*s)); } } } } // insert_or_assign template typename std::enable_if::is_always_equal::value,std::pair>::type insert_or_assign(const string_view_type& name, T&& value) { bool inserted; auto it = std::lower_bound(members_.begin(),members_.end(), name, Comp()); if (it == members_.end()) { members_.emplace_back(key_type(name.begin(),name.end()), std::forward(value)); inserted = true; it = members_.begin() + members_.size() - 1; } else if ((*it).key() == name) { (*it).value(Json(std::forward(value))); inserted = false; // assigned } else { it = members_.emplace(it, key_type(name.begin(),name.end()), std::forward(value)); inserted = true; } return std::make_pair(it,inserted); } template typename std::enable_if::is_always_equal::value,std::pair>::type insert_or_assign(const string_view_type& name, T&& value) { bool inserted; auto it = std::lower_bound(members_.begin(),members_.end(), name, Comp()); if (it == members_.end()) { members_.emplace_back(key_type(name.begin(),name.end(), get_allocator()), std::forward(value)); inserted = true; it = members_.begin() + members_.size() - 1; } else if ((*it).key() == name) { (*it).value(Json(std::forward(value), get_allocator())); inserted = false; // assigned } else { it = members_.emplace(it, key_type(name.begin(),name.end(), get_allocator()), std::forward(value)); inserted = true; } return std::make_pair(it,inserted); } // try_emplace template typename std::enable_if::is_always_equal::value,std::pair>::type try_emplace(const string_view_type& name, Args&&... args) { bool inserted; auto it = std::lower_bound(members_.begin(),members_.end(), name, Comp()); if (it == members_.end()) { members_.emplace_back(key_type(name.begin(),name.end()), std::forward(args)...); it = members_.begin() + members_.size() - 1; inserted = true; } else if ((*it).key() == name) { inserted = false; } else { it = members_.emplace(it, key_type(name.begin(),name.end()), std::forward(args)...); inserted = true; } return std::make_pair(it,inserted); } template typename std::enable_if::is_always_equal::value,std::pair>::type try_emplace(const string_view_type& name, Args&&... args) { bool inserted; auto it = std::lower_bound(members_.begin(),members_.end(), name, Comp()); if (it == members_.end()) { members_.emplace_back(key_type(name.begin(),name.end(), get_allocator()), std::forward(args)...); it = members_.begin() + members_.size() - 1; inserted = true; } else if ((*it).key() == name) { inserted = false; } else { it = members_.emplace(it, key_type(name.begin(),name.end(), get_allocator()), std::forward(args)...); inserted = true; } return std::make_pair(it,inserted); } template typename std::enable_if::is_always_equal::value,iterator>::type try_emplace(iterator hint, const string_view_type& name, Args&&... args) { iterator it = hint; if (hint != members_.end() && hint->key() <= name) { it = std::lower_bound(hint,members_.end(), name, Comp()); } else { it = std::lower_bound(members_.begin(),members_.end(), name, Comp()); } if (it == members_.end()) { members_.emplace_back(key_type(name.begin(),name.end()), std::forward(args)...); it = members_.begin() + (members_.size() - 1); } else if ((*it).key() == name) { } else { it = members_.emplace(it, key_type(name.begin(),name.end()), std::forward(args)...); } return it; } template typename std::enable_if::is_always_equal::value,iterator>::type try_emplace(iterator hint, const string_view_type& name, Args&&... args) { iterator it = hint; if (hint != members_.end() && hint->key() <= name) { it = std::lower_bound(hint,members_.end(), name, Comp()); } else { it = std::lower_bound(members_.begin(),members_.end(), name, Comp()); } if (it == members_.end()) { members_.emplace_back(key_type(name.begin(),name.end(), get_allocator()), std::forward(args)...); it = members_.begin() + (members_.size() - 1); } else if ((*it).key() == name) { } else { it = members_.emplace(it, key_type(name.begin(),name.end(), get_allocator()), std::forward(args)...); } return it; } // insert_or_assign template typename std::enable_if::is_always_equal::value,iterator>::type insert_or_assign(iterator hint, const string_view_type& name, T&& value) { iterator it; if (hint != members_.end() && hint->key() <= name) { it = std::lower_bound(hint,members_.end(), name, [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); } else { it = std::lower_bound(members_.begin(),members_.end(), name, [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); } if (it == members_.end()) { members_.emplace_back(key_type(name.begin(),name.end()), std::forward(value)); it = members_.begin() + (members_.size() - 1); } else if ((*it).key() == name) { (*it).value(Json(std::forward(value))); } else { it = members_.emplace(it, key_type(name.begin(),name.end()), std::forward(value)); } return it; } template typename std::enable_if::is_always_equal::value,iterator>::type insert_or_assign(iterator hint, const string_view_type& name, T&& value) { iterator it; if (hint != members_.end() && hint->key() <= name) { it = std::lower_bound(hint,members_.end(), name, Comp()); } else { it = std::lower_bound(members_.begin(),members_.end(), name, Comp()); } if (it == members_.end()) { members_.emplace_back(key_type(name.begin(),name.end(), get_allocator()), std::forward(value)); it = members_.begin() + (members_.size() - 1); } else if ((*it).key() == name) { (*it).value(Json(std::forward(value),get_allocator())); } else { it = members_.emplace(it, key_type(name.begin(),name.end(), get_allocator()), std::forward(value)); } return it; } // merge void merge(const sorted_json_object& source) { for (auto it = source.begin(); it != source.end(); ++it) { try_emplace((*it).key(),(*it).value()); } } void merge(sorted_json_object&& source) { auto it = std::make_move_iterator(source.begin()); auto end = std::make_move_iterator(source.end()); for (; it != end; ++it) { auto pos = std::lower_bound(members_.begin(),members_.end(), (*it).key(), Comp()); if (pos == members_.end() ) { members_.emplace_back(*it); } else if ((*it).key() != pos->key()) { members_.emplace(pos,*it); } } } void merge(iterator hint, const sorted_json_object& source) { for (auto it = source.begin(); it != source.end(); ++it) { hint = try_emplace(hint, (*it).key(),(*it).value()); } } void merge(iterator hint, sorted_json_object&& source) { auto it = std::make_move_iterator(source.begin()); auto end = std::make_move_iterator(source.end()); for (; it != end; ++it) { iterator pos; if (hint != members_.end() && hint->key() <= (*it).key()) { pos = std::lower_bound(hint,members_.end(), (*it).key(), Comp()); } else { pos = std::lower_bound(members_.begin(),members_.end(), (*it).key(), Comp()); } if (pos == members_.end() ) { members_.emplace_back(*it); hint = members_.begin() + (members_.size() - 1); } else if ((*it).key() != pos->key()) { hint = members_.emplace(pos,*it); } } } // merge_or_update void merge_or_update(const sorted_json_object& source) { for (auto it = source.begin(); it != source.end(); ++it) { insert_or_assign((*it).key(),(*it).value()); } } void merge_or_update(sorted_json_object&& source) { auto it = std::make_move_iterator(source.begin()); auto end = std::make_move_iterator(source.end()); for (; it != end; ++it) { auto pos = std::lower_bound(members_.begin(),members_.end(), (*it).key(), Comp()); if (pos == members_.end() ) { members_.emplace_back(*it); } else { pos->value((*it).value()); } } } void merge_or_update(iterator hint, const sorted_json_object& source) { for (auto it = source.begin(); it != source.end(); ++it) { hint = insert_or_assign(hint, (*it).key(),(*it).value()); } } void merge_or_update(iterator hint, sorted_json_object&& source) { auto it = std::make_move_iterator(source.begin()); auto end = std::make_move_iterator(source.end()); for (; it != end; ++it) { iterator pos; if (hint != members_.end() && hint->key() <= (*it).key()) { pos = std::lower_bound(hint,members_.end(), (*it).key(), Comp()); } else { pos = std::lower_bound(members_.begin(),members_.end(), (*it).key(), Comp()); } if (pos == members_.end() ) { members_.emplace_back(*it); hint = members_.begin() + (members_.size() - 1); } else { pos->value((*it).value()); hint = pos; } } } bool operator==(const sorted_json_object& rhs) const { return members_ == rhs.members_; } bool operator<(const sorted_json_object& rhs) const { return members_ < rhs.members_; } private: void flatten_and_destroy() noexcept { if (!members_.empty()) { json_array temp(get_allocator()); for (auto& kv : members_) { switch (kv.value().storage_kind()) { case json_storage_kind::array: case json_storage_kind::object: if (!kv.value().empty()) { temp.emplace_back(std::move(kv.value())); } break; default: break; } } } } }; // Preserve order template class SequenceContainer = std::vector> class order_preserving_json_object : public allocator_holder { public: using allocator_type = typename Json::allocator_type; using char_type = typename Json::char_type; using key_type = KeyT; using string_view_type = typename Json::string_view_type; using key_value_type = key_value; private: struct MyHash { std::uintmax_t operator()(const key_type& s) const noexcept { const int p = 31; const int m = static_cast(1e9) + 9; std::uintmax_t hash_value = 0; std::uintmax_t p_pow = 1; for (char_type c : s) { hash_value = (hash_value + (c - 'a' + 1) * p_pow) % m; p_pow = (p_pow * p) % m; } return hash_value; } }; using key_value_allocator_type = typename std::allocator_traits:: template rebind_alloc; using key_value_container_type = SequenceContainer; key_value_container_type members_; struct Comp { const key_value_container_type& members_; Comp(const key_value_container_type& members_) : members_(members_) { } bool operator() (std::size_t i, string_view_type k) const { return members_.at(i).key() < k; } bool operator() (string_view_type k, std::size_t i) const { return k < members_.at(i).key(); } }; public: using iterator = typename key_value_container_type::iterator; using const_iterator = typename key_value_container_type::const_iterator; using allocator_holder::get_allocator; order_preserving_json_object() { } order_preserving_json_object(const allocator_type& alloc) : allocator_holder(alloc), members_(key_value_allocator_type(alloc)) { } order_preserving_json_object(const order_preserving_json_object& val) : allocator_holder(val.get_allocator()), members_(val.members_) { } order_preserving_json_object(order_preserving_json_object&& val,const allocator_type& alloc) : allocator_holder(alloc), members_(std::move(val.members_),key_value_allocator_type(alloc)) { } order_preserving_json_object(order_preserving_json_object&& val) noexcept : allocator_holder(val.get_allocator()), members_(std::move(val.members_)) { } order_preserving_json_object(const order_preserving_json_object& val, const allocator_type& alloc) : allocator_holder(alloc), members_(val.members_,key_value_allocator_type(alloc)) { } template order_preserving_json_object(InputIt first, InputIt last) { std::unordered_set keys; for (auto it = first; it != last; ++it) { auto kv = get_key_value()(*it); if (keys.find(kv.key()) == keys.end()) { keys.emplace(kv.key()); members_.emplace_back(std::move(kv)); } } } template order_preserving_json_object(InputIt first, InputIt last, const allocator_type& alloc) : allocator_holder(alloc), members_(key_value_allocator_type(alloc)) { std::unordered_set keys; for (auto it = first; it != last; ++it) { auto kv = get_key_value()(*it); if (keys.find(kv.key()) == keys.end()) { keys.emplace(kv.key()); members_.emplace_back(std::move(kv)); } } } order_preserving_json_object(std::initializer_list,Json>> init, const allocator_type& alloc = allocator_type()) : allocator_holder(alloc), members_(key_value_allocator_type(alloc)) { members_.reserve(init.size()); for (auto& item : init) { insert_or_assign(item.first, item.second); } } ~order_preserving_json_object() noexcept { flatten_and_destroy(); } order_preserving_json_object& operator=(order_preserving_json_object&& val) { val.swap(*this); return *this; } order_preserving_json_object& operator=(const order_preserving_json_object& val) { members_ = val.members_; return *this; } void swap(order_preserving_json_object& other) noexcept { members_.swap(other.members_); } bool empty() const { return members_.empty(); } iterator begin() { return members_.begin(); } iterator end() { return members_.end(); } const_iterator begin() const { return members_.begin(); } const_iterator end() const { return members_.end(); } std::size_t size() const {return members_.size();} std::size_t capacity() const {return members_.capacity();} void clear() { members_.clear(); } void shrink_to_fit() { for (std::size_t i = 0; i < members_.size(); ++i) { members_[i].shrink_to_fit(); } members_.shrink_to_fit(); } void reserve(std::size_t n) {members_.reserve(n);} Json& at(std::size_t i) { if (i >= members_.size()) { JSONCONS_THROW(json_runtime_error("Invalid array subscript")); } return members_[i].value(); } const Json& at(std::size_t i) const { if (i >= members_.size()) { JSONCONS_THROW(json_runtime_error("Invalid array subscript")); } return members_[i].value(); } iterator find(const string_view_type& name) noexcept { bool found = false; auto it = members_.begin(); while (!found && it != members_.end()) { if ((*it).key() == name) { found = true; } else { ++it; } } return it; } const_iterator find(const string_view_type& name) const noexcept { bool found = false; auto it = members_.begin(); while (!found && it != members_.end()) { if ((*it).key() == name) { found = true; } else { ++it; } } return it; } iterator erase(const_iterator pos) { if (pos != members_.end()) { return members_.erase(pos); } else { return members_.end(); } } iterator erase(const_iterator first, const_iterator last) { std::size_t pos1 = first == members_.end() ? members_.size() : first - members_.begin(); std::size_t pos2 = last == members_.end() ? members_.size() : last - members_.begin(); if (pos1 < members_.size() && pos2 <= members_.size()) { return members_.erase(first,last); } else { return members_.end(); } } void erase(const string_view_type& name) { auto pos = find(name); if (pos != members_.end()) { members_.erase(pos); } } static bool compare1(const index_key_value& item1, const index_key_value& item2) { int comp = item1.name.compare(item2.name); if (comp < 0) return true; if (comp == 0) return item1.index < item2.index; return false; } static bool compare2(const index_key_value& item1, const index_key_value& item2) { return item1.index < item2.index; } void uninitialized_init(index_key_value* items, std::size_t length) { if (length > 0) { std::sort(items, items+length, compare1); std::size_t count = 1; for (std::size_t i = 1; i < length; ++i) { while (i < length && items[i-1].name == items[i].name) { ++i; } if (i < length) { if (i != count) { items[count] = std::move(items[i]); } ++count; } } std::sort(items, items+count, compare2); members_.reserve(count); for (std::size_t i = 0; i < count; ++i) { members_.emplace_back(std::move(items[i].name), std::move(items[i].value)); } } } template void insert(InputIt first, InputIt last) { std::unordered_set keys; for (auto it = first; it != last; ++it) { key_type key{(*it).first.c_str(), (*it).first.size(), get_allocator()}; if (keys.find(key) == keys.end()) { keys.emplace(key.c_str(), key.size(), get_allocator()); members_.emplace_back(std::move(key), (*it).second); } } } template void insert(sorted_unique_range_tag, InputIt first, InputIt last) { for (auto it = first; it != last; ++it) { members_.emplace_back(get_key_value()(*it)); } } template typename std::enable_if::is_always_equal::value,std::pair>::type insert_or_assign(const string_view_type& name, T&& value) { auto it = find(name); if (it == members_.end()) { members_.emplace_back(key_type(name.begin(), name.end()), std::forward(value)); auto pos = members_.begin() + (members_.size() - 1); return std::make_pair(pos, true); } else { (*it).value(Json(std::forward(value))); return std::make_pair(it,false); } } template typename std::enable_if::is_always_equal::value,std::pair>::type insert_or_assign(const string_view_type& name, T&& value) { auto it = find(name); if (it == members_.end()) { members_.emplace_back(key_type(name.begin(),name.end(),get_allocator()), std::forward(value)); auto pos = members_.begin() + (members_.size()-1); return std::make_pair(pos,true); } else { (*it).value(Json(std::forward(value),get_allocator())); return std::make_pair(it,false); } } template typename std::enable_if::is_always_equal::value,iterator>::type insert_or_assign(iterator hint, const string_view_type& key, T&& value) { if (hint == members_.end()) { auto result = insert_or_assign(key, std::forward(value)); return result.first; } else { auto it = find(hint, key); if (it == members_.end()) { members_.emplace_back(key_type(key.begin(), key.end()), std::forward(value)); auto pos = members_.begin() + (members_.size() - 1); return pos; } else { (*it).value(Json(std::forward(value))); return it; } } } template typename std::enable_if::is_always_equal::value,iterator>::type insert_or_assign(iterator hint, const string_view_type& key, T&& value) { if (hint == members_.end()) { auto result = insert_or_assign(key, std::forward(value)); return result.first; } else { auto it = find(hint, key); if (it == members_.end()) { members_.emplace_back(key_type(key.begin(),key.end(),get_allocator()), std::forward(value)); auto pos = members_.begin() + (members_.size()-1); return pos; } else { (*it).value(Json(std::forward(value),get_allocator())); return it; } } } // merge void merge(const order_preserving_json_object& source) { for (auto it = source.begin(); it != source.end(); ++it) { try_emplace((*it).key(),(*it).value()); } } void merge(order_preserving_json_object&& source) { auto it = std::make_move_iterator(source.begin()); auto end = std::make_move_iterator(source.end()); for (; it != end; ++it) { auto pos = find((*it).key()); if (pos == members_.end() ) { try_emplace((*it).key(),std::move((*it).value())); } } } void merge(iterator hint, const order_preserving_json_object& source) { std::size_t pos = hint - members_.begin(); for (auto it = source.begin(); it != source.end(); ++it) { hint = try_emplace(hint, (*it).key(),(*it).value()); std::size_t newpos = hint - members_.begin(); if (newpos == pos) { ++hint; pos = hint - members_.begin(); } else { hint = members_.begin() + pos; } } } void merge(iterator hint, order_preserving_json_object&& source) { std::size_t pos = hint - members_.begin(); auto it = std::make_move_iterator(source.begin()); auto end = std::make_move_iterator(source.end()); for (; it != end; ++it) { hint = try_emplace(hint, (*it).key(), std::move((*it).value())); std::size_t newpos = hint - members_.begin(); if (newpos == pos) { ++hint; pos = hint - members_.begin(); } else { hint = members_.begin() + pos; } } } // merge_or_update void merge_or_update(const order_preserving_json_object& source) { for (auto it = source.begin(); it != source.end(); ++it) { insert_or_assign((*it).key(),(*it).value()); } } void merge_or_update(order_preserving_json_object&& source) { auto it = std::make_move_iterator(source.begin()); auto end = std::make_move_iterator(source.end()); for (; it != end; ++it) { auto pos = find((*it).key()); if (pos == members_.end() ) { insert_or_assign((*it).key(),std::move((*it).value())); } else { pos->value(std::move((*it).value())); } } } void merge_or_update(iterator hint, const order_preserving_json_object& source) { std::size_t pos = hint - members_.begin(); for (auto it = source.begin(); it != source.end(); ++it) { hint = insert_or_assign(hint, (*it).key(),(*it).value()); std::size_t newpos = hint - members_.begin(); if (newpos == pos) { ++hint; pos = hint - members_.begin(); } else { hint = members_.begin() + pos; } } } void merge_or_update(iterator hint, order_preserving_json_object&& source) { std::size_t pos = hint - members_.begin(); auto it = std::make_move_iterator(source.begin()); auto end = std::make_move_iterator(source.end()); for (; it != end; ++it) { hint = insert_or_assign(hint, (*it).key(), std::move((*it).value())); std::size_t newpos = hint - members_.begin(); if (newpos == pos) { ++hint; pos = hint - members_.begin(); } else { hint = members_.begin() + pos; } } } // try_emplace template typename std::enable_if::is_always_equal::value,std::pair>::type try_emplace(const string_view_type& name, Args&&... args) { auto it = find(name); if (it == members_.end()) { members_.emplace_back(key_type(name.begin(), name.end()), std::forward(args)...); auto pos = members_.begin() + (members_.size()-1); return std::make_pair(pos,true); } else { return std::make_pair(it,false); } } template typename std::enable_if::is_always_equal::value,std::pair>::type try_emplace(const string_view_type& key, Args&&... args) { auto it = find(key); if (it == members_.end()) { members_.emplace_back(key_type(key.begin(),key.end(), get_allocator()), std::forward(args)...); auto pos = members_.begin() + members_.size(); return std::make_pair(pos,true); } else { return std::make_pair(it,false); } } template typename std::enable_if::is_always_equal::value,iterator>::type try_emplace(iterator hint, const string_view_type& key, Args&&... args) { if (hint == members_.end()) { auto result = try_emplace(key, std::forward(args)...); return result.first; } else { auto it = find(hint, key); if (it == members_.end()) { members_.emplace_back(key_type(key.begin(),key.end(), get_allocator()), std::forward(args)...); auto pos = members_.begin() + members_.size(); return pos; } else { return it; } } } template typename std::enable_if::is_always_equal::value,iterator>::type try_emplace(iterator hint, const string_view_type& key, Args&&... args) { if (hint == members_.end()) { auto result = try_emplace(key, std::forward(args)...); return result.first; } else { auto it = find(hint, key); if (it == members_.end()) { members_.emplace_back(key_type(key.begin(),key.end(), get_allocator()), std::forward(args)...); auto pos = members_.begin() + members_.size(); return pos; } else { return it; } } } bool operator==(const order_preserving_json_object& rhs) const { return members_ == rhs.members_; } bool operator<(const order_preserving_json_object& rhs) const { return members_ < rhs.members_; } private: iterator find(iterator hint, const string_view_type& name) noexcept { bool found = false; auto it = hint; while (!found && it != members_.end()) { if ((*it).key() == name) { found = true; } else { ++it; } } return found ? it : find(name); } void flatten_and_destroy() noexcept { if (!members_.empty()) { json_array temp(get_allocator()); for (auto& kv : members_) { switch (kv.value().storage_kind()) { case json_storage_kind::array: case json_storage_kind::object: if (!kv.value().empty()) { temp.emplace_back(std::move(kv.value())); } break; default: break; } } } } }; } // namespace jsoncons #endif // JSONCONS_JSON_OBJECT_HPP jsoncons-1.3.2/include/jsoncons/json_options.hpp000066400000000000000000000520001477700171100220670ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_JSON_OPTIONS_HPP #define JSONCONS_JSON_OPTIONS_HPP #include #include #include #include #include #include #include #include namespace jsoncons { enum class float_chars_format : uint8_t {general,fixed,scientific,hex}; enum class indenting : uint8_t {no_indent = 0, indent = 1}; enum class line_split_kind : uint8_t {same_line=1, new_line, multi_line}; enum class bignum_format_kind : uint8_t {raw, #if !defined(JSONCONS_NO_DEPRECATED) number=raw, // deprecated, use raw instead #endif base10, base64, base64url}; #if !defined(JSONCONS_NO_DEPRECATED) JSONCONS_DEPRECATED_MSG("Instead, use bignum_format_kind") typedef bignum_format_kind bigint_chars_format; #endif enum class byte_string_chars_format : uint8_t {none=0,base16,base64,base64url}; enum class spaces_option : uint8_t {no_spaces=0,space_after,space_before,space_before_and_after}; struct default_json_parsing { bool operator()(json_errc ec, const ser_context&) noexcept { return ec == json_errc::illegal_comment; } }; struct strict_json_parsing { bool operator()(json_errc, const ser_context&) noexcept { return false; } }; struct allow_trailing_commas { bool operator()(const std::error_code& ec, const ser_context&) noexcept { return ec == json_errc::illegal_comment || ec == jsoncons::json_errc::extra_comma; } }; template class basic_json_options; template class basic_json_options_common { friend class basic_json_options; public: using char_type = CharT; using string_type = std::basic_string; private: bool enable_nan_to_num_:1; bool enable_inf_to_num_:1; bool enable_neginf_to_num_:1; bool enable_nan_to_str_:1; bool enable_inf_to_str_:1; bool enable_neginf_to_str_:1; bool enable_str_to_nan_:1; bool enable_str_to_inf_:1; bool enable_str_to_neginf_:1; string_type nan_to_num_; string_type inf_to_num_; string_type neginf_to_num_; string_type nan_to_str_; string_type inf_to_str_; string_type neginf_to_str_; int max_nesting_depth_; protected: basic_json_options_common() : enable_nan_to_num_(false), enable_inf_to_num_(false), enable_neginf_to_num_(false), enable_nan_to_str_(false), enable_inf_to_str_(false), enable_neginf_to_str_(false), enable_str_to_nan_(false), enable_str_to_inf_(false), enable_str_to_neginf_(false), max_nesting_depth_(1024) {} virtual ~basic_json_options_common() = default; basic_json_options_common(const basic_json_options_common&) = default; basic_json_options_common& operator=(const basic_json_options_common&) = default; basic_json_options_common(basic_json_options_common&&) = default; //basic_json_options_common& operator=(basic_json_options_common&&) = default; public: bool enable_nan_to_num() const { return enable_nan_to_num_; } bool enable_inf_to_num() const { return enable_inf_to_num_; } bool enable_neginf_to_num() const { return enable_neginf_to_num_ || enable_inf_to_num_; } bool enable_nan_to_str() const { return enable_nan_to_str_; } bool enable_str_to_nan() const { return enable_str_to_nan_; } bool enable_inf_to_str() const { return enable_inf_to_str_; } bool enable_str_to_inf() const { return enable_str_to_inf_; } bool enable_neginf_to_str() const { return enable_neginf_to_str_ || enable_inf_to_str_; } bool enable_str_to_neginf() const { return enable_str_to_neginf_ || enable_str_to_inf_; } string_type nan_to_num() const { if (enable_nan_to_num_) { return nan_to_num_; } else { return nan_to_num_; // empty string } } string_type inf_to_num() const { if (enable_inf_to_num_) { return inf_to_num_; } else { return inf_to_num_; // empty string } } string_type neginf_to_num() const { if (enable_neginf_to_num_) { return neginf_to_num_; } else if (enable_inf_to_num_) { string_type s; s.push_back('-'); s.append(inf_to_num_); return s; } else { return neginf_to_num_; // empty string } } string_type nan_to_str() const { return nan_to_str_; } string_type inf_to_str() const { return inf_to_str_; } string_type neginf_to_str() const { if (enable_neginf_to_str_) { return neginf_to_str_; } else if (enable_inf_to_str_) { string_type s; s.push_back('-'); s.append(inf_to_str_); return s; } else { return neginf_to_str_; // empty string } } int max_nesting_depth() const { return max_nesting_depth_; } }; template class basic_json_decode_options : public virtual basic_json_options_common { friend class basic_json_options; using super_type = basic_json_options_common; public: using typename super_type::char_type; using typename super_type::string_type; private: bool lossless_number_{false}; bool allow_comments_{true}; bool allow_trailing_comma_{false}; std::function err_handler_; public: basic_json_decode_options() : err_handler_(default_json_parsing()) { } basic_json_decode_options(const basic_json_decode_options&) = default; basic_json_decode_options(basic_json_decode_options&& other) noexcept : super_type(std::move(other)), lossless_number_(other.lossless_number_), allow_comments_(other.allow_comments_), allow_trailing_comma_(other.allow_trailing_comma_), err_handler_(std::move(other.err_handler_)) { } protected: basic_json_decode_options& operator=(const basic_json_decode_options&) = default; basic_json_decode_options& operator=(basic_json_decode_options&&) = default; public: bool lossless_number() const { return lossless_number_; } bool allow_comments() const { return allow_comments_; } bool allow_trailing_comma() const { return allow_trailing_comma_; } const std::function& err_handler() const { return err_handler_; } }; template class basic_json_encode_options : public virtual basic_json_options_common { friend class basic_json_options; using super_type = basic_json_options_common; public: using typename super_type::char_type; using typename super_type::string_type; static constexpr uint8_t indent_size_default = 4; static constexpr size_t line_length_limit_default = 120; private: bool escape_all_non_ascii_:1; bool escape_solidus_:1; bool pad_inside_object_braces_:1; bool pad_inside_array_brackets_:1; float_chars_format float_format_; byte_string_chars_format byte_string_format_; bignum_format_kind bignum_format_; line_split_kind line_splits_; line_split_kind object_object_line_splits_; line_split_kind object_array_line_splits_; line_split_kind array_array_line_splits_; line_split_kind array_object_line_splits_; spaces_option spaces_around_colon_; spaces_option spaces_around_comma_; int8_t precision_{0}; uint8_t indent_size_{indent_size_default}; std::size_t line_length_limit_{line_length_limit_default}; string_type new_line_chars_; public: basic_json_encode_options() : escape_all_non_ascii_(false), escape_solidus_(false), pad_inside_object_braces_(false), pad_inside_array_brackets_(false), float_format_(float_chars_format::general), byte_string_format_(byte_string_chars_format::none), bignum_format_(bignum_format_kind::raw), line_splits_(line_split_kind::multi_line), object_object_line_splits_(line_split_kind{}), object_array_line_splits_(line_split_kind{}), array_array_line_splits_(line_split_kind{}), array_object_line_splits_(line_split_kind{}), spaces_around_colon_(spaces_option::space_after), spaces_around_comma_(spaces_option::space_after) { new_line_chars_.push_back('\n'); } basic_json_encode_options(const basic_json_encode_options&) = default; basic_json_encode_options(basic_json_encode_options&& other) noexcept : super_type(std::move(other)), escape_all_non_ascii_(other.escape_all_non_ascii_), escape_solidus_(other.escape_solidus_), pad_inside_object_braces_(other.pad_inside_object_braces_), pad_inside_array_brackets_(other.pad_inside_array_brackets_), float_format_(other.float_format_), byte_string_format_(other.byte_string_format_), bignum_format_(other.bignum_format_), line_splits_(other.line_splits_), object_object_line_splits_(other.object_object_line_splits_), object_array_line_splits_(other.object_array_line_splits_), array_array_line_splits_(other.array_array_line_splits_), array_object_line_splits_(other.array_object_line_splits_), spaces_around_colon_(other.spaces_around_colon_), spaces_around_comma_(other.spaces_around_comma_), precision_(other.precision_), indent_size_(other.indent_size_), line_length_limit_(other.line_length_limit_), new_line_chars_(std::move(other.new_line_chars_)) { } ~basic_json_encode_options() = default; protected: basic_json_encode_options& operator=(const basic_json_encode_options&) = default; basic_json_encode_options& operator=(basic_json_encode_options&&) = default; public: byte_string_chars_format byte_string_format() const {return byte_string_format_;} #if !defined(JSONCONS_NO_DEPRECATED) JSONCONS_DEPRECATED_MSG("Instead, use bignum_format") bignum_format_kind bigint_format() const {return bignum_format_;} #endif bignum_format_kind bignum_format() const {return bignum_format_;} line_split_kind line_splits() const {return line_splits_;} line_split_kind object_object_line_splits() const {return object_object_line_splits_ == line_split_kind{} ? line_splits_ : object_object_line_splits_;} line_split_kind array_object_line_splits() const {return array_object_line_splits_ == line_split_kind{} ? line_splits_ : array_object_line_splits_;} line_split_kind object_array_line_splits() const {return object_array_line_splits_ == line_split_kind{} ? line_splits_ : object_array_line_splits_;} line_split_kind array_array_line_splits() const {return array_array_line_splits_ == line_split_kind{} ? line_splits_ : array_array_line_splits_;} uint8_t indent_size() const { return indent_size_; } spaces_option spaces_around_colon() const { return spaces_around_colon_; } spaces_option spaces_around_comma() const { return spaces_around_comma_; } bool pad_inside_object_braces() const { return pad_inside_object_braces_; } bool pad_inside_array_brackets() const { return pad_inside_array_brackets_; } string_type new_line_chars() const { return new_line_chars_; } std::size_t line_length_limit() const { return line_length_limit_; } float_chars_format float_format() const { return float_format_; } int8_t precision() const { return precision_; } bool escape_all_non_ascii() const { return escape_all_non_ascii_; } bool escape_solidus() const { return escape_solidus_; } }; template class basic_json_options final: public basic_json_decode_options, public basic_json_encode_options { public: using char_type = CharT; using string_type = std::basic_string; using basic_json_options_common::max_nesting_depth; using basic_json_decode_options::enable_str_to_nan; using basic_json_decode_options::enable_str_to_inf; using basic_json_decode_options::enable_str_to_neginf; using basic_json_decode_options::nan_to_str; using basic_json_decode_options::inf_to_str; using basic_json_decode_options::neginf_to_str; using basic_json_decode_options::nan_to_num; using basic_json_decode_options::inf_to_num; using basic_json_decode_options::neginf_to_num; using basic_json_decode_options::lossless_number; using basic_json_decode_options::allow_comments; using basic_json_decode_options::allow_trailing_comma; using basic_json_decode_options::err_handler; using basic_json_encode_options::byte_string_format; using basic_json_encode_options::bignum_format; using basic_json_encode_options::line_splits; using basic_json_encode_options::object_object_line_splits; using basic_json_encode_options::array_object_line_splits; using basic_json_encode_options::object_array_line_splits; using basic_json_encode_options::array_array_line_splits; using basic_json_encode_options::indent_size; using basic_json_encode_options::spaces_around_colon; using basic_json_encode_options::spaces_around_comma; using basic_json_encode_options::pad_inside_object_braces; using basic_json_encode_options::pad_inside_array_brackets; using basic_json_encode_options::new_line_chars; using basic_json_encode_options::line_length_limit; using basic_json_encode_options::float_format; using basic_json_encode_options::precision; using basic_json_encode_options::escape_all_non_ascii; using basic_json_encode_options::escape_solidus; public: // Constructors basic_json_options() = default; basic_json_options(const basic_json_options&) = default; basic_json_options(basic_json_options&&) = default; basic_json_options& operator=(const basic_json_options&) = default; basic_json_options& operator=(basic_json_options&&) = default; basic_json_options& nan_to_num(const string_type& value) { this->enable_nan_to_num_ = true; this->nan_to_str_.clear(); this->nan_to_num_ = value; return *this; } basic_json_options& inf_to_num(const string_type& value) { this->enable_inf_to_num_ = true; this->inf_to_str_.clear(); this->inf_to_num_ = value; return *this; } basic_json_options& neginf_to_num(const string_type& value) { this->enable_neginf_to_num_ = true; this->neginf_to_str_.clear(); this->neginf_to_num_ = value; return *this; } basic_json_options& nan_to_str(const string_type& value, bool enable_inverse = true) { this->enable_nan_to_str_ = true; this->enable_str_to_nan_ = enable_inverse; this->nan_to_num_.clear(); this->nan_to_str_ = value; return *this; } basic_json_options& inf_to_str(const string_type& value, bool enable_inverse = true) { this->enable_inf_to_str_ = true; this->enable_str_to_inf_ = enable_inverse; this->inf_to_num_.clear(); this->inf_to_str_ = value; return *this; } basic_json_options& neginf_to_str(const string_type& value, bool enable_inverse = true) { this->enable_neginf_to_str_ = true; this->enable_str_to_neginf_ = enable_inverse; this->neginf_to_num_.clear(); this->neginf_to_str_ = value; return *this; } basic_json_options& byte_string_format(byte_string_chars_format value) {this->byte_string_format_ = value; return *this;} #if !defined(JSONCONS_NO_DEPRECATED) JSONCONS_DEPRECATED_MSG("Instead, use bignum_format") basic_json_options& bigint_format(bignum_format_kind value) {this->bignum_format_ = value; return *this;} #endif basic_json_options& bignum_format(bignum_format_kind value) {this->bignum_format_ = value; return *this;} basic_json_options& line_splits(line_split_kind value) {this->line_splits_ = value; return *this;} basic_json_options& object_object_line_splits(line_split_kind value) {this->object_object_line_splits_ = value; return *this;} basic_json_options& array_object_line_splits(line_split_kind value) {this->array_object_line_splits_ = value; return *this;} basic_json_options& object_array_line_splits(line_split_kind value) {this->object_array_line_splits_ = value; return *this;} basic_json_options& array_array_line_splits(line_split_kind value) {this->array_array_line_splits_ = value; return *this;} basic_json_options& indent_size(uint8_t value) { this->indent_size_ = value; return *this; } basic_json_options& spaces_around_colon(spaces_option value) { this->spaces_around_colon_ = value; return *this; } basic_json_options& spaces_around_comma(spaces_option value) { this->spaces_around_comma_ = value; return *this; } basic_json_options& pad_inside_object_braces(bool value) { this->pad_inside_object_braces_ = value; return *this; } basic_json_options& pad_inside_array_brackets(bool value) { this->pad_inside_array_brackets_ = value; return *this; } basic_json_options& new_line_chars(const string_type& value) { this->new_line_chars_ = value; return *this; } basic_json_options& lossless_number(bool value) { this->lossless_number_ = value; return *this; } basic_json_options& allow_comments(bool value) { this->allow_comments_ = value; return *this; } basic_json_options& allow_trailing_comma(bool value) { this->allow_trailing_comma_ = value; return *this; } basic_json_options& err_handler(const std::function& value) { this->err_handler_ = value; return *this; } basic_json_options& line_length_limit(std::size_t value) { this->line_length_limit_ = value; return *this; } basic_json_options& float_format(float_chars_format value) { this->float_format_ = value; return *this; } basic_json_options& precision(int8_t value) { this->precision_ = value; return *this; } basic_json_options& escape_all_non_ascii(bool value) { this->escape_all_non_ascii_ = value; return *this; } basic_json_options& escape_solidus(bool value) { this->escape_solidus_ = value; return *this; } basic_json_options& max_nesting_depth(int value) { this->max_nesting_depth_ = value; return *this; } private: enum class input_state {initial,begin_quote,character,end_quote,escape,error}; bool is_string(const string_type& s) const { input_state state = input_state::initial; for (char_type c : s) { switch (c) { case '\t': case ' ': case '\n': case'\r': break; case '\\': state = input_state::escape; break; case '\"': switch (state) { case input_state::initial: state = input_state::begin_quote; break; case input_state::begin_quote: case input_state::character: state = input_state::end_quote; break; case input_state::end_quote: state = input_state::error; break; case input_state::escape: state = input_state::character; break; default: state = input_state::character; break; } break; default: break; } } return state == input_state::end_quote; } }; using json_options = basic_json_options; using wjson_options = basic_json_options; } // namespace jsoncons #endif // JSONCONS_JSON_OPTIONS_HPP jsoncons-1.3.2/include/jsoncons/json_parser.hpp000066400000000000000000003027101477700171100216760ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_JSON_PARSER_HPP #define JSONCONS_JSON_PARSER_HPP #include #include #include // std::function #include // std::numeric_limits #include // std::allocator #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define JSONCONS_ILLEGAL_CONTROL_CHARACTER \ case 0x00:case 0x01:case 0x02:case 0x03:case 0x04:case 0x05:case 0x06:case 0x07:case 0x08:case 0x0b: \ case 0x0c:case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12:case 0x13:case 0x14:case 0x15:case 0x16: \ case 0x17:case 0x18:case 0x19:case 0x1a:case 0x1b:case 0x1c:case 0x1d:case 0x1e:case 0x1f namespace jsoncons { namespace detail { } enum class parse_state : uint8_t { root, start, accept, slash, slash_slash, slash_star, slash_star_star, expect_comma_or_end, object, expect_member_name_or_end, expect_member_name, expect_colon, expect_value_or_end, expect_value, array, string, member_name, number, n, nu, nul, t, tr, tru, f, fa, fal, fals, cr, done }; enum class parse_string_state : uint8_t { text = 0, escape, escape_u1, escape_u2, escape_u3, escape_u4, escape_expect_surrogate_pair1, escape_expect_surrogate_pair2, escape_u5, escape_u6, escape_u7, escape_u8 }; enum class parse_number_state : uint8_t { minus, zero, integer, fraction1, fraction2, exp1, exp2, exp3 }; template > class basic_json_parser : public ser_context { public: using char_type = CharT; using string_view_type = typename basic_json_visitor::string_view_type; private: struct string_maps_to_double { string_view_type s; bool operator()(const std::pair& val) const { return val.first == s; } }; using temp_allocator_type = TempAllocator; using char_allocator_type = typename std::allocator_traits:: template rebind_alloc; using parse_state_allocator_type = typename std::allocator_traits:: template rebind_alloc; static constexpr std::size_t initial_string_buffer_capacity = 256; static constexpr int default_initial_stack_capacity = 66; int max_nesting_depth_; bool allow_trailing_comma_; bool allow_comments_; bool lossless_number_; std::function err_handler_; int level_{0}; uint32_t cp_{0}; uint32_t cp2_{0}; std::size_t line_{1}; std::size_t position_{0}; std::size_t mark_position_{0}; std::size_t begin_position_{0}; const char_type* begin_input_{nullptr}; const char_type* end_input_{nullptr}; const char_type* input_ptr_{nullptr}; parse_state state_{parse_state::start}; parse_string_state string_state_{}; parse_number_state number_state_{}; bool more_{true}; bool done_{false}; bool cursor_mode_{false}; int mark_level_{0}; std::basic_string,char_allocator_type> string_buffer_; jsoncons::detail::chars_to to_double_; std::vector state_stack_; std::vector,double>> string_double_map_; // Noncopyable and nonmoveable basic_json_parser(const basic_json_parser&) = delete; basic_json_parser& operator=(const basic_json_parser&) = delete; public: basic_json_parser(const TempAllocator& temp_alloc = TempAllocator()) : basic_json_parser(basic_json_decode_options(), default_json_parsing(), temp_alloc) { } basic_json_parser(std::function err_handler, const TempAllocator& temp_alloc = TempAllocator()) : basic_json_parser(basic_json_decode_options(), err_handler, temp_alloc) { } basic_json_parser(const basic_json_decode_options& options, const TempAllocator& temp_alloc = TempAllocator()) : basic_json_parser(options, options.err_handler(), temp_alloc) { } basic_json_parser(const basic_json_decode_options& options, std::function err_handler, const TempAllocator& temp_alloc = TempAllocator()) : max_nesting_depth_(options.max_nesting_depth()), allow_trailing_comma_(options.allow_trailing_comma()), allow_comments_(options.allow_comments()), lossless_number_(options.lossless_number()), err_handler_(err_handler), string_buffer_(temp_alloc), state_stack_(temp_alloc) { string_buffer_.reserve(initial_string_buffer_capacity); std::size_t initial_stack_capacity = options.max_nesting_depth() <= (default_initial_stack_capacity-2) ? (options.max_nesting_depth()+2) : default_initial_stack_capacity; state_stack_.reserve(initial_stack_capacity ); push_state(parse_state::root); if (options.enable_str_to_nan()) { string_double_map_.emplace_back(options.nan_to_str(),std::nan("")); } if (options.enable_str_to_inf()) { string_double_map_.emplace_back(options.inf_to_str(),std::numeric_limits::infinity()); } if (options.enable_str_to_neginf()) { string_double_map_.emplace_back(options.neginf_to_str(),-std::numeric_limits::infinity()); } } void cursor_mode(bool value) { cursor_mode_ = value; } int level() const { return level_; } int mark_level() const { return mark_level_; } void mark_level(int value) { mark_level_ = value; } bool source_exhausted() const { return input_ptr_ == end_input_; } ~basic_json_parser() noexcept { } parse_state parent() const { JSONCONS_ASSERT(state_stack_.size() >= 1); return state_stack_.back(); } bool done() const { return done_; } bool enter() const { return state_ == parse_state::start; } bool accept() const { return state_ == parse_state::accept || done_; } bool stopped() const { return !more_; } parse_state state() const { return state_; } bool finished() const { return !more_ && state_ != parse_state::accept; } const char_type* first() const { return begin_input_; } const char_type* current() const { return input_ptr_; } const char_type* last() const { return end_input_; } void skip_whitespace() { const char_type* local_input_end = end_input_; while (input_ptr_ != local_input_end) { switch (state_) { case parse_state::cr: ++line_; //++position_; switch (*input_ptr_) { case '\n': ++input_ptr_; ++position_; mark_position_ = position_; state_ = pop_state(); break; default: mark_position_ = position_; state_ = pop_state(); break; } break; default: switch (*input_ptr_) { case ' ':case '\t':case '\n':case '\r': skip_space(&input_ptr_); break; default: return; } break; } } } void begin_object(basic_json_visitor& visitor, std::error_code& ec) { if (JSONCONS_UNLIKELY(++level_ > max_nesting_depth_)) { more_ = err_handler_(json_errc::max_nesting_depth_exceeded, *this); if (!more_) { ec = json_errc::max_nesting_depth_exceeded; return; } } push_state(parse_state::object); state_ = parse_state::expect_member_name_or_end; visitor.begin_object(semantic_tag::none, *this, ec); more_ = !cursor_mode_; } void end_object(basic_json_visitor& visitor, std::error_code& ec) { if (JSONCONS_UNLIKELY(level_ < 1)) { err_handler_(json_errc::unexpected_rbrace, *this); ec = json_errc::unexpected_rbrace; more_ = false; return; } state_ = pop_state(); if (state_ == parse_state::object) { visitor.end_object(*this, ec); } else if (state_ == parse_state::array) { err_handler_(json_errc::expected_comma_or_rbracket, *this); ec = json_errc::expected_comma_or_rbracket; more_ = false; return; } else { err_handler_(json_errc::unexpected_rbrace, *this); ec = json_errc::unexpected_rbrace; more_ = false; return; } more_ = !cursor_mode_; if (level_ == mark_level_) { more_ = false; } --level_; if (level_ == 0) { state_ = parse_state::accept; } else { state_ = parse_state::expect_comma_or_end; } } void begin_array(basic_json_visitor& visitor, std::error_code& ec) { if (++level_ > max_nesting_depth_) { more_ = err_handler_(json_errc::max_nesting_depth_exceeded, *this); if (!more_) { ec = json_errc::max_nesting_depth_exceeded; return; } } push_state(parse_state::array); state_ = parse_state::expect_value_or_end; visitor.begin_array(semantic_tag::none, *this, ec); more_ = !cursor_mode_; } void end_array(basic_json_visitor& visitor, std::error_code& ec) { if (level_ < 1) { err_handler_(json_errc::unexpected_rbracket, *this); ec = json_errc::unexpected_rbracket; more_ = false; return; } state_ = pop_state(); if (state_ == parse_state::array) { visitor.end_array(*this, ec); } else if (state_ == parse_state::object) { err_handler_(json_errc::expected_comma_or_rbrace, *this); ec = json_errc::expected_comma_or_rbrace; more_ = false; return; } else { err_handler_(json_errc::unexpected_rbracket, *this); ec = json_errc::unexpected_rbracket; more_ = false; return; } more_ = !cursor_mode_; if (level_ == mark_level_) { more_ = false; } --level_; if (level_ == 0) { state_ = parse_state::accept; } else { state_ = parse_state::expect_comma_or_end; } } void reinitialize() { reset(); cp_ = 0; cp2_ = 0; begin_position_ = 0; begin_input_ = nullptr; end_input_ = nullptr; input_ptr_ = nullptr; string_buffer_.clear(); } void reset() { state_stack_.clear(); push_state(parse_state::root); state_ = parse_state::start; more_ = true; done_ = false; line_ = 1; position_ = 0; mark_position_ = 0; level_ = 0; } void restart() { more_ = true; } void check_done() { std::error_code ec; check_done(ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,line_,column())); } } void check_done(std::error_code& ec) { for (; input_ptr_ != end_input_; ++input_ptr_) { char_type curr_char_ = *input_ptr_; switch (curr_char_) { case '\n': case '\r': case '\t': case ' ': break; default: more_ = err_handler_(json_errc::extra_character, *this); if (!more_) { ec = json_errc::extra_character; return; } break; } } } void update(const string_view_type sv) { update(sv.data(),sv.length()); } void update(const char_type* data, std::size_t length) { begin_input_ = data; end_input_ = data + length; input_ptr_ = begin_input_; } void parse_some(basic_json_visitor& visitor) { std::error_code ec; parse_some(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,line_,column())); } } void parse_some(basic_json_visitor& visitor, std::error_code& ec) { parse_some_(visitor, ec); } void finish_parse(basic_json_visitor& visitor) { std::error_code ec; finish_parse(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,line_,column())); } } void finish_parse(basic_json_visitor& visitor, std::error_code& ec) { while (!finished()) { parse_some(visitor, ec); } } void parse_some_(basic_json_visitor& visitor, std::error_code& ec) { if (state_ == parse_state::accept) { visitor.flush(); done_ = true; state_ = parse_state::done; more_ = false; return; } const char_type* local_input_end = end_input_; if (input_ptr_ == local_input_end && more_) { switch (state_) { case parse_state::number: if (number_state_ == parse_number_state::zero || number_state_ == parse_number_state::integer) { end_integer_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; } else if (number_state_ == parse_number_state::fraction2 || number_state_ == parse_number_state::exp3) { end_fraction_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; } else { err_handler_(json_errc::unexpected_eof, *this); ec = json_errc::unexpected_eof; more_ = false; } break; case parse_state::accept: visitor.flush(); done_ = true; state_ = parse_state::done; more_ = false; break; case parse_state::start: more_ = false; ec = json_errc::unexpected_eof; break; case parse_state::done: more_ = false; break; case parse_state::cr: state_ = pop_state(); break; default: err_handler_(json_errc::unexpected_eof, *this); ec = json_errc::unexpected_eof; more_ = false; return; } } while ((input_ptr_ < local_input_end) && more_) { switch (state_) { case parse_state::accept: visitor.flush(); done_ = true; state_ = parse_state::done; more_ = false; break; case parse_state::cr: ++line_; switch (*input_ptr_) { case '\n': ++input_ptr_; ++position_; state_ = pop_state(); break; default: state_ = pop_state(); break; } mark_position_ = position_; break; case parse_state::start: { switch (*input_ptr_) { JSONCONS_ILLEGAL_CONTROL_CHARACTER: more_ = err_handler_(json_errc::illegal_control_character, *this); if (!more_) { ec = json_errc::illegal_control_character; return; } break; case ' ':case '\t':case '\n':case '\r': skip_space(&input_ptr_); break; case '/': ++input_ptr_; ++position_; push_state(state_); state_ = parse_state::slash; break; case '{': begin_position_ = position_; ++input_ptr_; ++position_; begin_object(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; break; case '[': begin_position_ = position_; ++input_ptr_; ++position_; begin_array(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; break; case '\"': state_ = parse_state::string; string_state_ = parse_string_state{}; begin_position_ = position_; ++input_ptr_; ++position_; string_buffer_.clear(); parse_string(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; break; case '-': string_buffer_.clear(); string_buffer_.push_back('-'); begin_position_ = position_; ++input_ptr_; ++position_; state_ = parse_state::number; number_state_ = parse_number_state::minus; parse_number(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} break; case '0': string_buffer_.clear(); string_buffer_.push_back(static_cast(*input_ptr_)); state_ = parse_state::number; number_state_ = parse_number_state::zero; begin_position_ = position_; ++input_ptr_; ++position_; parse_number(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} break; case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': string_buffer_.clear(); string_buffer_.push_back(static_cast(*input_ptr_)); begin_position_ = position_; ++input_ptr_; ++position_; state_ = parse_state::number; number_state_ = parse_number_state::integer; parse_number(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} break; case 'n': parse_null(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} break; case 't': parse_true(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} break; case 'f': parse_false(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} break; case '}': err_handler_(json_errc::unexpected_rbrace, *this); ec = json_errc::unexpected_rbrace; more_ = false; return; case ']': err_handler_(json_errc::unexpected_rbracket, *this); ec = json_errc::unexpected_rbracket; more_ = false; return; default: err_handler_(json_errc::syntax_error, *this); ec = json_errc::syntax_error; more_ = false; return; } break; } case parse_state::expect_comma_or_end: { switch (*input_ptr_) { JSONCONS_ILLEGAL_CONTROL_CHARACTER: more_ = err_handler_(json_errc::illegal_control_character, *this); if (!more_) { ec = json_errc::illegal_control_character; return; } ++input_ptr_; ++position_; break; case ' ':case '\t':case '\n':case '\r': skip_space(&input_ptr_); break; case '/': ++input_ptr_; ++position_; push_state(state_); state_ = parse_state::slash; break; case '}': begin_position_ = position_; ++input_ptr_; ++position_; end_object(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; break; case ']': begin_position_ = position_; ++input_ptr_; ++position_; end_array(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; break; case ',': begin_member_or_element(ec); if (JSONCONS_UNLIKELY(ec)) return; ++input_ptr_; ++position_; break; default: if (parent() == parse_state::array) { more_ = err_handler_(json_errc::expected_comma_or_rbracket, *this); if (!more_) { ec = json_errc::expected_comma_or_rbracket; return; } } else if (parent() == parse_state::object) { more_ = err_handler_(json_errc::expected_comma_or_rbrace, *this); if (!more_) { ec = json_errc::expected_comma_or_rbrace; return; } } ++input_ptr_; ++position_; break; } break; } case parse_state::expect_member_name_or_end: { if (input_ptr_ >= local_input_end) { return; } switch (*input_ptr_) { JSONCONS_ILLEGAL_CONTROL_CHARACTER: more_ = err_handler_(json_errc::illegal_control_character, *this); if (!more_) { ec = json_errc::illegal_control_character; return; } ++input_ptr_; ++position_; break; case ' ':case '\t':case '\n':case '\r': skip_space(&input_ptr_); break; case '/': ++input_ptr_; ++position_; push_state(state_); state_ = parse_state::slash; break; case '}': begin_position_ = position_; ++input_ptr_; ++position_; end_object(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; break; case '\"': begin_position_ = position_; ++input_ptr_; ++position_; push_state(parse_state::member_name); state_ = parse_state::string; string_state_ = parse_string_state{}; string_buffer_.clear(); parse_string(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; break; case '\'': more_ = err_handler_(json_errc::single_quote, *this); if (!more_) { ec = json_errc::single_quote; return; } ++input_ptr_; ++position_; break; default: more_ = err_handler_(json_errc::expected_key, *this); if (!more_) { ec = json_errc::expected_key; return; } ++input_ptr_; ++position_; break; } break; } case parse_state::expect_member_name: { switch (*input_ptr_) { JSONCONS_ILLEGAL_CONTROL_CHARACTER: more_ = err_handler_(json_errc::illegal_control_character, *this); if (!more_) { ec = json_errc::illegal_control_character; return; } ++input_ptr_; ++position_; break; case ' ':case '\t':case '\n':case '\r': skip_space(&input_ptr_); break; case '/': ++input_ptr_; ++position_; push_state(state_); state_ = parse_state::slash; break; case '\"': begin_position_ = position_; ++input_ptr_; ++position_; push_state(parse_state::member_name); state_ = parse_state::string; string_state_ = parse_string_state{}; string_buffer_.clear(); parse_string(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; break; case '}': begin_position_ = position_; ++input_ptr_; ++position_; if (!allow_trailing_comma_) { more_ = err_handler_(json_errc::extra_comma, *this); if (!more_) { ec = json_errc::extra_comma; return; } } end_object(visitor, ec); // Recover if (JSONCONS_UNLIKELY(ec)) return; break; case '\'': more_ = err_handler_(json_errc::single_quote, *this); if (!more_) { ec = json_errc::single_quote; return; } ++input_ptr_; ++position_; break; default: more_ = err_handler_(json_errc::expected_key, *this); if (!more_) { ec = json_errc::expected_key; return; } ++input_ptr_; ++position_; break; } break; } case parse_state::expect_colon: { switch (*input_ptr_) { JSONCONS_ILLEGAL_CONTROL_CHARACTER: more_ = err_handler_(json_errc::illegal_control_character, *this); if (!more_) { ec = json_errc::illegal_control_character; return; } ++input_ptr_; ++position_; break; case ' ':case '\t':case '\n':case '\r': skip_space(&input_ptr_); break; case '/': push_state(state_); state_ = parse_state::slash; ++input_ptr_; ++position_; break; case ':': state_ = parse_state::expect_value; ++input_ptr_; ++position_; break; default: more_ = err_handler_(json_errc::expected_colon, *this); if (!more_) { ec = json_errc::expected_colon; return; } ++input_ptr_; ++position_; break; } break; } case parse_state::expect_value: { switch (*input_ptr_) { JSONCONS_ILLEGAL_CONTROL_CHARACTER: more_ = err_handler_(json_errc::illegal_control_character, *this); if (!more_) { ec = json_errc::illegal_control_character; return; } ++input_ptr_; ++position_; break; case ' ':case '\t':case '\n':case '\r': skip_space(&input_ptr_); break; case '/': push_state(state_); ++input_ptr_; ++position_; state_ = parse_state::slash; break; case '{': begin_position_ = position_; ++input_ptr_; ++position_; begin_object(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; break; case '[': begin_position_ = position_; ++input_ptr_; ++position_; begin_array(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; break; case '\"': begin_position_ = position_; ++input_ptr_; ++position_; state_ = parse_state::string; string_state_ = parse_string_state{}; string_buffer_.clear(); parse_string(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; break; case '-': string_buffer_.clear(); string_buffer_.push_back('-'); begin_position_ = position_; ++input_ptr_; ++position_; state_ = parse_state::number; number_state_ = parse_number_state::minus; parse_number(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} break; case '0': string_buffer_.clear(); string_buffer_.push_back(static_cast(*input_ptr_)); begin_position_ = position_; ++input_ptr_; ++position_; state_ = parse_state::number; number_state_ = parse_number_state::zero; parse_number(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} break; case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': string_buffer_.clear(); string_buffer_.push_back(static_cast(*input_ptr_)); begin_position_ = position_; ++input_ptr_; ++position_; state_ = parse_state::number; number_state_ = parse_number_state::integer; parse_number(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} break; case 'n': parse_null(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} break; case 't': parse_true(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} break; case 'f': parse_false(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} break; case ']': begin_position_ = position_; ++input_ptr_; ++position_; if (parent() == parse_state::array) { if (!allow_trailing_comma_) { more_ = err_handler_(json_errc::extra_comma, *this); if (!more_) { ec = json_errc::extra_comma; return; } } end_array(visitor, ec); // Recover if (JSONCONS_UNLIKELY(ec)) return; } else { more_ = err_handler_(json_errc::expected_value, *this); if (!more_) { ec = json_errc::expected_value; return; } } break; case '\'': more_ = err_handler_(json_errc::single_quote, *this); if (!more_) { ec = json_errc::single_quote; return; } ++input_ptr_; ++position_; break; default: more_ = err_handler_(json_errc::expected_value, *this); if (!more_) { ec = json_errc::expected_value; return; } ++input_ptr_; ++position_; break; } break; } case parse_state::expect_value_or_end: { switch (*input_ptr_) { JSONCONS_ILLEGAL_CONTROL_CHARACTER: more_ = err_handler_(json_errc::illegal_control_character, *this); if (!more_) { ec = json_errc::illegal_control_character; return; } ++input_ptr_; ++position_; break; case ' ':case '\t':case '\n':case '\r': skip_space(&input_ptr_); break; case '/': ++input_ptr_; ++position_; push_state(state_); state_ = parse_state::slash; break; case '{': begin_position_ = position_; ++input_ptr_; ++position_; begin_object(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; break; case '[': begin_position_ = position_; ++input_ptr_; ++position_; begin_array(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; break; case ']': begin_position_ = position_; ++input_ptr_; ++position_; end_array(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; break; case '\"': begin_position_ = position_; ++input_ptr_; ++position_; state_ = parse_state::string; string_state_ = parse_string_state{}; string_buffer_.clear(); parse_string(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; break; case '-': string_buffer_.clear(); string_buffer_.push_back('-'); begin_position_ = position_; ++input_ptr_; ++position_; state_ = parse_state::number; number_state_ = parse_number_state::minus; parse_number(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} break; case '0': string_buffer_.clear(); string_buffer_.push_back(static_cast(*input_ptr_)); begin_position_ = position_; ++input_ptr_; ++position_; state_ = parse_state::number; number_state_ = parse_number_state::zero; parse_number(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} break; case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': string_buffer_.clear(); string_buffer_.push_back(static_cast(*input_ptr_)); begin_position_ = position_; ++input_ptr_; ++position_; state_ = parse_state::number; number_state_ = parse_number_state::integer; parse_number(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} break; case 'n': parse_null(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} break; case 't': parse_true(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} break; case 'f': parse_false(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} break; case '\'': more_ = err_handler_(json_errc::single_quote, *this); if (!more_) { ec = json_errc::single_quote; return; } ++input_ptr_; ++position_; break; default: more_ = err_handler_(json_errc::expected_value, *this); if (!more_) { ec = json_errc::expected_value; return; } ++input_ptr_; ++position_; break; } } break; case parse_state::string: parse_string(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; break; case parse_state::number: parse_number(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; break; case parse_state::t: switch (*input_ptr_) { case 'r': ++input_ptr_; ++position_; state_ = parse_state::tr; break; default: err_handler_(json_errc::invalid_value, *this); ec = json_errc::invalid_value; more_ = false; return; } break; case parse_state::tr: switch (*input_ptr_) { case 'u': state_ = parse_state::tru; break; default: err_handler_(json_errc::invalid_value, *this); ec = json_errc::invalid_value; more_ = false; return; } ++input_ptr_; ++position_; break; case parse_state::tru: switch (*input_ptr_) { case 'e': ++input_ptr_; ++position_; visitor.bool_value(true, semantic_tag::none, *this, ec); if (level_ == 0) { state_ = parse_state::accept; } else { state_ = parse_state::expect_comma_or_end; } more_ = !cursor_mode_; break; default: err_handler_(json_errc::invalid_value, *this); ec = json_errc::invalid_value; more_ = false; return; } break; case parse_state::f: switch (*input_ptr_) { case 'a': ++input_ptr_; ++position_; state_ = parse_state::fa; break; default: err_handler_(json_errc::invalid_value, *this); ec = json_errc::invalid_value; more_ = false; return; } break; case parse_state::fa: switch (*input_ptr_) { case 'l': state_ = parse_state::fal; break; default: err_handler_(json_errc::invalid_value, *this); ec = json_errc::invalid_value; more_ = false; return; } ++input_ptr_; ++position_; break; case parse_state::fal: switch (*input_ptr_) { case 's': state_ = parse_state::fals; break; default: err_handler_(json_errc::invalid_value, *this); ec = json_errc::invalid_value; more_ = false; return; } ++input_ptr_; ++position_; break; case parse_state::fals: switch (*input_ptr_) { case 'e': ++input_ptr_; ++position_; visitor.bool_value(false, semantic_tag::none, *this, ec); if (level_ == 0) { state_ = parse_state::accept; } else { state_ = parse_state::expect_comma_or_end; } more_ = !cursor_mode_; break; default: err_handler_(json_errc::invalid_value, *this); ec = json_errc::invalid_value; more_ = false; return; } break; case parse_state::n: switch (*input_ptr_) { case 'u': ++input_ptr_; ++position_; state_ = parse_state::nu; break; default: err_handler_(json_errc::invalid_value, *this); ec = json_errc::invalid_value; more_ = false; return; } break; case parse_state::nu: switch (*input_ptr_) { case 'l': state_ = parse_state::nul; break; default: err_handler_(json_errc::invalid_value, *this); ec = json_errc::invalid_value; more_ = false; return; } ++input_ptr_; ++position_; break; case parse_state::nul: ++position_; switch (*input_ptr_) { case 'l': visitor.null_value(semantic_tag::none, *this, ec); if (level_ == 0) { state_ = parse_state::accept; } else { state_ = parse_state::expect_comma_or_end; } more_ = !cursor_mode_; break; default: err_handler_(json_errc::invalid_value, *this); ec = json_errc::invalid_value; more_ = false; return; } ++input_ptr_; break; case parse_state::slash: { switch (*input_ptr_) { case '*': if (!allow_comments_) { ec = json_errc::illegal_comment; return; } more_ = err_handler_(json_errc::illegal_comment, *this); if (!more_) { ec = json_errc::illegal_comment; return; } state_ = parse_state::slash_star; break; case '/': if (!allow_comments_) { ec = json_errc::illegal_comment; return; } more_ = err_handler_(json_errc::illegal_comment, *this); if (!more_) { ec = json_errc::illegal_comment; return; } state_ = parse_state::slash_slash; break; default: more_ = err_handler_(json_errc::syntax_error, *this); if (!more_) { ec = json_errc::syntax_error; return; } break; } ++input_ptr_; ++position_; break; } case parse_state::slash_star: { switch (*input_ptr_) { case '\r': push_state(state_); ++input_ptr_; ++position_; state_ = parse_state::cr; break; case '\n': ++input_ptr_; ++line_; ++position_; mark_position_ = position_; break; case '*': ++input_ptr_; ++position_; state_ = parse_state::slash_star_star; break; default: ++input_ptr_; ++position_; break; } break; } case parse_state::slash_slash: { switch (*input_ptr_) { case '\r': case '\n': state_ = pop_state(); break; default: ++input_ptr_; ++position_; } break; } case parse_state::slash_star_star: { switch (*input_ptr_) { case '/': state_ = pop_state(); break; default: state_ = parse_state::slash_star; break; } ++input_ptr_; ++position_; break; } default: JSONCONS_ASSERT(false); break; } } } void parse_true(basic_json_visitor& visitor, std::error_code& ec) { begin_position_ = position_; if (JSONCONS_LIKELY(end_input_ - input_ptr_ >= 4)) { if (*(input_ptr_+1) == 'r' && *(input_ptr_+2) == 'u' && *(input_ptr_+3) == 'e') { input_ptr_ += 4; position_ += 4; visitor.bool_value(true, semantic_tag::none, *this, ec); if (level_ == 0) { state_ = parse_state::accept; } else { state_ = parse_state::expect_comma_or_end; } more_ = !cursor_mode_; } else { err_handler_(json_errc::invalid_value, *this); ec = json_errc::invalid_value; more_ = false; return; } } else { ++input_ptr_; ++position_; state_ = parse_state::t; } } void parse_null(basic_json_visitor& visitor, std::error_code& ec) { begin_position_ = position_; if (JSONCONS_LIKELY(end_input_ - input_ptr_ >= 4)) { if (*(input_ptr_+1) == 'u' && *(input_ptr_+2) == 'l' && *(input_ptr_+3) == 'l') { input_ptr_ += 4; position_ += 4; visitor.null_value(semantic_tag::none, *this, ec); more_ = !cursor_mode_; if (level_ == 0) { state_ = parse_state::accept; } else { state_ = parse_state::expect_comma_or_end; } } else { err_handler_(json_errc::invalid_value, *this); ec = json_errc::invalid_value; more_ = false; return; } } else { ++input_ptr_; ++position_; state_ = parse_state::n; } } void parse_false(basic_json_visitor& visitor, std::error_code& ec) { begin_position_ = position_; if (JSONCONS_LIKELY(end_input_ - input_ptr_ >= 5)) { if (*(input_ptr_+1) == 'a' && *(input_ptr_+2) == 'l' && *(input_ptr_+3) == 's' && *(input_ptr_+4) == 'e') { input_ptr_ += 5; position_ += 5; visitor.bool_value(false, semantic_tag::none, *this, ec); more_ = !cursor_mode_; if (level_ == 0) { state_ = parse_state::accept; } else { state_ = parse_state::expect_comma_or_end; } } else { err_handler_(json_errc::invalid_value, *this); ec = json_errc::invalid_value; more_ = false; return; } } else { ++input_ptr_; ++position_; state_ = parse_state::f; } } void parse_number(basic_json_visitor& visitor, std::error_code& ec) { const char_type* local_input_end = end_input_; switch (number_state_) { case parse_number_state::minus: goto minus_sign; case parse_number_state::zero: goto zero; case parse_number_state::integer: goto integer; case parse_number_state::fraction1: goto fraction1; case parse_number_state::fraction2: goto fraction2; case parse_number_state::exp1: goto exp1; case parse_number_state::exp2: goto exp2; case parse_number_state::exp3: goto exp3; default: JSONCONS_UNREACHABLE(); } minus_sign: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { number_state_ = parse_number_state::minus; return; } switch (*input_ptr_) { case '0': string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++position_; goto zero; case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++position_; goto integer; default: err_handler_(json_errc::invalid_number, *this); ec = json_errc::expected_value; more_ = false; return; } zero: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { number_state_ = parse_number_state::zero; return; } switch (*input_ptr_) { case '\r': end_integer_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; ++input_ptr_; ++position_; push_state(state_); state_ = parse_state::cr; return; case '\n': end_integer_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; ++input_ptr_; ++line_; ++position_; mark_position_ = position_; return; case ' ':case '\t': end_integer_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; skip_space(&input_ptr_); return; case '/': end_integer_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; ++input_ptr_; ++position_; push_state(state_); state_ = parse_state::slash; return; case '}': case ']': end_integer_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; state_ = parse_state::expect_comma_or_end; return; case '.': string_buffer_.push_back(to_double_.get_decimal_point()); ++input_ptr_; ++position_; goto fraction1; case 'e':case 'E': string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++position_; goto exp1; case ',': end_integer_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; begin_member_or_element(ec); if (JSONCONS_UNLIKELY(ec)) return; ++input_ptr_; ++position_; return; case '0': case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': err_handler_(json_errc::leading_zero, *this); ec = json_errc::leading_zero; more_ = false; number_state_ = parse_number_state::zero; return; default: err_handler_(json_errc::invalid_number, *this); ec = json_errc::invalid_number; more_ = false; number_state_ = parse_number_state::zero; return; } integer: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { number_state_ = parse_number_state::integer; return; } switch (*input_ptr_) { case '\r': end_integer_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; push_state(state_); ++input_ptr_; ++position_; state_ = parse_state::cr; return; case '\n': end_integer_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; ++input_ptr_; ++line_; ++position_; mark_position_ = position_; return; case ' ':case '\t': end_integer_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; skip_space(&input_ptr_); return; case '/': end_integer_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; push_state(state_); ++input_ptr_; ++position_; state_ = parse_state::slash; return; case '}': case ']': end_integer_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; state_ = parse_state::expect_comma_or_end; return; case '0': case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++position_; goto integer; case '.': string_buffer_.push_back(to_double_.get_decimal_point()); ++input_ptr_; ++position_; goto fraction1; case 'e':case 'E': string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++position_; goto exp1; case ',': end_integer_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; begin_member_or_element(ec); if (JSONCONS_UNLIKELY(ec)) return; ++input_ptr_; ++position_; return; default: err_handler_(json_errc::invalid_number, *this); ec = json_errc::invalid_number; more_ = false; number_state_ = parse_number_state::integer; return; } fraction1: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { number_state_ = parse_number_state::fraction1; return; } switch (*input_ptr_) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++position_; goto fraction2; default: err_handler_(json_errc::invalid_number, *this); ec = json_errc::invalid_number; more_ = false; number_state_ = parse_number_state::fraction1; return; } fraction2: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { number_state_ = parse_number_state::fraction2; return; } switch (*input_ptr_) { case '\r': end_fraction_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; push_state(state_); ++input_ptr_; ++position_; state_ = parse_state::cr; return; case '\n': end_fraction_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; ++input_ptr_; ++line_; ++position_; mark_position_ = position_; return; case ' ':case '\t': end_fraction_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; skip_space(&input_ptr_); return; case '/': end_fraction_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; push_state(state_); ++input_ptr_; ++position_; state_ = parse_state::slash; return; case '}': end_fraction_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; state_ = parse_state::expect_comma_or_end; return; case ']': end_fraction_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; state_ = parse_state::expect_comma_or_end; return; case ',': end_fraction_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; begin_member_or_element(ec); if (JSONCONS_UNLIKELY(ec)) return; ++input_ptr_; ++position_; return; case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++position_; goto fraction2; case 'e':case 'E': string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++position_; goto exp1; default: err_handler_(json_errc::invalid_number, *this); ec = json_errc::invalid_number; more_ = false; number_state_ = parse_number_state::fraction2; return; } exp1: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { number_state_ = parse_number_state::exp1; return; } switch (*input_ptr_) { case '+': ++input_ptr_; ++position_; goto exp2; case '-': string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++position_; goto exp2; case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++position_; goto exp3; default: err_handler_(json_errc::invalid_number, *this); ec = json_errc::expected_value; more_ = false; number_state_ = parse_number_state::exp1; return; } exp2: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { number_state_ = parse_number_state::exp2; return; } switch (*input_ptr_) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++position_; goto exp3; default: err_handler_(json_errc::invalid_number, *this); ec = json_errc::expected_value; more_ = false; number_state_ = parse_number_state::exp2; return; } exp3: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { number_state_ = parse_number_state::exp3; return; } switch (*input_ptr_) { case '\r': end_fraction_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; ++input_ptr_; ++position_; push_state(state_); state_ = parse_state::cr; return; case '\n': end_fraction_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; ++input_ptr_; ++line_; ++position_; mark_position_ = position_; return; case ' ':case '\t': end_fraction_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; skip_space(&input_ptr_); return; case '/': end_fraction_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; push_state(state_); ++input_ptr_; ++position_; state_ = parse_state::slash; return; case '}': end_fraction_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; state_ = parse_state::expect_comma_or_end; return; case ']': end_fraction_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; state_ = parse_state::expect_comma_or_end; return; case ',': end_fraction_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) return; begin_member_or_element(ec); if (JSONCONS_UNLIKELY(ec)) return; ++input_ptr_; ++position_; return; case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++position_; goto exp3; default: err_handler_(json_errc::invalid_number, *this); ec = json_errc::invalid_number; more_ = false; number_state_ = parse_number_state::exp3; return; } JSONCONS_UNREACHABLE(); } void parse_string(basic_json_visitor& visitor, std::error_code& ec) { const char_type* local_input_end = end_input_; const char_type* sb = input_ptr_; switch (string_state_) { case parse_string_state::text: goto text; case parse_string_state::escape: goto escape; case parse_string_state::escape_u1: goto escape_u1; case parse_string_state::escape_u2: goto escape_u2; case parse_string_state::escape_u3: goto escape_u3; case parse_string_state::escape_u4: goto escape_u4; case parse_string_state::escape_expect_surrogate_pair1: goto escape_expect_surrogate_pair1; case parse_string_state::escape_expect_surrogate_pair2: goto escape_expect_surrogate_pair2; case parse_string_state::escape_u5: goto escape_u5; case parse_string_state::escape_u6: goto escape_u6; case parse_string_state::escape_u7: goto escape_u7; case parse_string_state::escape_u8: goto escape_u8; default: JSONCONS_UNREACHABLE(); } text: while (input_ptr_ < local_input_end) { switch (*input_ptr_) { JSONCONS_ILLEGAL_CONTROL_CHARACTER: { position_ += (input_ptr_ - sb + 1); more_ = err_handler_(json_errc::illegal_control_character, *this); if (!more_) { ec = json_errc::illegal_control_character; string_state_ = parse_string_state{}; return; } // recovery - skip string_buffer_.append(sb,input_ptr_-sb); ++input_ptr_; string_state_ = parse_string_state{}; return; } case '\n': case '\r': case '\t': { position_ += (input_ptr_ - sb + 1); if (!err_handler_(json_errc::illegal_character_in_string, *this)) { more_ = false; ec = json_errc::illegal_character_in_string; return; } // recovery - skip string_buffer_.append(sb,input_ptr_-sb); sb = input_ptr_ + 1; break; } case '\\': { string_buffer_.append(sb,input_ptr_-sb); position_ += (input_ptr_ - sb + 1); ++input_ptr_; goto escape; } case '\"': { position_ += (input_ptr_ - sb + 1); if (string_buffer_.length() == 0) { end_string_value(sb,input_ptr_-sb, visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} } else { string_buffer_.append(sb,input_ptr_-sb); end_string_value(string_buffer_.data(),string_buffer_.length(), visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} } ++input_ptr_; return; } default: break; } ++input_ptr_; } // Buffer exhausted { string_buffer_.append(sb,input_ptr_-sb); position_ += (input_ptr_ - sb); string_state_ = parse_string_state{}; return; } escape: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { string_state_ = parse_string_state::escape; return; } switch (*input_ptr_) { case '\"': string_buffer_.push_back('\"'); sb = ++input_ptr_; ++position_; goto text; case '\\': string_buffer_.push_back('\\'); sb = ++input_ptr_; ++position_; goto text; case '/': string_buffer_.push_back('/'); sb = ++input_ptr_; ++position_; goto text; case 'b': string_buffer_.push_back('\b'); sb = ++input_ptr_; ++position_; goto text; case 'f': string_buffer_.push_back('\f'); sb = ++input_ptr_; ++position_; goto text; case 'n': string_buffer_.push_back('\n'); sb = ++input_ptr_; ++position_; goto text; case 'r': string_buffer_.push_back('\r'); sb = ++input_ptr_; ++position_; goto text; case 't': string_buffer_.push_back('\t'); sb = ++input_ptr_; ++position_; goto text; case 'u': cp_ = 0; ++input_ptr_; ++position_; goto escape_u1; default: err_handler_(json_errc::illegal_escaped_character, *this); ec = json_errc::illegal_escaped_character; more_ = false; string_state_ = parse_string_state::escape; return; } escape_u1: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { string_state_ = parse_string_state::escape_u1; return; } { cp_ = append_to_codepoint(0, *input_ptr_, ec); if (JSONCONS_UNLIKELY(ec)) { string_state_ = parse_string_state::escape_u1; return; } ++input_ptr_; ++position_; goto escape_u2; } escape_u2: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { string_state_ = parse_string_state::escape_u2; return; } { cp_ = append_to_codepoint(cp_, *input_ptr_, ec); if (JSONCONS_UNLIKELY(ec)) { string_state_ = parse_string_state::escape_u2; return; } ++input_ptr_; ++position_; goto escape_u3; } escape_u3: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { string_state_ = parse_string_state::escape_u3; return; } { cp_ = append_to_codepoint(cp_, *input_ptr_, ec); if (JSONCONS_UNLIKELY(ec)) { string_state_ = parse_string_state::escape_u3; return; } ++input_ptr_; ++position_; goto escape_u4; } escape_u4: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { string_state_ = parse_string_state::escape_u4; return; } { cp_ = append_to_codepoint(cp_, *input_ptr_, ec); if (JSONCONS_UNLIKELY(ec)) { string_state_ = parse_string_state::escape_u4; return; } if (unicode_traits::is_high_surrogate(cp_)) { ++input_ptr_; ++position_; goto escape_expect_surrogate_pair1; } else { unicode_traits::convert(&cp_, 1, string_buffer_); sb = ++input_ptr_; ++position_; string_state_ = parse_string_state{}; return; } } escape_expect_surrogate_pair1: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { string_state_ = parse_string_state::escape_expect_surrogate_pair1; return; } { switch (*input_ptr_) { case '\\': cp2_ = 0; ++input_ptr_; ++position_; goto escape_expect_surrogate_pair2; default: err_handler_(json_errc::expected_codepoint_surrogate_pair, *this); ec = json_errc::expected_codepoint_surrogate_pair; more_ = false; string_state_ = parse_string_state::escape_expect_surrogate_pair1; return; } } escape_expect_surrogate_pair2: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { string_state_ = parse_string_state::escape_expect_surrogate_pair2; return; } { switch (*input_ptr_) { case 'u': ++input_ptr_; ++position_; goto escape_u5; default: err_handler_(json_errc::expected_codepoint_surrogate_pair, *this); ec = json_errc::expected_codepoint_surrogate_pair; more_ = false; string_state_ = parse_string_state::escape_expect_surrogate_pair2; return; } } escape_u5: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { string_state_ = parse_string_state::escape_u5; return; } { cp2_ = append_to_codepoint(0, *input_ptr_, ec); if (JSONCONS_UNLIKELY(ec)) { string_state_ = parse_string_state::escape_u5; return; } } ++input_ptr_; ++position_; goto escape_u6; escape_u6: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { string_state_ = parse_string_state::escape_u6; return; } { cp2_ = append_to_codepoint(cp2_, *input_ptr_, ec); if (JSONCONS_UNLIKELY(ec)) { string_state_ = parse_string_state::escape_u6; return; } ++input_ptr_; ++position_; goto escape_u7; } escape_u7: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { string_state_ = parse_string_state::escape_u7; return; } { cp2_ = append_to_codepoint(cp2_, *input_ptr_, ec); if (JSONCONS_UNLIKELY(ec)) { string_state_ = parse_string_state::escape_u7; return; } ++input_ptr_; ++position_; goto escape_u8; } escape_u8: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { string_state_ = parse_string_state::escape_u8; return; } { cp2_ = append_to_codepoint(cp2_, *input_ptr_, ec); if (JSONCONS_UNLIKELY(ec)) { string_state_ = parse_string_state::escape_u8; return; } uint32_t cp = 0x10000 + ((cp_ & 0x3FF) << 10) + (cp2_ & 0x3FF); unicode_traits::convert(&cp, 1, string_buffer_); sb = ++input_ptr_; ++position_; goto text; } JSONCONS_UNREACHABLE(); } void translate_conv_errc(unicode_traits::conv_errc result, std::error_code& ec) { switch (result) { case unicode_traits::conv_errc(): break; case unicode_traits::conv_errc::over_long_utf8_sequence: more_ = err_handler_(json_errc::over_long_utf8_sequence, *this); if (!more_) { ec = json_errc::over_long_utf8_sequence; return; } break; case unicode_traits::conv_errc::unpaired_high_surrogate: more_ = err_handler_(json_errc::unpaired_high_surrogate, *this); if (!more_) { ec = json_errc::unpaired_high_surrogate; return; } break; case unicode_traits::conv_errc::expected_continuation_byte: more_ = err_handler_(json_errc::expected_continuation_byte, *this); if (!more_) { ec = json_errc::expected_continuation_byte; return; } break; case unicode_traits::conv_errc::illegal_surrogate_value: more_ = err_handler_(json_errc::illegal_surrogate_value, *this); if (!more_) { ec = json_errc::illegal_surrogate_value; return; } break; default: more_ = err_handler_(json_errc::illegal_codepoint, *this); if (!more_) { ec = json_errc::illegal_codepoint; return; } break; } } std::size_t line() const override { return line_; } std::size_t column() const override { return (position_ - mark_position_) + 1; } std::size_t begin_position() const override { return begin_position_; } std::size_t position() const override { return begin_position_; } std::size_t end_position() const override { return position_; } std::size_t offset() const { return input_ptr_ - begin_input_; } private: void skip_space(char_type const ** ptr) { const char_type* local_input_end = end_input_; const char_type* cur = *ptr; while (cur < local_input_end) { if (*cur == ' ' || *cur == '\t') { ++cur; ++position_; continue; } if (*cur == '\n') { ++cur; ++line_; ++position_; mark_position_ = position_; continue; } if (*cur == '\r') { ++cur; ++position_; if (cur < local_input_end) { ++line_; if (*cur == '\n') { ++cur; ++position_; } mark_position_ = position_; } else { push_state(state_); state_ = parse_state::cr; *ptr = cur; return; } continue; } break; } *ptr = cur; } void end_integer_value(basic_json_visitor& visitor, std::error_code& ec) { if (string_buffer_[0] == '-') { end_negative_value(visitor, ec); } else { end_positive_value(visitor, ec); } } void end_negative_value(basic_json_visitor& visitor, std::error_code& ec) { int64_t val; auto result = jsoncons::detail::to_integer_unchecked(string_buffer_.data(), string_buffer_.length(), val); if (result) { visitor.int64_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else // Must be overflow { visitor.string_value(string_buffer_, semantic_tag::bigint, *this, ec); more_ = !cursor_mode_; } after_value(ec); } void end_positive_value(basic_json_visitor& visitor, std::error_code& ec) { uint64_t val; auto result = jsoncons::detail::to_integer_unchecked(string_buffer_.data(), string_buffer_.length(), val); if (result) { visitor.uint64_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else // Must be overflow { visitor.string_value(string_buffer_, semantic_tag::bigint, *this, ec); more_ = !cursor_mode_; } after_value(ec); } void end_fraction_value(basic_json_visitor& visitor, std::error_code& ec) { JSONCONS_TRY { if (lossless_number_) { visitor.string_value(string_buffer_, semantic_tag::bigdec, *this, ec); more_ = !cursor_mode_; } else { double d = to_double_(string_buffer_.c_str(), string_buffer_.length()); visitor.double_value(d, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } } JSONCONS_CATCH(...) { more_ = err_handler_(json_errc::invalid_number, *this); if (!more_) { ec = json_errc::invalid_number; return; } visitor.null_value(semantic_tag::none, *this, ec); // recovery more_ = !cursor_mode_; } after_value(ec); } void end_string_value(const char_type* s, std::size_t length, basic_json_visitor& visitor, std::error_code& ec) { string_view_type sv(s, length); auto result = unicode_traits::validate(s, length); if (result.ec != unicode_traits::conv_errc()) { translate_conv_errc(result.ec,ec); position_ += (result.ptr - s); return; } switch (parent()) { case parse_state::member_name: visitor.key(sv, *this, ec); more_ = !cursor_mode_; pop_state(); state_ = parse_state::expect_colon; break; case parse_state::object: case parse_state::array: { auto it = std::find_if(string_double_map_.begin(), string_double_map_.end(), string_maps_to_double{ sv }); if (it != string_double_map_.end()) { visitor.double_value((*it).second, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else { visitor.string_value(sv, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } state_ = parse_state::expect_comma_or_end; break; } case parse_state::root: { auto it = std::find_if(string_double_map_.begin(),string_double_map_.end(),string_maps_to_double{sv}); if (it != string_double_map_.end()) { visitor.double_value((*it).second, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else { visitor.string_value(sv, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } state_ = parse_state::accept; break; } default: more_ = err_handler_(json_errc::syntax_error, *this); if (!more_) { ec = json_errc::syntax_error; return; } break; } } void begin_member_or_element(std::error_code& ec) { switch (parent()) { case parse_state::object: state_ = parse_state::expect_member_name; break; case parse_state::array: state_ = parse_state::expect_value; break; case parse_state::root: break; default: more_ = err_handler_(json_errc::syntax_error, *this); if (!more_) { ec = json_errc::syntax_error; return; } break; } } void after_value(std::error_code& ec) { switch (parent()) { case parse_state::array: case parse_state::object: state_ = parse_state::expect_comma_or_end; break; case parse_state::root: state_ = parse_state::accept; break; default: more_ = err_handler_(json_errc::syntax_error, *this); if (!more_) { ec = json_errc::syntax_error; return; } break; } } void push_state(parse_state state) { state_stack_.push_back(state); //std::cout << "max_nesting_depth: " << max_nesting_depth_ << ", capacity: " << state_stack_.capacity() << ", nesting_depth: " << level_ << ", stack size: " << state_stack_.size() << "\n"; } parse_state pop_state() { JSONCONS_ASSERT(!state_stack_.empty()) parse_state state = state_stack_.back(); state_stack_.pop_back(); return state; } uint32_t append_to_codepoint(uint32_t cp, int c, std::error_code& ec) { cp *= 16; if (c >= '0' && c <= '9') { cp += c - '0'; } else if (c >= 'a' && c <= 'f') { cp += c - 'a' + 10; } else if (c >= 'A' && c <= 'F') { cp += c - 'A' + 10; } else { more_ = err_handler_(json_errc::invalid_unicode_escape_sequence, *this); if (!more_) { ec = json_errc::invalid_unicode_escape_sequence; return cp; } } return cp; } }; using json_parser = basic_json_parser; using wjson_parser = basic_json_parser; } #endif jsoncons-1.3.2/include/jsoncons/json_reader.hpp000066400000000000000000000360421477700171100216460ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_JSON_READER_HPP #define JSONCONS_JSON_READER_HPP #include #include #include #include // std::allocator #include #include #include // std::move #include #include #include #include #include #include #include #include #include namespace jsoncons { // utf8_other_json_input_adapter template class json_utf8_to_other_visitor_adaptor : public json_visitor { public: using json_visitor::string_view_type; private: basic_default_json_visitor default_visitor_; basic_json_visitor& other_visitor_; //std::function err_handler_; // noncopyable and nonmoveable json_utf8_to_other_visitor_adaptor(const json_utf8_to_other_visitor_adaptor&) = delete; json_utf8_to_other_visitor_adaptor& operator=(const json_utf8_to_other_visitor_adaptor&) = delete; public: json_utf8_to_other_visitor_adaptor() : other_visitor_(default_visitor_) { } json_utf8_to_other_visitor_adaptor(basic_json_visitor& other_visitor/*, std::function err_handler*/) : other_visitor_(other_visitor)/*, err_handler_(err_handler)*/ { } private: void visit_flush() override { other_visitor_.flush(); } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag tag, const ser_context& context, std::error_code& ec) override { other_visitor_.begin_object(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context& context, std::error_code& ec) override { other_visitor_.end_object(context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag tag, const ser_context& context, std::error_code& ec) override { other_visitor_.begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context& context, std::error_code& ec) override { other_visitor_.end_array(context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type& name, const ser_context& context, std::error_code& ec) override { std::basic_string target; auto result = unicode_traits::convert( name.data(), name.size(), target, unicode_traits::conv_flags::strict); if (result.ec != unicode_traits::conv_errc()) { JSONCONS_THROW(ser_error(result.ec,context.line(),context.column())); } other_visitor_.key(target, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { std::basic_string target; auto result = unicode_traits::convert( value.data(), value.size(), target, unicode_traits::conv_flags::strict); if (result.ec != unicode_traits::conv_errc()) { ec = result.ec; JSONCONS_VISITOR_RETURN; } other_visitor_.string_value(target, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { other_visitor_.int64_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { other_visitor_.uint64_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_half(uint16_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { other_visitor_.half_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_double(double value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { other_visitor_.double_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { other_visitor_.bool_value(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag tag, const ser_context& context, std::error_code& ec) override { other_visitor_.null_value(tag, context, ec); JSONCONS_VISITOR_RETURN; } }; template ,typename TempAllocator =std::allocator> class basic_json_reader { public: using char_type = CharT; using source_type = Source; using string_view_type = jsoncons::basic_string_view; private: using char_allocator_type = typename std::allocator_traits:: template rebind_alloc; static constexpr size_t default_max_buffer_size = 16384; json_source_adaptor source_; basic_default_json_visitor default_visitor_; basic_json_visitor& visitor_; basic_json_parser parser_; // Noncopyable and nonmoveable basic_json_reader(const basic_json_reader&) = delete; basic_json_reader& operator=(const basic_json_reader&) = delete; public: template explicit basic_json_reader(Sourceable&& source, const TempAllocator& temp_alloc = TempAllocator()) : basic_json_reader(std::forward(source), default_visitor_, basic_json_decode_options(), default_json_parsing(), temp_alloc) { } template basic_json_reader(Sourceable&& source, const basic_json_decode_options& options, const TempAllocator& temp_alloc = TempAllocator()) : basic_json_reader(std::forward(source), default_visitor_, options, options.err_handler(), temp_alloc) { } template basic_json_reader(Sourceable&& source, std::function err_handler, const TempAllocator& temp_alloc = TempAllocator()) : basic_json_reader(std::forward(source), default_visitor_, basic_json_decode_options(), err_handler, temp_alloc) { } template basic_json_reader(Sourceable&& source, const basic_json_decode_options& options, std::function err_handler, const TempAllocator& temp_alloc = TempAllocator()) : basic_json_reader(std::forward(source), default_visitor_, options, err_handler, temp_alloc) { } template basic_json_reader(Sourceable&& source, basic_json_visitor& visitor, const TempAllocator& temp_alloc = TempAllocator()) : basic_json_reader(std::forward(source), visitor, basic_json_decode_options(), default_json_parsing(), temp_alloc) { } template basic_json_reader(Sourceable&& source, basic_json_visitor& visitor, const basic_json_decode_options& options, const TempAllocator& temp_alloc = TempAllocator()) : basic_json_reader(std::forward(source), visitor, options, options.err_handler(), temp_alloc) { } template basic_json_reader(Sourceable&& source, basic_json_visitor& visitor, std::function err_handler, const TempAllocator& temp_alloc = TempAllocator()) : basic_json_reader(std::forward(source), visitor, basic_json_decode_options(), err_handler, temp_alloc) { } template basic_json_reader(Sourceable&& source, basic_json_visitor& visitor, const basic_json_decode_options& options, std::function err_handler, const TempAllocator& temp_alloc = TempAllocator()) : source_(std::forward(source)), visitor_(visitor), parser_(options,err_handler,temp_alloc) { } void read_next() { std::error_code ec; read_next(ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); } } void read_next(std::error_code& ec) { if (source_.is_error()) { ec = json_errc::source_error; return; } parser_.reset(); while (!parser_.stopped()) { if (parser_.source_exhausted()) { auto s = source_.read_buffer(ec); if (JSONCONS_UNLIKELY(ec)) return; if (s.size() > 0) { parser_.update(s.data(),s.size()); } } bool eof = parser_.source_exhausted(); parser_.parse_some(visitor_, ec); if (JSONCONS_UNLIKELY(ec)) return; if (eof) { if (parser_.enter()) { break; } else if (!parser_.accept()) { ec = json_errc::unexpected_eof; return; } } } parser_.skip_whitespace(); while (!source_.eof()) { parser_.skip_whitespace(); if (parser_.source_exhausted()) { auto s = source_.read_buffer(ec); if (JSONCONS_UNLIKELY(ec)) return; if (s.size() > 0) { parser_.update(s.data(),s.size()); } } else { break; } } } void check_done() { std::error_code ec; check_done(ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); } } std::size_t line() const { return parser_.line(); } std::size_t column() const { return parser_.column(); } void check_done(std::error_code& ec) { if (source_.is_error()) { ec = json_errc::source_error; return; } if (source_.eof()) { parser_.check_done(ec); if (JSONCONS_UNLIKELY(ec)) return; } else { do { if (parser_.source_exhausted()) { auto s = source_.read_buffer(ec); if (JSONCONS_UNLIKELY(ec)) return; if (s.size() > 0) { parser_.update(s.data(),s.size()); } } if (!parser_.source_exhausted()) { parser_.check_done(ec); if (JSONCONS_UNLIKELY(ec)) return; } } while (!eof()); } } bool eof() const { return parser_.source_exhausted() && source_.eof(); } void read() { read_next(); check_done(); } void read(std::error_code& ec) { read_next(ec); if (!ec) { check_done(ec); } } }; using json_string_reader = basic_json_reader>; using wjson_string_reader = basic_json_reader>; using json_stream_reader = basic_json_reader>; using wjson_stream_reader = basic_json_reader>; } #endif jsoncons-1.3.2/include/jsoncons/json_traits_macros.hpp000066400000000000000000002411361477700171100232600ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_JSON_TRAITS_MACROS_HPP #define JSONCONS_JSON_TRAITS_MACROS_HPP #include #include #include // JSONCONS_EXPAND, JSONCONS_QUOTE #include #include namespace jsoncons { #define JSONCONS_RDONLY(X) #define JSONCONS_RDWR(X) X struct always_true { template< typename T> constexpr bool operator()(const T&) const noexcept { return true; } }; struct identity { template< typename T> constexpr T&& operator()(T&& val) const noexcept { return std::forward(val); } }; template struct json_traits_macro_names {}; template struct json_traits_helper { using string_view_type = typename Json::string_view_type; template static void set_udt_member(const Json&, const string_view_type&, const OutputType&) { } template static void set_udt_member(const Json& j, const string_view_type& key, OutputType& val) { val = j.at(key).template as(); } template static void set_udt_member(const Json&, const string_view_type&, From, const OutputType&) { } template static void set_udt_member(const Json& j, const string_view_type& key, From from, OutputType& val) { val = from(j.at(key).template as()); } template static void set_optional_json_member(const string_view_type& key, const std::shared_ptr& val, Json& j) { if (val) j.try_emplace(key, val); } template static void set_optional_json_member(const string_view_type& key, const std::unique_ptr& val, Json& j) { if (val) j.try_emplace(key, val); } template static void set_optional_json_member(const string_view_type& key, const jsoncons::optional& val, Json& j) { if (val) j.try_emplace(key, val); } template static void set_optional_json_member(const string_view_type& key, const U& val, Json& j) { j.try_emplace(key, val); } }; } #if defined(_MSC_VER) #pragma warning( disable : 4127) #endif #define JSONCONS_CONCAT_IMPL(a, b) a ## b #define JSONCONS_CONCAT(a, b) JSONCONS_CONCAT_IMPL(a, b) // Inspired by https://github.com/Loki-Astari/ThorsSerializer/blob/master/src/Serialize/Traits.h #define JSONCONS_NARGS(...) JSONCONS_NARG_(__VA_ARGS__, 70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0) #define JSONCONS_NARG_(...) JSONCONS_EXPAND( JSONCONS_ARG_N(__VA_ARGS__) ) #define JSONCONS_ARG_N(e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15,e16,e17,e18,e19,e20,e21,e22,e23,e24,e25,e26,e27,e28,e29,e30,e31,e32,e33,e34,e35,e36,e37,e38,e39,e40,e41,e42,e43,e44,e45,e46,e47,e48,e49,e50,e51,e52,e53,e54,e55,e56,e57,e58,e59,e60,e61,e62,e63,e64,e65,e66,e67,e68,e69,e70,N,...)N #define JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, Count) Call(P1, P2, P3, P4, Count) #define JSONKONS_VARIADIC_FOR_EACH(Call, P1, P2, P3, ...) JSONCONS_VARIADIC_REP_OF_N(Call, P1,P2, P3, JSONCONS_NARGS(__VA_ARGS__), __VA_ARGS__) #define JSONCONS_VARIADIC_REP_OF_N(Call, P1, P2, P3, Count, ...) JSONCONS_VARIADIC_REP_OF_N_(Call, P1, P2, P3, Count, __VA_ARGS__) #define JSONCONS_VARIADIC_REP_OF_N_(Call, P1, P2, P3, Count, ...) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_ ## Count(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_70(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 70) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_69(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_69(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 69) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_68(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_68(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 68) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_67(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_67(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 67) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_66(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_66(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 66) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_65(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_65(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 65) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_64(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_64(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 64) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_63(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_63(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 63) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_62(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_62(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 62) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_61(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_61(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 61) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_60(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_60(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 60) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_59(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_59(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 59) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_58(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_58(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 58) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_57(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_57(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 57) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_56(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_56(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 56) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_55(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_55(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 55) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_54(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_54(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 54) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_53(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_53(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 53) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_52(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_52(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 52) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_51(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_51(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 51) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_50(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_50(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 50) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_49(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_49(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 49) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_48(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_48(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 48) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_47(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_47(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 47) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_46(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_46(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 46) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_45(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_45(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 45) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_44(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_44(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 44) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_43(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_43(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 43) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_42(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_42(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 42) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_41(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_41(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 41) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_40(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_40(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 40) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_39(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_39(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 39) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_38(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_38(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 38) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_37(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_37(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 37) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_36(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_36(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 36) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_35(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_35(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 35) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_34(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_34(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 34) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_33(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_33(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 33) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_32(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_32(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 32) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_31(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_31(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 31) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_30(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_30(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 30) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_29(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_29(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 29) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_28(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_28(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 28) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_27(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_27(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 27) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_26(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_26(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 26) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_25(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_25(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 25) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_24(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_24(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 24) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_23(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_23(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 23) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_22(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_22(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 22) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_21(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_21(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 21) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_20(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_20(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 20) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_19(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_19(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 19) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_18(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_18(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 18) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_17(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_17(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 17) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_16(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_16(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 16) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_15(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_15(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 15) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_14(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_14(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 14) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_13(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_13(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 13) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_12(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_12(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 12) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_11(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_11(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 11) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_10(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_10(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 10) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_9(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_9(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 9) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_8(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_8(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 8) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_7(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_7(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 7) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_6(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_6(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 6) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_5(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_5(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 5) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_4(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_4(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 4) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_3(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_3(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 3) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_2(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_2(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 2) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_1(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_1(Call, P1, P2, P3, P4) JSONCONS_EXPAND(Call ## _LAST(P1, P2, P3, P4, 1)) #define JSONCONS_TYPE_TRAITS_FRIEND \ template \ friend struct jsoncons::json_type_traits; #define JSONCONS_EXPAND_CALL2(Call, Expr, Id) JSONCONS_EXPAND(Call(Expr, Id)) #define JSONCONS_REP_OF_N(Call, Expr, Pre, App, Count) JSONCONS_REP_OF_ ## Count(Call, Expr, Pre, App) #define JSONCONS_REP_OF_50(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 50) JSONCONS_REP_OF_49(Call, Expr, , App) #define JSONCONS_REP_OF_49(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 49) JSONCONS_REP_OF_48(Call, Expr, , App) #define JSONCONS_REP_OF_48(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 48) JSONCONS_REP_OF_47(Call, Expr, , App) #define JSONCONS_REP_OF_47(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 47) JSONCONS_REP_OF_46(Call, Expr, , App) #define JSONCONS_REP_OF_46(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 46) JSONCONS_REP_OF_45(Call, Expr, , App) #define JSONCONS_REP_OF_45(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 45) JSONCONS_REP_OF_44(Call, Expr, , App) #define JSONCONS_REP_OF_44(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 44) JSONCONS_REP_OF_43(Call, Expr, , App) #define JSONCONS_REP_OF_43(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 43) JSONCONS_REP_OF_42(Call, Expr, , App) #define JSONCONS_REP_OF_42(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 42) JSONCONS_REP_OF_41(Call, Expr, , App) #define JSONCONS_REP_OF_41(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 41) JSONCONS_REP_OF_40(Call, Expr, , App) #define JSONCONS_REP_OF_40(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 40) JSONCONS_REP_OF_39(Call, Expr, , App) #define JSONCONS_REP_OF_39(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 39) JSONCONS_REP_OF_38(Call, Expr, , App) #define JSONCONS_REP_OF_38(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 38) JSONCONS_REP_OF_37(Call, Expr, , App) #define JSONCONS_REP_OF_37(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 37) JSONCONS_REP_OF_36(Call, Expr, , App) #define JSONCONS_REP_OF_36(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 36) JSONCONS_REP_OF_35(Call, Expr, , App) #define JSONCONS_REP_OF_35(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 35) JSONCONS_REP_OF_34(Call, Expr, , App) #define JSONCONS_REP_OF_34(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 34) JSONCONS_REP_OF_33(Call, Expr, , App) #define JSONCONS_REP_OF_33(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 33) JSONCONS_REP_OF_32(Call, Expr, , App) #define JSONCONS_REP_OF_32(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 32) JSONCONS_REP_OF_31(Call, Expr, , App) #define JSONCONS_REP_OF_31(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 31) JSONCONS_REP_OF_30(Call, Expr, , App) #define JSONCONS_REP_OF_30(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 30) JSONCONS_REP_OF_29(Call, Expr, , App) #define JSONCONS_REP_OF_29(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 29) JSONCONS_REP_OF_28(Call, Expr, , App) #define JSONCONS_REP_OF_28(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 28) JSONCONS_REP_OF_27(Call, Expr, , App) #define JSONCONS_REP_OF_27(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 27) JSONCONS_REP_OF_26(Call, Expr, , App) #define JSONCONS_REP_OF_26(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 26) JSONCONS_REP_OF_25(Call, Expr, , App) #define JSONCONS_REP_OF_25(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 25) JSONCONS_REP_OF_24(Call, Expr, , App) #define JSONCONS_REP_OF_24(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 24) JSONCONS_REP_OF_23(Call, Expr, , App) #define JSONCONS_REP_OF_23(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 23) JSONCONS_REP_OF_22(Call, Expr, , App) #define JSONCONS_REP_OF_22(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 22) JSONCONS_REP_OF_21(Call, Expr, , App) #define JSONCONS_REP_OF_21(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 21) JSONCONS_REP_OF_20(Call, Expr, , App) #define JSONCONS_REP_OF_20(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 20) JSONCONS_REP_OF_19(Call, Expr, , App) #define JSONCONS_REP_OF_19(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 19) JSONCONS_REP_OF_18(Call, Expr, , App) #define JSONCONS_REP_OF_18(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 18) JSONCONS_REP_OF_17(Call, Expr, , App) #define JSONCONS_REP_OF_17(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 17) JSONCONS_REP_OF_16(Call, Expr, , App) #define JSONCONS_REP_OF_16(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 16) JSONCONS_REP_OF_15(Call, Expr, , App) #define JSONCONS_REP_OF_15(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 15) JSONCONS_REP_OF_14(Call, Expr, , App) #define JSONCONS_REP_OF_14(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 14) JSONCONS_REP_OF_13(Call, Expr, , App) #define JSONCONS_REP_OF_13(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 13) JSONCONS_REP_OF_12(Call, Expr, , App) #define JSONCONS_REP_OF_12(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 12) JSONCONS_REP_OF_11(Call, Expr, , App) #define JSONCONS_REP_OF_11(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 11) JSONCONS_REP_OF_10(Call, Expr, , App) #define JSONCONS_REP_OF_10(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 10) JSONCONS_REP_OF_9(Call, Expr, , App) #define JSONCONS_REP_OF_9(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 9) JSONCONS_REP_OF_8(Call, Expr, , App) #define JSONCONS_REP_OF_8(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 8) JSONCONS_REP_OF_7(Call, Expr, , App) #define JSONCONS_REP_OF_7(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 7) JSONCONS_REP_OF_6(Call, Expr, , App) #define JSONCONS_REP_OF_6(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 6) JSONCONS_REP_OF_5(Call, Expr, , App) #define JSONCONS_REP_OF_5(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 5) JSONCONS_REP_OF_4(Call, Expr, , App) #define JSONCONS_REP_OF_4(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 4) JSONCONS_REP_OF_3(Call, Expr, , App) #define JSONCONS_REP_OF_3(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 3) JSONCONS_REP_OF_2(Call, Expr, , App) #define JSONCONS_REP_OF_2(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 2) JSONCONS_REP_OF_1(Call, Expr, , App) #define JSONCONS_REP_OF_1(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call ## _LAST, Expr, 1) App #define JSONCONS_REP_OF_0(Call, Expr, Pre, App) #define JSONCONS_GENERATE_TPL_PARAMS(Call, Count) JSONCONS_REP_OF_N(Call, , , ,Count) #define JSONCONS_GENERATE_TPL_ARGS(Call, Count) JSONCONS_REP_OF_N(Call, ,<,>,Count) #define JSONCONS_GENERATE_TPL_PARAM(Expr, Id) typename T ## Id, #define JSONCONS_GENERATE_TPL_PARAM_LAST(Expr, Id) typename T ## Id #define JSONCONS_GENERATE_MORE_TPL_PARAM(Expr, Id) ,typename T ## Id #define JSONCONS_GENERATE_MORE_TPL_PARAM_LAST(Expr, Id) ,typename T ## Id #define JSONCONS_GENERATE_TPL_ARG(Expr, Id) T ## Id, #define JSONCONS_GENERATE_TPL_ARG_LAST(Ex, Id) T ## Id #define JSONCONS_GENERATE_NAME_STR(Prefix, P2, P3, Member, Count) JSONCONS_GENERATE_NAME_STR_LAST(Prefix, P2, P3, Member, Count) #define JSONCONS_GENERATE_NAME_STR_LAST(Prefix, P2, P3, Member, Count) \ static inline const char* Member ## _str(char) {return JSONCONS_QUOTE(,Member);} \ static inline const wchar_t* Member ## _str(wchar_t) {return JSONCONS_QUOTE(L,Member);} \ /**/ #define JSONCONS_N_MEMBER_IS(Prefix, P2, P3, Member, Count) JSONCONS_N_MEMBER_IS_LAST(Prefix, P2, P3, Member, Count) #define JSONCONS_N_MEMBER_IS_LAST(Prefix, P2, P3, Member, Count) if ((num_params-Count) < num_mandatory_params1 && !ajson.contains(json_traits_macro_names::Member##_str(char_type{}))) return false; #define JSONCONS_N_MEMBER_AS(Prefix,P2,P3, Member, Count) JSONCONS_N_MEMBER_AS_LAST(Prefix,P2,P3, Member, Count) #define JSONCONS_N_MEMBER_AS_LAST(Prefix,P2,P3, Member, Count) \ if ((num_params-Count) < num_mandatory_params2 || ajson.contains(json_traits_macro_names::Member##_str(char_type{}))) \ {json_traits_helper::set_udt_member(ajson,json_traits_macro_names::Member##_str(char_type{}),class_instance.Member);} #define JSONCONS_ALL_MEMBER_AS(Prefix, P2,P3,Member, Count) JSONCONS_ALL_MEMBER_AS_LAST(Prefix,P2,P3, Member, Count) #define JSONCONS_ALL_MEMBER_AS_LAST(Prefix,P2,P3, Member, Count) \ json_traits_helper::set_udt_member(ajson,json_traits_macro_names::Member##_str(char_type{}),class_instance.Member); #define JSONCONS_TO_JSON(Prefix, P2, P3, Member, Count) JSONCONS_TO_JSON_LAST(Prefix, P2, P3, Member, Count) #define JSONCONS_TO_JSON_LAST(Prefix, P2, P3, Member, Count) if ((num_params-Count) < num_mandatory_params2) \ {ajson.try_emplace(json_traits_macro_names::Member##_str(char_type{}),class_instance.Member);} \ else {json_traits_helper::set_optional_json_member(json_traits_macro_names::Member##_str(char_type{}),class_instance.Member, ajson);} #define JSONCONS_ALL_TO_JSON(Prefix, P2, P3, Member, Count) JSONCONS_ALL_TO_JSON_LAST(Prefix, P2, P3, Member, Count) #define JSONCONS_ALL_TO_JSON_LAST(Prefix, P2, P3, Member, Count) \ ajson.try_emplace(json_traits_macro_names::Member##_str(char_type{}),class_instance.Member); #define JSONCONS_MEMBER_TRAITS_BASE(AsT,ToJ,NumTemplateParams,ClassType,NumMandatoryParams1,NumMandatoryParams2, ...) \ namespace jsoncons \ { \ template \ struct json_traits_macro_names \ { \ JSONKONS_VARIADIC_FOR_EACH(JSONCONS_GENERATE_NAME_STR, ,,, __VA_ARGS__)\ }; \ template \ struct json_type_traits \ { \ using class_type = ClassType JSONCONS_GENERATE_TPL_ARGS(JSONCONS_GENERATE_TPL_ARG, NumTemplateParams); \ using allocator_type = typename Json::allocator_type; \ using char_type = typename Json::char_type; \ using string_view_type = typename Json::string_view_type; \ constexpr static size_t num_params = JSONCONS_NARGS(__VA_ARGS__); \ constexpr static size_t num_mandatory_params1 = NumMandatoryParams1; \ constexpr static size_t num_mandatory_params2 = NumMandatoryParams2; \ static bool is(const Json& ajson) noexcept \ { \ if (!ajson.is_object()) return false; \ JSONKONS_VARIADIC_FOR_EACH(JSONCONS_N_MEMBER_IS, ,,, __VA_ARGS__)\ return true; \ } \ static class_type as(const Json& ajson) \ { \ if (!is(ajson)) JSONCONS_THROW(conv_error(conv_errc::conversion_failed, "Not a " # ClassType)); \ class_type class_instance{}; \ JSONKONS_VARIADIC_FOR_EACH(AsT, ,,, __VA_ARGS__) \ return class_instance; \ } \ static Json to_json(const class_type& class_instance, allocator_type alloc=allocator_type()) \ { \ Json ajson(json_object_arg, semantic_tag::none, alloc); \ JSONKONS_VARIADIC_FOR_EACH(ToJ, ,,, __VA_ARGS__) \ return ajson; \ } \ }; \ } \ /**/ #define JSONCONS_N_MEMBER_TRAITS(ClassType,NumMandatoryParams,...) \ JSONCONS_MEMBER_TRAITS_BASE(JSONCONS_N_MEMBER_AS, JSONCONS_TO_JSON,0, ClassType,NumMandatoryParams,NumMandatoryParams, __VA_ARGS__) \ namespace jsoncons { template <> struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_TPL_N_MEMBER_TRAITS(NumTemplateParams, ClassType,NumMandatoryParams, ...) \ JSONCONS_MEMBER_TRAITS_BASE(JSONCONS_N_MEMBER_AS, JSONCONS_TO_JSON,NumTemplateParams, ClassType,NumMandatoryParams,NumMandatoryParams, __VA_ARGS__) \ namespace jsoncons { template struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_ALL_MEMBER_TRAITS(ClassType, ...) \ JSONCONS_MEMBER_TRAITS_BASE(JSONCONS_ALL_MEMBER_AS,JSONCONS_ALL_TO_JSON,0,ClassType, JSONCONS_NARGS(__VA_ARGS__), JSONCONS_NARGS(__VA_ARGS__),__VA_ARGS__) \ namespace jsoncons { template <> struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_TPL_ALL_MEMBER_TRAITS(NumTemplateParams, ClassType, ...) \ JSONCONS_MEMBER_TRAITS_BASE(JSONCONS_ALL_MEMBER_AS,JSONCONS_ALL_TO_JSON,NumTemplateParams,ClassType, JSONCONS_NARGS(__VA_ARGS__), JSONCONS_NARGS(__VA_ARGS__),__VA_ARGS__) \ namespace jsoncons { template struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_MEMBER_NAME_IS(P1, P2, P3, Seq, Count) JSONCONS_MEMBER_NAME_IS_LAST(P1, P2, P3, Seq, Count) #define JSONCONS_MEMBER_NAME_IS_LAST(P1, P2, P3, Seq, Count) if ((num_params-Count) < num_mandatory_params1 && JSONCONS_EXPAND(JSONCONS_CONCAT(JSONCONS_MEMBER_NAME_IS_,JSONCONS_NARGS Seq) Seq) #define JSONCONS_MEMBER_NAME_IS_2(Member, Name) !ajson.contains(Name)) return false; #define JSONCONS_MEMBER_NAME_IS_3(Member, Name, Mode) JSONCONS_MEMBER_NAME_IS_2(Member, Name) #define JSONCONS_MEMBER_NAME_IS_4(Member, Name, Mode, Match) JSONCONS_MEMBER_NAME_IS_6(Member, Name, Mode, Match, , ) #define JSONCONS_MEMBER_NAME_IS_5(Member, Name, Mode, Match, Into) JSONCONS_MEMBER_NAME_IS_6(Member, Name, Mode, Match, Into, ) #define JSONCONS_MEMBER_NAME_IS_6(Member, Name, Mode, Match, Into, From) !ajson.contains(Name)) return false; \ JSONCONS_TRY{if (!Match(ajson.at(Name).template as())->Member))>::type>())) return false;} \ JSONCONS_CATCH(...) {return false;} #define JSONCONS_N_MEMBER_NAME_AS(P1, P2, P3, Seq, Count) JSONCONS_N_MEMBER_NAME_AS_LAST(P1, P2, P3, Seq, Count) #define JSONCONS_N_MEMBER_NAME_AS_LAST(P1, P2, P3, Seq, Count) JSONCONS_EXPAND(JSONCONS_CONCAT(JSONCONS_N_MEMBER_NAME_AS_,JSONCONS_NARGS Seq) Seq) #define JSONCONS_N_MEMBER_NAME_AS_2(Member, Name) \ if (ajson.contains(Name)) {json_traits_helper::set_udt_member(ajson,Name,class_instance.Member);} #define JSONCONS_N_MEMBER_NAME_AS_3(Member, Name, Mode) Mode(JSONCONS_N_MEMBER_NAME_AS_2(Member, Name)) #define JSONCONS_N_MEMBER_NAME_AS_4(Member, Name, Mode, Match) \ Mode(if (ajson.contains(Name)) {json_traits_helper::set_udt_member(ajson,Name,class_instance.Member);}) #define JSONCONS_N_MEMBER_NAME_AS_5(Member, Name, Mode, Match, Into) \ Mode(if (ajson.contains(Name)) {json_traits_helper::template set_udt_member())->Member))>::type>(ajson,Name,class_instance.Member);}) #define JSONCONS_N_MEMBER_NAME_AS_6(Member, Name, Mode, Match, Into, From) \ Mode(if (ajson.contains(Name)) {json_traits_helper::template set_udt_member())->Member))>::type>(ajson,Name,From,class_instance.Member);}) #define JSONCONS_ALL_MEMBER_NAME_AS(P1, P2, P3, Seq, Count) JSONCONS_ALL_MEMBER_NAME_AS_LAST(P1, P2, P3, Seq, Count) #define JSONCONS_ALL_MEMBER_NAME_AS_LAST(P1, P2, P3, Seq, Count) JSONCONS_EXPAND(JSONCONS_CONCAT(JSONCONS_ALL_MEMBER_NAME_AS_,JSONCONS_NARGS Seq) Seq) #define JSONCONS_ALL_MEMBER_NAME_AS_2(Member, Name) \ json_traits_helper::set_udt_member(ajson,Name,class_instance.Member); #define JSONCONS_ALL_MEMBER_NAME_AS_3(Member, Name, Mode) Mode(JSONCONS_ALL_MEMBER_NAME_AS_2(Member, Name)) #define JSONCONS_ALL_MEMBER_NAME_AS_4(Member, Name, Mode, Match) \ Mode(json_traits_helper::set_udt_member(ajson,Name,class_instance.Member);) #define JSONCONS_ALL_MEMBER_NAME_AS_5(Member, Name, Mode, Match, Into) \ Mode(json_traits_helper::template set_udt_member())->Member))>::type>(ajson,Name,class_instance.Member);) #define JSONCONS_ALL_MEMBER_NAME_AS_6(Member, Name, Mode, Match, Into, From) \ Mode(json_traits_helper::template set_udt_member())->Member))>::type>(ajson,Name,From,class_instance.Member);) #define JSONCONS_N_MEMBER_NAME_TO_JSON(P1, P2, P3, Seq, Count) JSONCONS_N_MEMBER_NAME_TO_JSON_LAST(P1, P2, P3, Seq, Count) #define JSONCONS_N_MEMBER_NAME_TO_JSON_LAST(P1, P2, P3, Seq, Count) if ((num_params-Count) < num_mandatory_params2) JSONCONS_EXPAND(JSONCONS_CONCAT(JSONCONS_N_MEMBER_NAME_TO_JSON_,JSONCONS_NARGS Seq) Seq) #define JSONCONS_N_MEMBER_NAME_TO_JSON_2(Member, Name) \ {ajson.try_emplace(Name,class_instance.Member);} \ else \ {json_traits_helper::set_optional_json_member(Name,class_instance.Member, ajson);} #define JSONCONS_N_MEMBER_NAME_TO_JSON_3(Member, Name, Mode) JSONCONS_N_MEMBER_NAME_TO_JSON_2(Member, Name) #define JSONCONS_N_MEMBER_NAME_TO_JSON_4(Member, Name, Mode, Match) JSONCONS_N_MEMBER_NAME_TO_JSON_6(Member, Name, Mode, Match,,) #define JSONCONS_N_MEMBER_NAME_TO_JSON_5(Member, Name, Mode, Match, Into) JSONCONS_N_MEMBER_NAME_TO_JSON_6(Member, Name, Mode, Match, Into, ) #define JSONCONS_N_MEMBER_NAME_TO_JSON_6(Member, Name, Mode, Match, Into, From) \ {ajson.try_emplace(Name, Into(class_instance.Member));} \ else \ {json_traits_helper::set_optional_json_member(Name, Into(class_instance.Member), ajson);} #define JSONCONS_ALL_MEMBER_NAME_TO_JSON(P1, P2, P3, Seq, Count) JSONCONS_ALL_MEMBER_NAME_TO_JSON_LAST(P1, P2, P3, Seq, Count) #define JSONCONS_ALL_MEMBER_NAME_TO_JSON_LAST(P1, P2, P3, Seq, Count) JSONCONS_EXPAND(JSONCONS_CONCAT(JSONCONS_ALL_MEMBER_NAME_TO_JSON_,JSONCONS_NARGS Seq) Seq) #define JSONCONS_ALL_MEMBER_NAME_TO_JSON_2(Member, Name) ajson.try_emplace(Name,class_instance.Member); #define JSONCONS_ALL_MEMBER_NAME_TO_JSON_3(Member, Name, Mode) JSONCONS_ALL_MEMBER_NAME_TO_JSON_2(Member, Name) #define JSONCONS_ALL_MEMBER_NAME_TO_JSON_4(Member, Name, Mode, Match) JSONCONS_ALL_MEMBER_NAME_TO_JSON_6(Member, Name, Mode, Match,,) #define JSONCONS_ALL_MEMBER_NAME_TO_JSON_5(Member, Name, Mode, Match, Into) JSONCONS_ALL_MEMBER_NAME_TO_JSON_6(Member, Name, Mode, Match, Into, ) #define JSONCONS_ALL_MEMBER_NAME_TO_JSON_6(Member, Name, Mode, Match, Into, From) ajson.try_emplace(Name, Into(class_instance.Member)); #define JSONCONS_MEMBER_NAME_TRAITS_BASE(AsT,ToJ, NumTemplateParams, ClassType,NumMandatoryParams1,NumMandatoryParams2, ...) \ namespace jsoncons \ { \ template \ struct json_type_traits \ { \ using class_type = ClassType JSONCONS_GENERATE_TPL_ARGS(JSONCONS_GENERATE_TPL_ARG, NumTemplateParams); \ using allocator_type = typename Json::allocator_type; \ using char_type = typename Json::char_type; \ using string_view_type = typename Json::string_view_type; \ constexpr static size_t num_params = JSONCONS_NARGS(__VA_ARGS__); \ constexpr static size_t num_mandatory_params1 = NumMandatoryParams1; \ constexpr static size_t num_mandatory_params2 = NumMandatoryParams2; \ static bool is(const Json& ajson) noexcept \ { \ if (!ajson.is_object()) return false; \ JSONKONS_VARIADIC_FOR_EACH(JSONCONS_MEMBER_NAME_IS,,,, __VA_ARGS__)\ return true; \ } \ static class_type as(const Json& ajson) \ { \ if (!is(ajson)) JSONCONS_THROW(conv_error(conv_errc::conversion_failed, "Not a " # ClassType)); \ class_type class_instance{}; \ JSONKONS_VARIADIC_FOR_EACH(AsT,,,, __VA_ARGS__) \ return class_instance; \ } \ static Json to_json(const class_type& class_instance, allocator_type alloc=allocator_type()) \ { \ Json ajson(json_object_arg, semantic_tag::none, alloc); \ JSONKONS_VARIADIC_FOR_EACH(ToJ,,,, __VA_ARGS__) \ return ajson; \ } \ }; \ } \ /**/ #define JSONCONS_N_MEMBER_NAME_TRAITS(ClassType,NumMandatoryParams, ...) \ JSONCONS_MEMBER_NAME_TRAITS_BASE(JSONCONS_N_MEMBER_NAME_AS, JSONCONS_N_MEMBER_NAME_TO_JSON, 0, ClassType,NumMandatoryParams,NumMandatoryParams, __VA_ARGS__) \ namespace jsoncons { template <> struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_TPL_N_MEMBER_NAME_TRAITS(NumTemplateParams, ClassType,NumMandatoryParams, ...) \ JSONCONS_MEMBER_NAME_TRAITS_BASE(JSONCONS_N_MEMBER_NAME_AS, JSONCONS_N_MEMBER_NAME_TO_JSON, NumTemplateParams, ClassType,NumMandatoryParams,NumMandatoryParams, __VA_ARGS__) \ namespace jsoncons { template struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_ALL_MEMBER_NAME_TRAITS(ClassType, ...) \ JSONCONS_MEMBER_NAME_TRAITS_BASE(JSONCONS_ALL_MEMBER_NAME_AS, JSONCONS_ALL_MEMBER_NAME_TO_JSON, 0, ClassType, JSONCONS_NARGS(__VA_ARGS__), JSONCONS_NARGS(__VA_ARGS__), __VA_ARGS__) \ namespace jsoncons { template <> struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_TPL_ALL_MEMBER_NAME_TRAITS(NumTemplateParams, ClassType, ...) \ JSONCONS_MEMBER_NAME_TRAITS_BASE(JSONCONS_ALL_MEMBER_NAME_AS, JSONCONS_ALL_MEMBER_NAME_TO_JSON, NumTemplateParams, ClassType, JSONCONS_NARGS(__VA_ARGS__), JSONCONS_NARGS(__VA_ARGS__), __VA_ARGS__) \ namespace jsoncons { template struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_CTOR_GETTER_IS(Prefix, P2, P3, Getter, Count) JSONCONS_CTOR_GETTER_IS_LAST(Prefix, P2, P3, Getter, Count) #define JSONCONS_CTOR_GETTER_IS_LAST(Prefix, P2, P3, Getter, Count) if ((num_params-Count) < num_mandatory_params1 && !ajson.contains(json_traits_macro_names::Getter##_str(char_type{}))) return false; #define JSONCONS_CTOR_GETTER_AS(Prefix, P2, P3, Getter, Count) JSONCONS_CTOR_GETTER_AS_LAST(Prefix, P2, P3, Getter, Count), #define JSONCONS_CTOR_GETTER_AS_LAST(Prefix, P2, P3, Getter, Count) ((num_params-Count) < num_mandatory_params2) ? (ajson.at(json_traits_macro_names::Getter##_str(char_type{}))).template as())->Getter())>::type>() : (ajson.contains(json_traits_macro_names::Getter##_str(char_type{})) ? (ajson.at(json_traits_macro_names::Getter##_str(char_type{}))).template as())->Getter())>::type>() : typename std::decay())->Getter())>::type()) #define JSONCONS_CTOR_GETTER_TO_JSON(Prefix, P2, P3, Getter, Count) JSONCONS_CTOR_GETTER_TO_JSON_LAST(Prefix, P2, P3, Getter, Count) #define JSONCONS_CTOR_GETTER_TO_JSON_LAST(Prefix, P2, P3, Getter, Count) \ if ((num_params-Count) < num_mandatory_params2) { \ ajson.try_emplace(json_traits_macro_names::Getter##_str(char_type{}),class_instance.Getter() ); \ } \ else { \ json_traits_helper::set_optional_json_member(json_traits_macro_names::Getter##_str(char_type{}),class_instance.Getter(), ajson); \ } #define JSONCONS_CTOR_GETTER_TRAITS_BASE(NumTemplateParams, ClassType,NumMandatoryParams1,NumMandatoryParams2, ...) \ namespace jsoncons \ { \ template \ struct json_traits_macro_names \ { \ JSONKONS_VARIADIC_FOR_EACH(JSONCONS_GENERATE_NAME_STR, ,,, __VA_ARGS__)\ }; \ template \ struct json_type_traits \ { \ using class_type = ClassType JSONCONS_GENERATE_TPL_ARGS(JSONCONS_GENERATE_TPL_ARG, NumTemplateParams); \ using allocator_type = typename Json::allocator_type; \ using char_type = typename Json::char_type; \ using string_view_type = typename Json::string_view_type; \ constexpr static size_t num_params = JSONCONS_NARGS(__VA_ARGS__); \ constexpr static size_t num_mandatory_params1 = NumMandatoryParams1; \ constexpr static size_t num_mandatory_params2 = NumMandatoryParams2; \ static bool is(const Json& ajson) noexcept \ { \ if (!ajson.is_object()) return false; \ JSONKONS_VARIADIC_FOR_EACH(JSONCONS_CTOR_GETTER_IS, ,,, __VA_ARGS__)\ return true; \ } \ static class_type as(const Json& ajson) \ { \ if (!is(ajson)) JSONCONS_THROW(conv_error(conv_errc::conversion_failed, "Not a " # ClassType)); \ return class_type ( JSONKONS_VARIADIC_FOR_EACH(JSONCONS_CTOR_GETTER_AS, ,,, __VA_ARGS__) ); \ } \ static Json to_json(const class_type& class_instance, allocator_type alloc=allocator_type()) \ { \ Json ajson(json_object_arg, semantic_tag::none, alloc); \ JSONKONS_VARIADIC_FOR_EACH(JSONCONS_CTOR_GETTER_TO_JSON, ,,, __VA_ARGS__) \ return ajson; \ } \ }; \ } \ /**/ #define JSONCONS_ALL_CTOR_GETTER_TRAITS(ClassType, ...) \ JSONCONS_CTOR_GETTER_TRAITS_BASE(0, ClassType, JSONCONS_NARGS(__VA_ARGS__), JSONCONS_NARGS(__VA_ARGS__), __VA_ARGS__) \ namespace jsoncons { template <> struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_TPL_ALL_CTOR_GETTER_TRAITS(NumTemplateParams, ClassType, ...) \ JSONCONS_CTOR_GETTER_TRAITS_BASE(NumTemplateParams, ClassType, JSONCONS_NARGS(__VA_ARGS__), JSONCONS_NARGS(__VA_ARGS__), __VA_ARGS__) \ namespace jsoncons { template struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_N_CTOR_GETTER_TRAITS(ClassType,NumMandatoryParams, ...) \ JSONCONS_CTOR_GETTER_TRAITS_BASE(0, ClassType,NumMandatoryParams,NumMandatoryParams, __VA_ARGS__) \ namespace jsoncons { template <> struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_N_ALL_CTOR_GETTER_TRAITS(NumTemplateParams, ClassType,NumMandatoryParams, ...) \ JSONCONS_CTOR_GETTER_TRAITS_BASE(NumTemplateParams, ClassType,NumMandatoryParams,NumMandatoryParams, __VA_ARGS__) \ namespace jsoncons { template <> struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_CTOR_GETTER_NAME_IS(P1, P2, P3, Seq, Count) JSONCONS_CTOR_GETTER_NAME_IS_LAST(P1, P2, P3, Seq, Count) #define JSONCONS_CTOR_GETTER_NAME_IS_LAST(P1, P2, P3, Seq, Count) if ((num_params-Count) < num_mandatory_params1 && JSONCONS_EXPAND(JSONCONS_CONCAT(JSONCONS_CTOR_GETTER_NAME_IS_,JSONCONS_NARGS Seq) Seq) #define JSONCONS_CTOR_GETTER_NAME_IS_2(Getter, Name) !ajson.contains(Name)) return false; #define JSONCONS_CTOR_GETTER_NAME_IS_3(Getter, Name, Mode) JSONCONS_CTOR_GETTER_NAME_IS_2(Getter, Name) #define JSONCONS_CTOR_GETTER_NAME_IS_4(Getter, Name, Mode, Match) JSONCONS_CTOR_GETTER_NAME_IS_6(Getter, Name, Mode, Match, , ) #define JSONCONS_CTOR_GETTER_NAME_IS_5(Getter, Name, Mode, Match, Into) JSONCONS_CTOR_GETTER_NAME_IS_6(Getter, Name, Mode, Match, Into, ) #define JSONCONS_CTOR_GETTER_NAME_IS_6(Getter, Name, Mode, Match, Into, From) !ajson.contains(Name)) return false; \ JSONCONS_TRY{if (!Match(ajson.at(Name).template as())->Getter()))>::type>())) return false;} \ JSONCONS_CATCH(...) {return false;} #define JSONCONS_CTOR_GETTER_NAME_AS(P1, P2, P3, Seq, Count) JSONCONS_EXPAND(JSONCONS_CONCAT(JSONCONS_CTOR_GETTER_NAME_AS_,JSONCONS_NARGS Seq) Seq) #define JSONCONS_CTOR_GETTER_NAME_AS_2(Getter, Name) JSONCONS_CTOR_GETTER_NAME_AS_LAST_2(Getter, Name) JSONCONS_COMMA #define JSONCONS_CTOR_GETTER_NAME_AS_3(Getter, Name, Mode) Mode(JSONCONS_CTOR_GETTER_NAME_AS_LAST_2(Getter, Name)) Mode(JSONCONS_COMMA) #define JSONCONS_CTOR_GETTER_NAME_AS_4(Getter, Name, Mode, Match) JSONCONS_CTOR_GETTER_NAME_AS_6(Getter, Name, Mode, Match,,) #define JSONCONS_CTOR_GETTER_NAME_AS_5(Getter, Name, Mode, Match, Into) JSONCONS_CTOR_GETTER_NAME_AS_6(Getter, Name, Mode, Match, Into, ) #define JSONCONS_CTOR_GETTER_NAME_AS_6(Getter, Name, Mode, Match, Into, From) JSONCONS_CTOR_GETTER_NAME_AS_LAST_6(Getter,Name,Mode,Match,Into,From) Mode(JSONCONS_COMMA) #define JSONCONS_COMMA , #define JSONCONS_CTOR_GETTER_NAME_AS_LAST(P1, P2, P3, Seq, Count) JSONCONS_EXPAND(JSONCONS_CONCAT(JSONCONS_CTOR_GETTER_NAME_AS_LAST_,JSONCONS_NARGS Seq) Seq) #define JSONCONS_CTOR_GETTER_NAME_AS_LAST_2(Getter, Name) (ajson.contains(Name)) ? (ajson.at(Name)).template as())->Getter())>::type>() : typename std::decay())->Getter())>::type() #define JSONCONS_CTOR_GETTER_NAME_AS_LAST_3(Getter, Name, Mode) Mode(JSONCONS_CTOR_GETTER_NAME_AS_LAST_2(Getter, Name)) #define JSONCONS_CTOR_GETTER_NAME_AS_LAST_4(Getter, Name, Mode, Match) JSONCONS_CTOR_GETTER_NAME_AS_LAST_6(Getter, Name, Mode, Match,,) #define JSONCONS_CTOR_GETTER_NAME_AS_LAST_5(Getter, Name, Mode, Match, Into) JSONCONS_CTOR_GETTER_NAME_AS_LAST_6(Getter, Name, Mode, Match, Into, ) #define JSONCONS_CTOR_GETTER_NAME_AS_LAST_6(Getter, Name, Mode, Match, Into, From) Mode(ajson.contains(Name) ? From(ajson.at(Name).template as())->Getter()))>::type>()) : From(typename std::decay())->Getter()))>::type())) #define JSONCONS_CTOR_GETTER_NAME_TO_JSON(P1, P2, P3, Seq, Count) JSONCONS_CTOR_GETTER_NAME_TO_JSON_LAST(P1, P2, P3, Seq, Count) #define JSONCONS_CTOR_GETTER_NAME_TO_JSON_LAST(P1, P2, P3, Seq, Count) if ((num_params-Count) < num_mandatory_params2) JSONCONS_EXPAND(JSONCONS_CONCAT(JSONCONS_CTOR_GETTER_NAME_TO_JSON_,JSONCONS_NARGS Seq) Seq) #define JSONCONS_CTOR_GETTER_NAME_TO_JSON_2(Getter, Name) \ { \ ajson.try_emplace(Name,class_instance.Getter() ); \ } \ else { \ json_traits_helper::set_optional_json_member(Name,class_instance.Getter(), ajson); \ } #define JSONCONS_CTOR_GETTER_NAME_TO_JSON_3(Getter, Name, Mode) JSONCONS_CTOR_GETTER_NAME_TO_JSON_2(Getter, Name) #define JSONCONS_CTOR_GETTER_NAME_TO_JSON_4(Getter, Name, Mode, Match) JSONCONS_CTOR_GETTER_NAME_TO_JSON_2(Getter, Name) #define JSONCONS_CTOR_GETTER_NAME_TO_JSON_5(Getter, Name, Mode, Match, Into) JSONCONS_CTOR_GETTER_NAME_TO_JSON_6(Getter, Name, Mode, Match, Into, ) #define JSONCONS_CTOR_GETTER_NAME_TO_JSON_6(Getter, Name, Mode, Match, Into, From) \ { \ ajson.try_emplace(Name, Into(class_instance.Getter()) ); \ } \ else { \ json_traits_helper::set_optional_json_member(Name, Into(class_instance.Getter()), ajson); \ } #define JSONCONS_CTOR_GETTER_NAME_TRAITS_BASE(NumTemplateParams, ClassType,NumMandatoryParams1,NumMandatoryParams2, ...) \ namespace jsoncons \ { \ template \ struct json_type_traits \ { \ using class_type = ClassType JSONCONS_GENERATE_TPL_ARGS(JSONCONS_GENERATE_TPL_ARG, NumTemplateParams); \ using allocator_type = typename Json::allocator_type; \ using char_type = typename Json::char_type; \ using string_view_type = typename Json::string_view_type; \ constexpr static size_t num_params = JSONCONS_NARGS(__VA_ARGS__); \ constexpr static size_t num_mandatory_params1 = NumMandatoryParams1; \ constexpr static size_t num_mandatory_params2 = NumMandatoryParams2; \ static bool is(const Json& ajson) noexcept \ { \ if (!ajson.is_object()) return false; \ JSONKONS_VARIADIC_FOR_EACH(JSONCONS_CTOR_GETTER_NAME_IS,,,, __VA_ARGS__)\ return true; \ } \ static class_type as(const Json& ajson) \ { \ if (!is(ajson)) JSONCONS_THROW(conv_error(conv_errc::conversion_failed, "Not a " # ClassType)); \ return class_type ( JSONKONS_VARIADIC_FOR_EACH(JSONCONS_CTOR_GETTER_NAME_AS,,,, __VA_ARGS__) ); \ } \ static Json to_json(const class_type& class_instance, allocator_type alloc=allocator_type()) \ { \ Json ajson(json_object_arg, semantic_tag::none, alloc); \ JSONKONS_VARIADIC_FOR_EACH(JSONCONS_CTOR_GETTER_NAME_TO_JSON,,,, __VA_ARGS__) \ return ajson; \ } \ }; \ } \ /**/ #define JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ClassType, ...) \ JSONCONS_CTOR_GETTER_NAME_TRAITS_BASE(0, ClassType, JSONCONS_NARGS(__VA_ARGS__), JSONCONS_NARGS(__VA_ARGS__), __VA_ARGS__) \ namespace jsoncons { template <> struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_TPL_ALL_CTOR_GETTER_NAME_TRAITS(NumTemplateParams, ClassType, ...) \ JSONCONS_CTOR_GETTER_NAME_TRAITS_BASE(NumTemplateParams, ClassType, JSONCONS_NARGS(__VA_ARGS__), JSONCONS_NARGS(__VA_ARGS__), __VA_ARGS__) \ namespace jsoncons { template struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_N_CTOR_GETTER_NAME_TRAITS(ClassType,NumMandatoryParams, ...) \ JSONCONS_CTOR_GETTER_NAME_TRAITS_BASE(0, ClassType,NumMandatoryParams,NumMandatoryParams, __VA_ARGS__) \ namespace jsoncons { template <> struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_TPL_N_CTOR_GETTER_NAME_TRAITS(NumTemplateParams, ClassType,NumMandatoryParams, ...) \ JSONCONS_CTOR_GETTER_NAME_TRAITS_BASE(NumTemplateParams, ClassType,NumMandatoryParams,NumMandatoryParams, __VA_ARGS__) \ namespace jsoncons { template struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_ENUM_PAIR(Prefix, P2, P3, Member, Count) JSONCONS_ENUM_PAIR_LAST(Prefix, P2, P3, Member, Count), #define JSONCONS_ENUM_PAIR_LAST(Prefix, P2, P3, Member, Count) {enum_type::Member, json_traits_macro_names::Member##_str(char_type{})} #define JSONCONS_ENUM_TRAITS_BASE(EnumType, ...) \ namespace jsoncons \ { \ template \ struct json_traits_macro_names \ { \ JSONKONS_VARIADIC_FOR_EACH(JSONCONS_GENERATE_NAME_STR, ,,, __VA_ARGS__)\ }; \ template \ struct json_type_traits \ { \ static_assert(std::is_enum::value, # EnumType " must be an enum"); \ using enum_type = EnumType; \ using char_type = typename Json::char_type; \ using string_type = std::basic_string; \ using string_view_type = jsoncons::basic_string_view; \ using allocator_type = typename Json::allocator_type; \ using mapped_type = std::pair; \ \ static std::pair get_values() \ { \ static const mapped_type v[] = { \ JSONKONS_VARIADIC_FOR_EACH(JSONCONS_ENUM_PAIR, ,,, __VA_ARGS__)\ };\ return std::make_pair(v,v+JSONCONS_NARGS(__VA_ARGS__)); \ } \ \ static bool is(const Json& ajson) noexcept \ { \ if (!ajson.is_string()) return false; \ auto first = get_values().first; \ auto last = get_values().second; \ const string_view_type s = ajson.template as(); \ if (s.empty() && std::find_if(first, last, \ [](const mapped_type& item) -> bool \ { return item.first == enum_type(); }) == last) \ { \ return true; \ } \ auto it = std::find_if(first, last, \ [&](const mapped_type& item) -> bool \ { return item.second == s; }); \ return it != last; \ } \ static enum_type as(const Json& ajson) \ { \ if (!is(ajson)) JSONCONS_THROW(conv_error(conv_errc::conversion_failed, "Not a " # EnumType)); \ const string_view_type s = ajson.template as(); \ auto first = get_values().first; \ auto last = get_values().second; \ if (s.empty() && std::find_if(first, last, \ [](const mapped_type& item) -> bool \ { return item.first == enum_type(); }) == last) \ { \ return enum_type(); \ } \ auto it = std::find_if(first, last, \ [&](const mapped_type& item) -> bool \ { return item.second == s; }); \ if (it == last) \ { \ if (s.empty()) \ { \ return enum_type(); \ } \ else \ { \ JSONCONS_THROW(conv_error(conv_errc::conversion_failed, "Not an enum")); \ } \ } \ return (*it).first; \ } \ static Json to_json(enum_type class_instance, allocator_type alloc=allocator_type()) \ { \ static constexpr char_type empty_string[] = {0}; \ auto first = get_values().first; \ auto last = get_values().second; \ auto it = std::find_if(first, last, \ [class_instance](const mapped_type& item) -> bool \ { return item.first == class_instance; }); \ if (it == last) \ { \ if (class_instance == enum_type()) \ { \ return Json(empty_string); \ } \ else \ { \ JSONCONS_THROW(conv_error(conv_errc::conversion_failed, "Not an enum")); \ } \ } \ return Json((*it).second,alloc); \ } \ }; \ } \ /**/ #define JSONCONS_ENUM_TRAITS(EnumType, ...) \ JSONCONS_ENUM_TRAITS_BASE(EnumType,__VA_ARGS__) \ namespace jsoncons { template <> struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_NAME_ENUM_PAIR(P1, P2, P3, Seq, Count) JSONCONS_EXPAND(JSONCONS_NAME_ENUM_PAIR_ Seq), #define JSONCONS_NAME_ENUM_PAIR_LAST(P1, P2, P3, Seq, Count) JSONCONS_EXPAND(JSONCONS_NAME_ENUM_PAIR_ Seq) #define JSONCONS_NAME_ENUM_PAIR_(Member, Name) {enum_type::Member, Name} #define JSONCONS_ENUM_NAME_TRAITS(EnumType, ...) \ namespace jsoncons \ { \ template \ struct json_type_traits \ { \ static_assert(std::is_enum::value, # EnumType " must be an enum"); \ using enum_type = EnumType; \ using char_type = typename Json::char_type; \ using string_type = std::basic_string; \ using string_view_type = jsoncons::basic_string_view; \ using allocator_type = typename Json::allocator_type; \ using mapped_type = std::pair; \ \ static std::pair get_values() \ { \ static const mapped_type v[] = { \ JSONKONS_VARIADIC_FOR_EACH(JSONCONS_NAME_ENUM_PAIR,,,, __VA_ARGS__)\ };\ return std::make_pair(v,v+JSONCONS_NARGS(__VA_ARGS__)); \ } \ \ static bool is(const Json& ajson) noexcept \ { \ if (!ajson.is_string()) return false; \ auto first = get_values().first; \ auto last = get_values().second; \ const string_view_type s = ajson.template as(); \ if (s.empty() && std::find_if(first, last, \ [](const mapped_type& item) -> bool \ { return item.first == enum_type(); }) == last) \ { \ return true; \ } \ auto it = std::find_if(first, last, \ [&](const mapped_type& item) -> bool \ { return item.second == s; }); \ return it != last; \ } \ static enum_type as(const Json& ajson) \ { \ if (!is(ajson)) JSONCONS_THROW(conv_error(conv_errc::conversion_failed, "Not a " # EnumType)); \ const string_view_type s = ajson.template as(); \ auto first = get_values().first; \ auto last = get_values().second; \ if (s.empty() && std::find_if(first, last, \ [](const mapped_type& item) -> bool \ { return item.first == enum_type(); }) == last) \ { \ return enum_type(); \ } \ auto it = std::find_if(first, last, \ [&](const mapped_type& item) -> bool \ { return item.second == s; }); \ if (it == last) \ { \ if (s.empty()) \ { \ return enum_type(); \ } \ else \ { \ JSONCONS_THROW(conv_error(conv_errc::conversion_failed, "Not an enum")); \ } \ } \ return (*it).first; \ } \ static Json to_json(enum_type class_instance, allocator_type alloc=allocator_type()) \ { \ static constexpr char_type empty_string[] = {0}; \ auto first = get_values().first; \ auto last = get_values().second; \ auto it = std::find_if(first, last, \ [class_instance](const mapped_type& item) -> bool \ { return item.first == class_instance; }); \ if (it == last) \ { \ if (class_instance == enum_type()) \ { \ return Json(empty_string); \ } \ else \ { \ JSONCONS_THROW(conv_error(conv_errc::conversion_failed, "Not an enum")); \ } \ } \ return Json((*it).second,alloc); \ } \ }; \ template <> struct is_json_type_traits_declared : public std::true_type {}; \ } \ /**/ #define JSONCONS_GETTER_SETTER_AS(Prefix, GetPrefix, SetPrefix, Property, Count) JSONCONS_GETTER_SETTER_AS_(Prefix, GetPrefix ## Property, SetPrefix ## Property, Property, Count) #define JSONCONS_GETTER_SETTER_AS_LAST(Prefix, GetPrefix, SetPrefix, Property, Count) JSONCONS_GETTER_SETTER_AS_(Prefix, GetPrefix ## Property, SetPrefix ## Property, Property, Count) #define JSONCONS_GETTER_SETTER_AS_(Prefix, Getter, Setter, Property, Count) if ((num_params-Count) < num_mandatory_params2 || ajson.contains(json_traits_macro_names::Property##_str(char_type{}))) {class_instance.Setter(ajson.at(json_traits_macro_names::Property##_str(char_type{})).template as::type>());} #define JSONCONS_ALL_GETTER_SETTER_AS(Prefix, GetPrefix, SetPrefix, Property, Count) JSONCONS_ALL_GETTER_SETTER_AS_(Prefix, GetPrefix ## Property, SetPrefix ## Property, Property, Count) #define JSONCONS_ALL_GETTER_SETTER_AS_LAST(Prefix, GetPrefix, SetPrefix, Property, Count) JSONCONS_ALL_GETTER_SETTER_AS_(Prefix, GetPrefix ## Property, SetPrefix ## Property, Property, Count) #define JSONCONS_ALL_GETTER_SETTER_AS_(Prefix, Getter, Setter, Property, Count) class_instance.Setter(ajson.at(json_traits_macro_names::Property##_str(char_type{})).template as::type>()); #define JSONCONS_GETTER_SETTER_TO_JSON(Prefix, GetPrefix, SetPrefix, Property, Count) JSONCONS_GETTER_SETTER_TO_JSON_(Prefix, GetPrefix ## Property, SetPrefix ## Property, Property, Count) #define JSONCONS_GETTER_SETTER_TO_JSON_LAST(Prefix, GetPrefix, SetPrefix, Property, Count) JSONCONS_GETTER_SETTER_TO_JSON_(Prefix, GetPrefix ## Property, SetPrefix ## Property, Property, Count) #define JSONCONS_GETTER_SETTER_TO_JSON_(Prefix, Getter, Setter, Property, Count) \ if ((num_params-Count) < num_mandatory_params2) \ {ajson.try_emplace(json_traits_macro_names::Property##_str(char_type{}),class_instance.Getter());} \ else \ {json_traits_helper::set_optional_json_member(json_traits_macro_names::Property##_str(char_type{}),class_instance.Getter(), ajson);} #define JSONCONS_ALL_GETTER_SETTER_TO_JSON(Prefix, GetPrefix, SetPrefix, Property, Count) JSONCONS_ALL_GETTER_SETTER_TO_JSON_(Prefix, GetPrefix ## Property, SetPrefix ## Property, Property, Count) #define JSONCONS_ALL_GETTER_SETTER_TO_JSON_LAST(Prefix, GetPrefix, SetPrefix, Property, Count) JSONCONS_ALL_GETTER_SETTER_TO_JSON_(Prefix, GetPrefix ## Property, SetPrefix ## Property, Property, Count) #define JSONCONS_ALL_GETTER_SETTER_TO_JSON_(Prefix, Getter, Setter, Property, Count) ajson.try_emplace(json_traits_macro_names::Property##_str(char_type{}),class_instance.Getter() ); #define JSONCONS_GETTER_SETTER_TRAITS_BASE(AsT,ToJ,NumTemplateParams, ClassType,GetPrefix,SetPrefix,NumMandatoryParams1,NumMandatoryParams2, ...) \ namespace jsoncons \ { \ template \ struct json_traits_macro_names \ { \ JSONKONS_VARIADIC_FOR_EACH(JSONCONS_GENERATE_NAME_STR, ,,, __VA_ARGS__)\ }; \ template \ struct json_type_traits \ { \ using class_type = ClassType JSONCONS_GENERATE_TPL_ARGS(JSONCONS_GENERATE_TPL_ARG, NumTemplateParams); \ using allocator_type = typename Json::allocator_type; \ using char_type = typename Json::char_type; \ using string_view_type = typename Json::string_view_type; \ constexpr static size_t num_params = JSONCONS_NARGS(__VA_ARGS__); \ constexpr static size_t num_mandatory_params1 = NumMandatoryParams1; \ constexpr static size_t num_mandatory_params2 = NumMandatoryParams2; \ static bool is(const Json& ajson) noexcept \ { \ if (!ajson.is_object()) return false; \ JSONKONS_VARIADIC_FOR_EACH(JSONCONS_N_MEMBER_IS, ,GetPrefix,SetPrefix, __VA_ARGS__)\ return true; \ } \ static class_type as(const Json& ajson) \ { \ if (!is(ajson)) JSONCONS_THROW(conv_error(conv_errc::conversion_failed, "Not a " # ClassType)); \ class_type class_instance{}; \ JSONKONS_VARIADIC_FOR_EACH(AsT, ,GetPrefix,SetPrefix, __VA_ARGS__) \ return class_instance; \ } \ static Json to_json(const class_type& class_instance, allocator_type alloc=allocator_type()) \ { \ Json ajson(json_object_arg, semantic_tag::none, alloc); \ JSONKONS_VARIADIC_FOR_EACH(ToJ, ,GetPrefix,SetPrefix, __VA_ARGS__) \ return ajson; \ } \ }; \ } \ /**/ #define JSONCONS_N_GETTER_SETTER_TRAITS(ClassType,GetPrefix,SetPrefix,NumMandatoryParams, ...) \ JSONCONS_GETTER_SETTER_TRAITS_BASE(JSONCONS_GETTER_SETTER_AS, JSONCONS_GETTER_SETTER_TO_JSON,0, ClassType,GetPrefix,SetPrefix,NumMandatoryParams,NumMandatoryParams, __VA_ARGS__) \ namespace jsoncons { template <> struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_TPL_N_GETTER_SETTER_TRAITS(NumTemplateParams, ClassType,GetPrefix,SetPrefix,NumMandatoryParams, ...) \ JSONCONS_GETTER_SETTER_TRAITS_BASE(JSONCONS_GETTER_SETTER_AS, JSONCONS_GETTER_SETTER_TO_JSON,NumTemplateParams, ClassType,GetPrefix,SetPrefix,NumMandatoryParams,NumMandatoryParams, __VA_ARGS__) \ namespace jsoncons { template struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_ALL_GETTER_SETTER_TRAITS(ClassType,GetPrefix,SetPrefix, ...) \ JSONCONS_GETTER_SETTER_TRAITS_BASE(JSONCONS_ALL_GETTER_SETTER_AS, JSONCONS_ALL_GETTER_SETTER_TO_JSON,0,ClassType,GetPrefix,SetPrefix, JSONCONS_NARGS(__VA_ARGS__), JSONCONS_NARGS(__VA_ARGS__),__VA_ARGS__) \ namespace jsoncons { template <> struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_TPL_ALL_GETTER_SETTER_TRAITS(NumTemplateParams, ClassType,GetPrefix,SetPrefix, ...) \ JSONCONS_GETTER_SETTER_TRAITS_BASE(JSONCONS_ALL_GETTER_SETTER_AS, JSONCONS_ALL_GETTER_SETTER_TO_JSON,NumTemplateParams,ClassType,GetPrefix,SetPrefix, JSONCONS_NARGS(__VA_ARGS__), JSONCONS_NARGS(__VA_ARGS__),__VA_ARGS__) \ namespace jsoncons { template struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_GETTER_SETTER_NAME_IS(P1, P2, P3, Seq, Count) JSONCONS_GETTER_SETTER_NAME_IS_LAST(P1, P2, P3, Seq, Count) #define JSONCONS_GETTER_SETTER_NAME_IS_LAST(P1, P2, P3, Seq, Count) if ((num_params-Count) < num_mandatory_params1 && JSONCONS_EXPAND(JSONCONS_CONCAT(JSONCONS_GETTER_SETTER_NAME_IS_,JSONCONS_NARGS Seq) Seq) #define JSONCONS_GETTER_SETTER_NAME_IS_3(Getter, Setter, Name) !ajson.contains(Name)) return false; #define JSONCONS_GETTER_SETTER_NAME_IS_5(Getter, Setter, Name, Mode, Match) JSONCONS_GETTER_SETTER_NAME_IS_7(Getter, Setter, Name, Mode, Match,, ) #define JSONCONS_GETTER_SETTER_NAME_IS_6(Getter, Setter, Name, Mode, Match, Into) JSONCONS_GETTER_SETTER_NAME_IS_7(Getter, Setter, Name, Mode, Match, Into, ) #define JSONCONS_GETTER_SETTER_NAME_IS_7(Getter, Setter, Name, Mode, Match, Into, From) !ajson.contains(Name)) return false; \ JSONCONS_TRY{if (!Match(ajson.at(Name).template as())->Getter()))>::type>())) return false;} \ JSONCONS_CATCH(...) {return false;} #define JSONCONS_N_GETTER_SETTER_NAME_AS(P1, P2, P3, Seq, Count) JSONCONS_N_GETTER_SETTER_NAME_AS_LAST(P1, P2, P3, Seq, Count) #define JSONCONS_N_GETTER_SETTER_NAME_AS_LAST(P1, P2, P3, Seq, Count) JSONCONS_EXPAND(JSONCONS_CONCAT(JSONCONS_N_GETTER_SETTER_NAME_AS_,JSONCONS_NARGS Seq) Seq) #define JSONCONS_N_GETTER_SETTER_NAME_AS_3(Getter, Setter, Name) if (ajson.contains(Name)) class_instance.Setter(ajson.at(Name).template as::type>()); #define JSONCONS_N_GETTER_SETTER_NAME_AS_4(Getter, Setter, Name, Mode) Mode(JSONCONS_N_GETTER_SETTER_NAME_AS_3(Getter, Setter, Name)) #define JSONCONS_N_GETTER_SETTER_NAME_AS_5(Getter, Setter, Name, Mode, Match) JSONCONS_N_GETTER_SETTER_NAME_AS_7(Getter, Setter, Name, Mode, Match, , ) #define JSONCONS_N_GETTER_SETTER_NAME_AS_6(Getter, Setter, Name, Mode, Match, Into) JSONCONS_N_GETTER_SETTER_NAME_AS_7(Getter, Setter, Name, Mode, Match, Into, ) #define JSONCONS_N_GETTER_SETTER_NAME_AS_7(Getter, Setter, Name, Mode, Match, Into, From) Mode(if (ajson.contains(Name)) class_instance.Setter(From(ajson.at(Name).template as::type>()));) #define JSONCONS_N_GETTER_SETTER_NAME_TO_JSON(P1, P2, P3, Seq, Count) JSONCONS_N_GETTER_SETTER_NAME_TO_JSON_LAST(P1, P2, P3, Seq, Count) #define JSONCONS_N_GETTER_SETTER_NAME_TO_JSON_LAST(P1, P2, P3, Seq, Count) JSONCONS_EXPAND(JSONCONS_CONCAT(JSONCONS_N_GETTER_SETTER_NAME_TO_JSON_,JSONCONS_NARGS Seq) Seq) #define JSONCONS_N_GETTER_SETTER_NAME_TO_JSON_3(Getter, Setter, Name) ajson.try_emplace(Name,class_instance.Getter() ); #define JSONCONS_N_GETTER_SETTER_NAME_TO_JSON_5(Getter, Setter, Name, Mode, Match) JSONCONS_N_GETTER_SETTER_NAME_TO_JSON_7(Getter, Setter, Name, Mode, Match, , ) #define JSONCONS_N_GETTER_SETTER_NAME_TO_JSON_6(Getter, Setter, Name, Mode, Match, Into) JSONCONS_N_GETTER_SETTER_NAME_TO_JSON_7(Getter, Setter, Name, Mode, Match, Into, ) #define JSONCONS_N_GETTER_SETTER_NAME_TO_JSON_7(Getter, Setter, Name, Mode, Match, Into, From) ajson.try_emplace(Name, Into(class_instance.Getter()) ); #define JSONCONS_ALL_GETTER_SETTER_NAME_AS(P1, P2, P3, Seq, Count) JSONCONS_ALL_GETTER_SETTER_NAME_AS_LAST(P1, P2, P3, Seq, Count) #define JSONCONS_ALL_GETTER_SETTER_NAME_AS_LAST(P1, P2, P3, Seq, Count) JSONCONS_EXPAND(JSONCONS_CONCAT(JSONCONS_ALL_GETTER_SETTER_NAME_AS_,JSONCONS_NARGS Seq) Seq) #define JSONCONS_ALL_GETTER_SETTER_NAME_AS_3(Getter, Setter, Name) class_instance.Setter(ajson.at(Name).template as::type>()); #define JSONCONS_ALL_GETTER_SETTER_NAME_AS_4(Getter, Setter, Name, Mode) Mode(JSONCONS_ALL_GETTER_SETTER_NAME_AS_3(Getter, Setter, Name)) #define JSONCONS_ALL_GETTER_SETTER_NAME_AS_5(Getter, Setter, Name, Mode, Match) JSONCONS_ALL_GETTER_SETTER_NAME_AS_7(Getter, Setter, Name, Mode, Match, , ) #define JSONCONS_ALL_GETTER_SETTER_NAME_AS_6(Getter, Setter, Name, Mode, Match, Into) JSONCONS_ALL_GETTER_SETTER_NAME_AS_7(Getter, Setter, Name, Mode, Match, Into, ) #define JSONCONS_ALL_GETTER_SETTER_NAME_AS_7(Getter, Setter, Name, Mode, Match, Into, From) Mode(class_instance.Setter(From(ajson.at(Name).template as::type>()));) #define JSONCONS_ALL_GETTER_SETTER_NAME_TO_JSON(P1, P2, P3, Seq, Count) JSONCONS_ALL_GETTER_SETTER_NAME_TO_JSON_LAST(P1, P2, P3, Seq, Count) #define JSONCONS_ALL_GETTER_SETTER_NAME_TO_JSON_LAST(P1, P2, P3, Seq, Count) if ((num_params-Count) < num_mandatory_params2) JSONCONS_EXPAND(JSONCONS_CONCAT(JSONCONS_ALL_GETTER_SETTER_NAME_TO_JSON_,JSONCONS_NARGS Seq) Seq) #define JSONCONS_ALL_GETTER_SETTER_NAME_TO_JSON_3(Getter, Setter, Name) \ ajson.try_emplace(Name,class_instance.Getter()); \ else \ {json_traits_helper::set_optional_json_member(Name,class_instance.Getter(), ajson);} #define JSONCONS_ALL_GETTER_SETTER_NAME_TO_JSON_5(Getter, Setter, Name, Mode, Match) JSONCONS_ALL_GETTER_SETTER_NAME_TO_JSON_7(Getter, Setter, Name, Mode, Match, , ) #define JSONCONS_ALL_GETTER_SETTER_NAME_TO_JSON_6(Getter, Setter, Name, Mode, Match, Into) JSONCONS_ALL_GETTER_SETTER_NAME_TO_JSON_7(Getter, Setter, Name, Mode, Match, Into, ) #define JSONCONS_ALL_GETTER_SETTER_NAME_TO_JSON_7(Getter, Setter, Name, Mode, Match, Into, From) \ ajson.try_emplace(Name, Into(class_instance.Getter())); \ else \ {json_traits_helper::set_optional_json_member(Name, Into(class_instance.Getter()), ajson);} #define JSONCONS_GETTER_SETTER_NAME_TRAITS_BASE(AsT,ToJ, NumTemplateParams, ClassType,NumMandatoryParams1,NumMandatoryParams2, ...) \ namespace jsoncons \ { \ template \ struct json_type_traits \ { \ using class_type = ClassType JSONCONS_GENERATE_TPL_ARGS(JSONCONS_GENERATE_TPL_ARG, NumTemplateParams); \ using allocator_type = typename Json::allocator_type; \ using char_type = typename Json::char_type; \ using string_view_type = typename Json::string_view_type; \ constexpr static size_t num_params = JSONCONS_NARGS(__VA_ARGS__); \ constexpr static size_t num_mandatory_params1 = NumMandatoryParams1; \ constexpr static size_t num_mandatory_params2 = NumMandatoryParams2; \ static bool is(const Json& ajson) noexcept \ { \ if (!ajson.is_object()) return false; \ JSONKONS_VARIADIC_FOR_EACH(JSONCONS_GETTER_SETTER_NAME_IS,,,, __VA_ARGS__)\ return true; \ } \ static class_type as(const Json& ajson) \ { \ if (!is(ajson)) JSONCONS_THROW(conv_error(conv_errc::conversion_failed, "Not a " # ClassType)); \ class_type class_instance{}; \ JSONKONS_VARIADIC_FOR_EACH(AsT,,,, __VA_ARGS__) \ return class_instance; \ } \ static Json to_json(const class_type& class_instance, allocator_type alloc=allocator_type()) \ { \ Json ajson(json_object_arg, semantic_tag::none, alloc); \ JSONKONS_VARIADIC_FOR_EACH(ToJ,,,, __VA_ARGS__) \ return ajson; \ } \ }; \ } \ /**/ #define JSONCONS_N_GETTER_SETTER_NAME_TRAITS(ClassType,NumMandatoryParams, ...) \ JSONCONS_GETTER_SETTER_NAME_TRAITS_BASE(JSONCONS_N_GETTER_SETTER_NAME_AS,JSONCONS_N_GETTER_SETTER_NAME_TO_JSON, 0, ClassType,NumMandatoryParams,NumMandatoryParams, __VA_ARGS__) \ namespace jsoncons { template <> struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_TPL_N_GETTER_SETTER_NAME_TRAITS(NumTemplateParams, ClassType,NumMandatoryParams, ...) \ JSONCONS_GETTER_SETTER_NAME_TRAITS_BASE(JSONCONS_N_GETTER_SETTER_NAME_AS,JSONCONS_N_GETTER_SETTER_NAME_TO_JSON, NumTemplateParams, ClassType,NumMandatoryParams,NumMandatoryParams, __VA_ARGS__) \ namespace jsoncons { template struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_ALL_GETTER_SETTER_NAME_TRAITS(ClassType, ...) \ JSONCONS_GETTER_SETTER_NAME_TRAITS_BASE(JSONCONS_ALL_GETTER_SETTER_NAME_AS,JSONCONS_ALL_GETTER_SETTER_NAME_TO_JSON, 0, ClassType, JSONCONS_NARGS(__VA_ARGS__), JSONCONS_NARGS(__VA_ARGS__), __VA_ARGS__) \ namespace jsoncons { template <> struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_TPL_ALL_GETTER_SETTER_NAME_TRAITS(NumTemplateParams, ClassType, ...) \ JSONCONS_GETTER_SETTER_NAME_TRAITS_BASE(JSONCONS_ALL_GETTER_SETTER_NAME_AS,JSONCONS_ALL_GETTER_SETTER_NAME_TO_JSON, NumTemplateParams, ClassType, JSONCONS_NARGS(__VA_ARGS__), JSONCONS_NARGS(__VA_ARGS__), __VA_ARGS__) \ namespace jsoncons { template struct is_json_type_traits_declared : public std::true_type {}; } \ /**/ #define JSONCONS_POLYMORPHIC_IS(BaseClass, P2, P3, DerivedClass, Count) if (ajson.template is()) return true; #define JSONCONS_POLYMORPHIC_IS_LAST(BaseClass, P2, P3, DerivedClass, Count) if (ajson.template is()) return true; #define JSONCONS_POLYMORPHIC_AS(BaseClass, P2, P3, DerivedClass, Count) if (ajson.template is()) return std::make_shared(ajson.template as()); #define JSONCONS_POLYMORPHIC_AS_LAST(BaseClass, P2, P3, DerivedClass, Count) if (ajson.template is()) return std::make_shared(ajson.template as()); #define JSONCONS_POLYMORPHIC_AS_UNIQUE_PTR(BaseClass, P2, P3, DerivedClass, Count) if (ajson.template is()) return jsoncons::make_unique(ajson.template as()); #define JSONCONS_POLYMORPHIC_AS_UNIQUE_PTR_LAST(BaseClass, P2, P3, DerivedClass, Count) if (ajson.template is()) return jsoncons::make_unique(ajson.template as()); #define JSONCONS_POLYMORPHIC_AS_SHARED_PTR(BaseClass, P2, P3, DerivedClass, Count) if (ajson.template is()) return std::make_shared(ajson.template as()); #define JSONCONS_POLYMORPHIC_AS_SHARED_PTR_LAST(BaseClass, P2, P3, DerivedClass, Count) if (ajson.template is()) return std::make_shared(ajson.template as()); #define JSONCONS_POLYMORPHIC_TO_JSON(BaseClass, P2, P3, DerivedClass, Count) if (DerivedClass* p = dynamic_cast(ptr.get())) {return Json(*p);} #define JSONCONS_POLYMORPHIC_TO_JSON_LAST(BaseClass, P2, P3, DerivedClass, Count) if (DerivedClass* p = dynamic_cast(ptr.get())) {return Json(*p);} #define JSONCONS_POLYMORPHIC_TRAITS(BaseClass, ...) \ namespace jsoncons { \ template \ struct json_type_traits> { \ static bool is(const Json& ajson) noexcept { \ if (!ajson.is_object()) return false; \ JSONKONS_VARIADIC_FOR_EACH(JSONCONS_POLYMORPHIC_IS, BaseClass,,, __VA_ARGS__)\ return false; \ } \ \ static std::shared_ptr as(const Json& ajson) { \ if (!ajson.is_object()) return std::shared_ptr(); \ JSONKONS_VARIADIC_FOR_EACH(JSONCONS_POLYMORPHIC_AS_SHARED_PTR, BaseClass,,, __VA_ARGS__)\ return std::shared_ptr(); \ } \ \ static Json to_json(const std::shared_ptr& ptr) { \ if (ptr.get() == nullptr) {return Json::null();} \ JSONKONS_VARIADIC_FOR_EACH(JSONCONS_POLYMORPHIC_TO_JSON, BaseClass,,, __VA_ARGS__)\ return Json::null(); \ } \ }; \ template \ struct json_type_traits> { \ static bool is(const Json& ajson) noexcept { \ if (!ajson.is_object()) return false; \ JSONKONS_VARIADIC_FOR_EACH(JSONCONS_POLYMORPHIC_IS, BaseClass,,, __VA_ARGS__)\ return false; \ } \ static std::unique_ptr as(const Json& ajson) { \ if (!ajson.is_object()) return std::unique_ptr(); \ JSONKONS_VARIADIC_FOR_EACH(JSONCONS_POLYMORPHIC_AS_UNIQUE_PTR, BaseClass,,, __VA_ARGS__)\ return std::unique_ptr(); \ } \ static Json to_json(const std::unique_ptr& ptr) { \ if (ptr.get() == nullptr) {return Json::null();} \ JSONKONS_VARIADIC_FOR_EACH(JSONCONS_POLYMORPHIC_TO_JSON, BaseClass,,, __VA_ARGS__)\ return Json::null(); \ } \ }; \ } \ /**/ #endif // JSONCONS_JSON_TRAITS_MACROS_HPP jsoncons-1.3.2/include/jsoncons/json_type.hpp000066400000000000000000000174331477700171100213700ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_JSON_TYPE_HPP #define JSONCONS_JSON_TYPE_HPP #include #include #include namespace jsoncons { enum class json_type : uint8_t { null_value, bool_value, int64_value, uint64_value, half_value, double_value, string_value, byte_string_value, array_value, object_value }; template std::basic_ostream& operator<<(std::basic_ostream& os, json_type type) { static constexpr const CharT* null_value = JSONCONS_CSTRING_CONSTANT(CharT, "null"); static constexpr const CharT* bool_value = JSONCONS_CSTRING_CONSTANT(CharT, "bool"); static constexpr const CharT* int64_value = JSONCONS_CSTRING_CONSTANT(CharT, "int64"); static constexpr const CharT* uint64_value = JSONCONS_CSTRING_CONSTANT(CharT, "uint64"); static constexpr const CharT* half_value = JSONCONS_CSTRING_CONSTANT(CharT, "half"); static constexpr const CharT* double_value = JSONCONS_CSTRING_CONSTANT(CharT, "double"); static constexpr const CharT* string_value = JSONCONS_CSTRING_CONSTANT(CharT, "string"); static constexpr const CharT* byte_string_value = JSONCONS_CSTRING_CONSTANT(CharT, "byte_string"); static constexpr const CharT* array_value = JSONCONS_CSTRING_CONSTANT(CharT, "array"); static constexpr const CharT* object_value = JSONCONS_CSTRING_CONSTANT(CharT, "object"); switch (type) { case json_type::null_value: { os << null_value; break; } case json_type::bool_value: { os << bool_value; break; } case json_type::int64_value: { os << int64_value; break; } case json_type::uint64_value: { os << uint64_value; break; } case json_type::half_value: { os << half_value; break; } case json_type::double_value: { os << double_value; break; } case json_type::string_value: { os << string_value; break; } case json_type::byte_string_value: { os << byte_string_value; break; } case json_type::array_value: { os << array_value; break; } case json_type::object_value: { os << object_value; break; } } return os; } enum class json_storage_kind : uint8_t { null = 0, // 0000 boolean = 1, // 0001 int64 = 2, // 0010 uint64 = 3, // 0011 empty_object = 4, // 0100 float64 = 5, // 0101 half_float = 6, // 0110 short_str = 7, // 0111 json_const_reference = 8, // 1000 json_reference = 9, // 1001 byte_str = 12, // 1100 object = 13, // 1101 array = 14, // 1110 long_str = 15 // 1111 }; inline bool is_string_storage(json_storage_kind storage_kind) noexcept { static const uint8_t mask{ uint8_t(json_storage_kind::short_str) & uint8_t(json_storage_kind::long_str) }; return (uint8_t(storage_kind) & mask) == mask; } inline bool is_trivial_storage(json_storage_kind storage_kind) noexcept { static const uint8_t mask{ uint8_t(json_storage_kind::long_str) & uint8_t(json_storage_kind::byte_str) & uint8_t(json_storage_kind::array) & uint8_t(json_storage_kind::object) }; return (uint8_t(storage_kind) & mask) != mask; } template std::basic_ostream& operator<<(std::basic_ostream& os, json_storage_kind storage) { static constexpr const CharT* null_value = JSONCONS_CSTRING_CONSTANT(CharT, "null"); static constexpr const CharT* bool_value = JSONCONS_CSTRING_CONSTANT(CharT, "bool"); static constexpr const CharT* int64_value = JSONCONS_CSTRING_CONSTANT(CharT, "int64"); static constexpr const CharT* uint64_value = JSONCONS_CSTRING_CONSTANT(CharT, "uint64"); static constexpr const CharT* half_value = JSONCONS_CSTRING_CONSTANT(CharT, "half"); static constexpr const CharT* double_value = JSONCONS_CSTRING_CONSTANT(CharT, "double"); static constexpr const CharT* short_string_value = JSONCONS_CSTRING_CONSTANT(CharT, "short_string"); static constexpr const CharT* long_string_value = JSONCONS_CSTRING_CONSTANT(CharT, "string"); static constexpr const CharT* byte_string_value = JSONCONS_CSTRING_CONSTANT(CharT, "byte_string"); static constexpr const CharT* array_value = JSONCONS_CSTRING_CONSTANT(CharT, "array"); static constexpr const CharT* empty_object_value = JSONCONS_CSTRING_CONSTANT(CharT, "empty_object"); static constexpr const CharT* object_value = JSONCONS_CSTRING_CONSTANT(CharT, "object"); static constexpr const CharT* json_const_reference = JSONCONS_CSTRING_CONSTANT(CharT, "json_const_reference"); static constexpr const CharT* json_reference = JSONCONS_CSTRING_CONSTANT(CharT, "json_reference"); switch (storage) { case json_storage_kind::null: { os << null_value; break; } case json_storage_kind::boolean: { os << bool_value; break; } case json_storage_kind::int64: { os << int64_value; break; } case json_storage_kind::uint64: { os << uint64_value; break; } case json_storage_kind::half_float: { os << half_value; break; } case json_storage_kind::float64: { os << double_value; break; } case json_storage_kind::short_str: { os << short_string_value; break; } case json_storage_kind::long_str: { os << long_string_value; break; } case json_storage_kind::byte_str: { os << byte_string_value; break; } case json_storage_kind::array: { os << array_value; break; } case json_storage_kind::empty_object: { os << empty_object_value; break; } case json_storage_kind::object: { os << object_value; break; } case json_storage_kind::json_const_reference: { os << json_const_reference; break; } case json_storage_kind::json_reference: { os << json_reference; break; } } return os; } } // namespace jsoncons #endif // JSONCONS_JSON_TYPE_HPP jsoncons-1.3.2/include/jsoncons/json_type_traits.hpp000066400000000000000000001703361477700171100227600ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_JSON_TYPE_TRAITS_HPP #define JSONCONS_JSON_TYPE_TRAITS_HPP #include // std::swap #include #include // std::bitset #include #include #include #include #include // std::iterator_traits, std::input_iterator_tag #include #include #include #include #include // std::enable_if #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(JSONCONS_HAS_STD_VARIANT) #include #endif namespace jsoncons { template struct is_json_type_traits_declared : public std::false_type {}; // json_type_traits template struct unimplemented : std::false_type {}; template struct json_type_traits { using allocator_type = typename Json::allocator_type; static constexpr bool is_compatible = false; static constexpr bool is(const Json&) noexcept { return false; } static T as(const Json&) { static_assert(unimplemented::value, "as not implemented"); } static Json to_json(const T&) { static_assert(unimplemented::value, "to_json not implemented"); } static Json to_json(const T&, const allocator_type&) { static_assert(unimplemented::value, "to_json not implemented"); } }; namespace detail { template using traits_can_convert_t = decltype(json_type_traits::can_convert(Json())); template using has_can_convert = extension_traits::is_detected; template struct invoke_can_convert { template static typename std::enable_if::value,bool>::type can_convert(const Json& j) noexcept { return json_type_traits::can_convert(j); } template static typename std::enable_if::value,bool>::type can_convert(const Json& j) noexcept { return json_type_traits::is(j); } }; // is_json_type_traits_unspecialized template struct is_json_type_traits_unspecialized : std::false_type {}; // is_json_type_traits_unspecialized template struct is_json_type_traits_unspecialized::is_compatible>::value>::type > : std::true_type {}; // is_compatible_array_type template struct is_compatible_array_type : std::false_type {}; template struct is_compatible_array_type::value && extension_traits::is_array_like::value && !is_json_type_traits_unspecialized::value_type>::value >::type> : std::true_type {}; } // namespace detail // is_json_type_traits_specialized template struct is_json_type_traits_specialized : std::false_type {}; template struct is_json_type_traits_specialized::value >::type> : std::true_type {}; template struct json_type_traits::type*> { using char_type = typename Json::char_type; using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return j.is_string(); } static const char_type* as(const Json& j) { return j.as_cstring(); } template static Json to_json(const char_type* s, Args&&... args) { return Json(s, semantic_tag::none, std::forward(args)...); } }; template struct json_type_traits::type*> { using char_type = typename Json::char_type; using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return j.is_string(); } template static Json to_json(const char_type* s, Args&&... args) { return Json(s, semantic_tag::none, std::forward(args)...); } }; // integer template struct json_type_traits::value && sizeof(T) <= sizeof(int64_t)) || (extension_traits::is_unsigned_integer::value && sizeof(T) <= sizeof(uint64_t)) >::type> { using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return j.template is_integer(); } static T as(const Json& j) { return j.template as_integer(); } static Json to_json(T val) { return Json(val, semantic_tag::none); } static Json to_json(T val, const allocator_type&) { return Json(val, semantic_tag::none); } }; template struct json_type_traits::value && sizeof(T) > sizeof(int64_t)) || (extension_traits::is_unsigned_integer::value && sizeof(T) > sizeof(uint64_t)) >::type> { using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return j.template is_integer(); } static T as(const Json& j) { return j.template as_integer(); } static Json to_json(T val, const allocator_type& alloc = allocator_type()) { return Json(val, semantic_tag::none, alloc); } }; template struct json_type_traits::value >::type> { using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return j.is_double(); } static T as(const Json& j) { return static_cast(j.as_double()); } static Json to_json(T val) { return Json(val, semantic_tag::none); } static Json to_json(T val, const allocator_type&) { return Json(val, semantic_tag::none); } }; template struct json_type_traits { using json_object = typename Json::object; using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return j.is_object(); } static Json to_json(const json_object& o) { return Json(o,semantic_tag::none); } static Json to_json(const json_object& o, const allocator_type&) { return Json(o,semantic_tag::none); } }; template struct json_type_traits { using json_array = typename Json::array; using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return j.is_array(); } static Json to_json(const json_array& a) { return Json(a, semantic_tag::none); } static Json to_json(const json_array& a, const allocator_type&) { return Json(a, semantic_tag::none); } }; template struct json_type_traits { using allocator_type = typename Json::allocator_type; static bool is(const Json&) noexcept { return true; } static Json as(Json j) { return j; } static Json to_json(const Json& val) { return val; } static Json to_json(const Json& val, const allocator_type&) { return val; } }; template struct json_type_traits { using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return j.is_null(); } static typename jsoncons::null_type as(const Json& j) { if (!j.is_null()) { JSONCONS_THROW(conv_error(conv_errc::not_jsoncons_null_type)); } return jsoncons::null_type(); } static Json to_json(jsoncons::null_type) { return Json(jsoncons::null_type{}, semantic_tag::none); } static Json to_json(jsoncons::null_type, const allocator_type&) { return Json(jsoncons::null_type{}, semantic_tag::none); } }; template struct json_type_traits { using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return j.is_bool(); } static bool as(const Json& j) { return j.as_bool(); } static Json to_json(bool val) { return Json(val, semantic_tag::none); } static Json to_json(bool val, const allocator_type&) { return Json(val, semantic_tag::none); } }; template struct json_type_traits::const_reference>::value, std::vector::const_reference, void>::type>::value>::type> { using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return j.is_bool(); } static bool as(const Json& j) { return j.as_bool(); } static Json to_json(bool val) { return Json(val, semantic_tag::none); } static Json to_json(bool val, const allocator_type&) { return Json(val, semantic_tag::none); } }; template struct json_type_traits::reference> { using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return j.is_bool(); } static bool as(const Json& j) { return j.as_bool(); } static Json to_json(bool val) { return Json(val, semantic_tag::none); } static Json to_json(bool val, const allocator_type&) { return Json(val, semantic_tag::none); } }; template struct json_type_traits::value && extension_traits::is_string::value && std::is_same::value>::type> { using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return j.is_string(); } static T as(const Json& j) { return T(j.as_string()); } static Json to_json(const T& val) { return Json(val, semantic_tag::none); } static Json to_json(const T& val, const allocator_type& alloc) { return Json(val, semantic_tag::none, alloc); } }; template struct json_type_traits::value && extension_traits::is_string::value && !std::is_same::value>::type> { using char_type = typename Json::char_type; using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return j.is_string(); } static T as(const Json& j) { auto s = j.as_string(); T val; unicode_traits::convert(s.data(), s.size(), val); return val; } static Json to_json(const T& val) { std::basic_string s; unicode_traits::convert(val.data(), val.size(), s); return Json(s, semantic_tag::none); } static Json to_json(const T& val, const allocator_type& alloc) { std::basic_string s; unicode_traits::convert(val.data(), val.size(), s); return Json(s, semantic_tag::none, alloc); } }; template struct json_type_traits::value && extension_traits::is_string_view::value && std::is_same::value>::type> { using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return j.is_string_view(); } static T as(const Json& j) { return T(j.as_string_view().data(),j.as_string_view().size()); } static Json to_json(const T& val) { return Json(val, semantic_tag::none); } static Json to_json(const T& val, const allocator_type& alloc) { return Json(val, semantic_tag::none, alloc); } }; // array back insertable template struct json_type_traits::value && jsoncons::detail::is_compatible_array_type::value && extension_traits::is_back_insertable::value >::type> { typedef typename std::iterator_traits::value_type value_type; using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { bool result = j.is_array(); if (result) { for (auto e : j.array_range()) { if (!e.template is()) { result = false; break; } } } return result; } // array back insertable non-byte container template static typename std::enable_if::value,Container>::type as(const Json& j) { if (j.is_array()) { T result; visit_reserve_(typename std::integral_constant::value>::type(),result,j.size()); for (const auto& item : j.array_range()) { result.push_back(item.template as()); } return result; } else { JSONCONS_THROW(conv_error(conv_errc::not_vector)); } } // array back insertable byte container template static typename std::enable_if::value,Container>::type as(const Json& j) { std::error_code ec; if (j.is_array()) { T result; visit_reserve_(typename std::integral_constant::value>::type(),result,j.size()); for (const auto& item : j.array_range()) { result.push_back(item.template as()); } return result; } else if (j.is_byte_string_view()) { value_converter converter; auto v = converter.convert(j.as_byte_string_view(),j.tag(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(conv_error(ec)); } return v; } else if (j.is_string()) { value_converter,T> converter; auto v = converter.convert(j.as_string_view(),j.tag(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(conv_error(ec)); } return v; } else { JSONCONS_THROW(conv_error(conv_errc::not_vector)); } } template static typename std::enable_if::value,Json>::type to_json(const T& val) { Json j(json_array_arg); auto first = std::begin(val); auto last = std::end(val); std::size_t size = std::distance(first,last); j.reserve(size); for (auto it = first; it != last; ++it) { j.push_back(*it); } return j; } template static typename std::enable_if::value,Json>::type to_json(const T& val, const allocator_type& alloc) { Json j(json_array_arg, alloc); auto first = std::begin(val); auto last = std::end(val); std::size_t size = std::distance(first, last); j.reserve(size); for (auto it = first; it != last; ++it) { j.push_back(*it); } return j; } template static typename std::enable_if::value,Json>::type to_json(const T& val) { Json j(byte_string_arg, val); return j; } template static typename std::enable_if::value,Json>::type to_json(const T& val, const allocator_type& alloc) { Json j(byte_string_arg, val, semantic_tag::none, alloc); return j; } static void visit_reserve_(std::true_type, T& v, std::size_t size) { v.reserve(size); } static void visit_reserve_(std::false_type, T&, std::size_t) { } }; // array, not back insertable but insertable template struct json_type_traits::value && jsoncons::detail::is_compatible_array_type::value && !extension_traits::is_back_insertable::value && extension_traits::is_insertable::value>::type> { typedef typename std::iterator_traits::value_type value_type; using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { bool result = j.is_array(); if (result) { for (auto e : j.array_range()) { if (!e.template is()) { result = false; break; } } } return result; } static T as(const Json& j) { if (j.is_array()) { T result; for (const auto& item : j.array_range()) { result.insert(item.template as()); } return result; } else { JSONCONS_THROW(conv_error(conv_errc::not_vector)); } } static Json to_json(const T& val) { Json j(json_array_arg); auto first = std::begin(val); auto last = std::end(val); std::size_t size = std::distance(first,last); j.reserve(size); for (auto it = first; it != last; ++it) { j.push_back(*it); } return j; } static Json to_json(const T& val, const allocator_type& alloc) { Json j(json_array_arg, alloc); auto first = std::begin(val); auto last = std::end(val); std::size_t size = std::distance(first, last); j.reserve(size); for (auto it = first; it != last; ++it) { j.push_back(*it); } return j; } }; // array not back insertable or insertable, but front insertable template struct json_type_traits::value && jsoncons::detail::is_compatible_array_type::value && !extension_traits::is_back_insertable::value && !extension_traits::is_insertable::value && extension_traits::is_front_insertable::value>::type> { typedef typename std::iterator_traits::value_type value_type; using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { bool result = j.is_array(); if (result) { for (auto e : j.array_range()) { if (!e.template is()) { result = false; break; } } } return result; } static T as(const Json& j) { if (j.is_array()) { T result; auto it = j.array_range().rbegin(); auto end = j.array_range().rend(); for (; it != end; ++it) { result.push_front((*it).template as()); } return result; } else { JSONCONS_THROW(conv_error(conv_errc::not_vector)); } } static Json to_json(const T& val) { Json j(json_array_arg); auto first = std::begin(val); auto last = std::end(val); std::size_t size = std::distance(first,last); j.reserve(size); for (auto it = first; it != last; ++it) { j.push_back(*it); } return j; } static Json to_json(const T& val, const allocator_type& alloc) { Json j(json_array_arg, alloc); auto first = std::begin(val); auto last = std::end(val); std::size_t size = std::distance(first, last); j.reserve(size); for (auto it = first; it != last; ++it) { j.push_back(*it); } return j; } }; // std::array template struct json_type_traits> { using allocator_type = typename Json::allocator_type; using value_type = E; static bool is(const Json& j) noexcept { bool result = j.is_array() && j.size() == N; if (result) { for (auto e : j.array_range()) { if (!e.template is()) { result = false; break; } } } return result; } static std::array as(const Json& j) { std::array buff; if (j.size() != N) { JSONCONS_THROW(conv_error(conv_errc::not_array)); } for (std::size_t i = 0; i < N; i++) { buff[i] = j[i].template as(); } return buff; } static Json to_json(const std::array& val) { Json j(json_array_arg); j.reserve(N); for (auto it = val.begin(); it != val.end(); ++it) { j.push_back(*it); } return j; } static Json to_json(const std::array& val, const allocator_type& alloc) { Json j(json_array_arg, alloc); j.reserve(N); for (auto it = val.begin(); it != val.end(); ++it) { j.push_back(*it); } return j; } }; // map like template struct json_type_traits::value && extension_traits::is_map_like::value && extension_traits::is_constructible_from_const_pointer_and_size::value && is_json_type_traits_specialized::value>::type > { using mapped_type = typename T::mapped_type; using value_type = typename T::value_type; using key_type = typename T::key_type; using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { bool result = j.is_object(); for (auto member : j.object_range()) { if (!member.value().template is()) { result = false; } } return result; } static T as(const Json& j) { if (!j.is_object()) { JSONCONS_THROW(conv_error(conv_errc::not_map)); } T result; for (const auto& item : j.object_range()) { result.emplace(key_type(item.key().data(),item.key().size()), item.value().template as()); } return result; } static Json to_json(const T& val) { Json j(json_object_arg, val.begin(), val.end()); return j; } static Json to_json(const T& val, const allocator_type& alloc) { Json j(json_object_arg, val.begin(), val.end(), alloc); return j; } }; template struct json_type_traits::value && extension_traits::is_map_like::value && !extension_traits::is_constructible_from_const_pointer_and_size::value && is_json_type_traits_specialized::value && is_json_type_traits_specialized::value>::type > { using mapped_type = typename T::mapped_type; using value_type = typename T::value_type; using key_type = typename T::key_type; using allocator_type = typename Json::allocator_type; static bool is(const Json& val) noexcept { if (!val.is_object()) return false; for (const auto& item : val.object_range()) { Json j(item.key()); if (!j.template is()) { return false; } if (!item.value().template is()) { return false; } } return true; } static T as(const Json& val) { T result; for (const auto& item : val.object_range()) { Json j(item.key()); auto key = json_type_traits::as(j); result.emplace(std::move(key), item.value().template as()); } return result; } static Json to_json(const T& val) { Json j(json_object_arg); j.reserve(val.size()); for (const auto& item : val) { auto temp = json_type_traits::to_json(item.first); if (temp.is_string_view()) { j.try_emplace(typename Json::key_type(temp.as_string_view()), item.second); } else { typename Json::key_type key; temp.dump(key); j.try_emplace(std::move(key), item.second); } } return j; } static Json to_json(const T& val, const allocator_type& alloc) { Json j(json_object_arg, semantic_tag::none, alloc); j.reserve(val.size()); for (const auto& item : val) { auto temp = json_type_traits::to_json(item.first, alloc); if (temp.is_string_view()) { j.try_emplace(typename Json::key_type(temp.as_string_view(), alloc), item.second); } else { typename Json::key_type key(alloc); temp.dump(key); j.try_emplace(std::move(key), item.second, alloc); } } return j; } }; namespace tuple_detail { template struct json_tuple_helper { using element_type = typename std::tuple_element::type; using next = json_tuple_helper; static bool is(const Json& j) noexcept { if (j[Size-Pos].template is()) { return next::is(j); } else { return false; } } static void as(Tuple& tuple, const Json& j) { std::get(tuple) = j[Size-Pos].template as(); next::as(tuple, j); } static void to_json(const Tuple& tuple, Json& j) { j.push_back(json_type_traits::to_json(std::get(tuple))); next::to_json(tuple, j); } }; template struct json_tuple_helper<0, Size, Json, Tuple> { static bool is(const Json&) noexcept { return true; } static void as(Tuple&, const Json&) { } static void to_json(const Tuple&, Json&) { } }; } // namespace tuple_detail template struct json_type_traits> { private: using helper = tuple_detail::json_tuple_helper>; public: using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return helper::is(j); } static std::tuple as(const Json& j) { std::tuple buff; helper::as(buff, j); return buff; } static Json to_json(const std::tuple& val) { Json j(json_array_arg); j.reserve(sizeof...(E)); helper::to_json(val, j); return j; } static Json to_json(const std::tuple& val, const allocator_type& alloc) { Json j(json_array_arg, alloc); j.reserve(sizeof...(E)); helper::to_json(val, j); return j; } }; template struct json_type_traits> { public: using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return j.is_array() && j.size() == 2; } static std::pair as(const Json& j) { return std::make_pair(j[0].template as(),j[1].template as()); } static Json to_json(const std::pair& val) { Json j(json_array_arg); j.reserve(2); j.push_back(val.first); j.push_back(val.second); return j; } static Json to_json(const std::pair& val, const allocator_type& alloc) { Json j(json_array_arg, alloc); j.reserve(2); j.push_back(val.first); j.push_back(val.second); return j; } }; template struct json_type_traits::value>::type> { public: using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return j.is_byte_string(); } static T as(const Json& j) { return j.template as_byte_string(); } static Json to_json(const T& val, const allocator_type& alloc = allocator_type()) { return Json(byte_string_arg, val, semantic_tag::none, alloc); } }; template struct json_type_traits, typename std::enable_if>::value && !std::is_polymorphic::value >::type> { using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return j.is_null() || j.template is(); } static std::shared_ptr as(const Json& j) { return j.is_null() ? std::shared_ptr(nullptr) : std::make_shared(j.template as()); } static Json to_json(const std::shared_ptr& ptr, const allocator_type& alloc = allocator_type()) { if (ptr.get() != nullptr) { Json j(*ptr, alloc); return j; } else { return Json::null(); } } }; template struct json_type_traits, typename std::enable_if>::value && !std::is_polymorphic::value >::type> { using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return j.is_null() || j.template is(); } static std::unique_ptr as(const Json& j) { return j.is_null() ? std::unique_ptr(nullptr) : jsoncons::make_unique(j.template as()); } static Json to_json(const std::unique_ptr& ptr, const allocator_type& alloc = allocator_type()) { if (ptr.get() != nullptr) { Json j(*ptr, alloc); return j; } else { return Json::null(); } } }; template struct json_type_traits, typename std::enable_if>::value>::type> { using allocator_type = typename Json::allocator_type; public: static bool is(const Json& j) noexcept { return j.is_null() || j.template is(); } static jsoncons::optional as(const Json& j) { return j.is_null() ? jsoncons::optional() : jsoncons::optional(j.template as()); } static Json to_json(const jsoncons::optional& val, const allocator_type& alloc = allocator_type()) { return val.has_value() ? Json(*val, alloc) : Json::null(); } }; template struct json_type_traits { using allocator_type = typename Json::allocator_type; public: static bool is(const Json& j) noexcept { return j.is_byte_string_view(); } static byte_string_view as(const Json& j) { return j.as_byte_string_view(); } static Json to_json(const byte_string_view& val, const allocator_type& alloc = allocator_type()) { return Json(byte_string_arg, val, semantic_tag::none, alloc); } }; // basic_bigint template struct json_type_traits> { public: using allocator_type = typename Json::allocator_type; using char_type = typename Json::char_type; static bool is(const Json& j) noexcept { switch (j.type()) { case json_type::string_value: return jsoncons::detail::is_base10(j.as_string_view().data(), j.as_string_view().length()); case json_type::int64_value: case json_type::uint64_value: return true; default: return false; } } static basic_bigint as(const Json& j) { switch (j.type()) { case json_type::string_value: if (!jsoncons::detail::is_base10(j.as_string_view().data(), j.as_string_view().length())) { JSONCONS_THROW(conv_error(conv_errc::not_bigint)); } return basic_bigint::from_string(j.as_string_view().data(), j.as_string_view().length()); case json_type::half_value: case json_type::double_value: return basic_bigint(j.template as()); case json_type::int64_value: return basic_bigint(j.template as()); case json_type::uint64_value: return basic_bigint(j.template as()); default: JSONCONS_THROW(conv_error(conv_errc::not_bigint)); } } static Json to_json(const basic_bigint& val) { std::basic_string s; val.write_string(s); return Json(s,semantic_tag::bigint); } static Json to_json(const basic_bigint& val, const allocator_type&) { std::basic_string s; val.write_string(s); return Json(s,semantic_tag::bigint); } }; // std::valarray template struct json_type_traits> { using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { bool result = j.is_array(); if (result) { for (auto e : j.array_range()) { if (!e.template is()) { result = false; break; } } } return result; } static std::valarray as(const Json& j) { if (j.is_array()) { std::valarray v(j.size()); for (std::size_t i = 0; i < j.size(); ++i) { v[i] = j[i].template as(); } return v; } else { JSONCONS_THROW(conv_error(conv_errc::not_array)); } } static Json to_json(const std::valarray& val) { Json j(json_array_arg); auto first = std::begin(val); auto last = std::end(val); std::size_t size = std::distance(first,last); j.reserve(size); for (auto it = first; it != last; ++it) { j.push_back(*it); } return j; } static Json to_json(const std::valarray& val, const allocator_type& alloc) { Json j(json_array_arg, alloc); auto first = std::begin(val); auto last = std::end(val); std::size_t size = std::distance(first,last); j.reserve(size); for (auto it = first; it != last; ++it) { j.push_back(*it); } return j; } }; #if defined(JSONCONS_HAS_STD_VARIANT) namespace variant_detail { template typename std::enable_if, bool>::type is_variant(const Json& /*j*/) { return false; } template typename std::enable_if, bool>::type is_variant(const Json& j) { if (j.template is()) { return true; } else { return is_variant(j); } } template typename std::enable_if, Variant>::type as_variant(const Json& /*j*/) { JSONCONS_THROW(conv_error(conv_errc::not_variant)); } template typename std::enable_if, Variant>::type as_variant(const Json& j) { if (j.template is()) { Variant var(j.template as()); return var; } else { return as_variant(j); } } template struct variant_to_json_visitor { Json& j_; variant_to_json_visitor(Json& j) : j_(j) {} template void operator()(const T& value) const { j_ = value; } }; } // namespace variant_detail template struct json_type_traits> { public: using variant_type = typename std::variant; using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return variant_detail::is_variant<0,Json,variant_type, VariantTypes...>(j); } static std::variant as(const Json& j) { return variant_detail::as_variant<0,Json,variant_type, VariantTypes...>(j); } static Json to_json(const std::variant& var) { Json j(json_array_arg); variant_detail::variant_to_json_visitor visitor(j); std::visit(visitor, var); return j; } static Json to_json(const std::variant& var, const allocator_type& alloc) { Json j(json_array_arg, alloc); variant_detail::variant_to_json_visitor visitor(j); std::visit(visitor, var); return j; } }; #endif // std::chrono::duration template struct json_type_traits> { using duration_type = std::chrono::duration; using allocator_type = typename Json::allocator_type; static constexpr int64_t nanos_in_milli = 1000000; static constexpr int64_t nanos_in_second = 1000000000; static constexpr int64_t millis_in_second = 1000; static bool is(const Json& j) noexcept { return (j.tag() == semantic_tag::epoch_second || j.tag() == semantic_tag::epoch_milli || j.tag() == semantic_tag::epoch_nano); } static duration_type as(const Json& j) { return from_json_(j); } static Json to_json(const duration_type& val, const allocator_type& = allocator_type()) { return to_json_(val); } template static typename std::enable_if>::value, duration_type>::type from_json_(const Json& j) { if (j.is_int64() || j.is_uint64() || j.is_double()) { auto count = j.template as(); switch (j.tag()) { case semantic_tag::epoch_second: return duration_type(count); case semantic_tag::epoch_milli: return duration_type(count == 0 ? 0 : count/millis_in_second); case semantic_tag::epoch_nano: return duration_type(count == 0 ? 0 : count/nanos_in_second); default: return duration_type(count); } } else if (j.is_string()) { switch (j.tag()) { case semantic_tag::epoch_second: { auto count = j.template as(); return duration_type(count); } case semantic_tag::epoch_milli: { auto sv = j.as_string_view(); bigint n = bigint::from_string(sv.data(), sv.length()); if (n != 0) { n = n / millis_in_second; } return duration_type(static_cast(n)); } case semantic_tag::epoch_nano: { auto sv = j.as_string_view(); bigint n = bigint::from_string(sv.data(), sv.length()); if (n != 0) { n = n / nanos_in_second; } return duration_type(static_cast(n)); } default: { auto count = j.template as(); return duration_type(count); } } } else { return duration_type(); } } template static typename std::enable_if::value, duration_type>::type from_json_(const Json& j) { if (j.is_int64() || j.is_uint64()) { auto count = j.template as(); switch (j.tag()) { case semantic_tag::epoch_second: return duration_type(count*millis_in_second); case semantic_tag::epoch_milli: return duration_type(count); case semantic_tag::epoch_nano: return duration_type(count == 0 ? 0 : count/nanos_in_milli); default: return duration_type(count); } } else if (j.is_double()) { auto count = j.template as(); switch (j.tag()) { case semantic_tag::epoch_second: return duration_type(static_cast(count * millis_in_second)); case semantic_tag::epoch_milli: return duration_type(static_cast(count)); case semantic_tag::epoch_nano: return duration_type(count == 0 ? 0 : static_cast(count / nanos_in_milli)); default: return duration_type(static_cast(count)); } } else if (j.is_string()) { switch (j.tag()) { case semantic_tag::epoch_second: { auto count = j.template as(); return duration_type(count*millis_in_second); } case semantic_tag::epoch_milli: { auto sv = j.as_string_view(); Rep n{0}; auto result = jsoncons::detail::decimal_to_integer(sv.data(), sv.size(), n); if (!result) { return duration_type(); } return duration_type(n); } case semantic_tag::epoch_nano: { auto sv = j.as_string_view(); bigint n = bigint::from_string(sv.data(), sv.length()); if (n != 0) { n = n / nanos_in_milli; } return duration_type(static_cast(n)); } default: { auto count = j.template as(); return duration_type(count); } } } else { return duration_type(); } } template static typename std::enable_if::value, duration_type>::type from_json_(const Json& j) { if (j.is_int64() || j.is_uint64() || j.is_double()) { auto count = j.template as(); switch (j.tag()) { case semantic_tag::epoch_second: return duration_type(count*nanos_in_second); case semantic_tag::epoch_milli: return duration_type(count*nanos_in_milli); case semantic_tag::epoch_nano: return duration_type(count); default: return duration_type(count); } } else if (j.is_double()) { auto count = j.template as(); switch (j.tag()) { case semantic_tag::epoch_second: return duration_type(static_cast(count * nanos_in_second)); case semantic_tag::epoch_milli: return duration_type(static_cast(count * nanos_in_milli)); case semantic_tag::epoch_nano: return duration_type(static_cast(count)); default: return duration_type(static_cast(count)); } } else if (j.is_string()) { auto count = j.template as(); switch (j.tag()) { case semantic_tag::epoch_second: return duration_type(count*nanos_in_second); case semantic_tag::epoch_milli: return duration_type(count*nanos_in_milli); case semantic_tag::epoch_nano: return duration_type(count); default: return duration_type(count); } } else { return duration_type(); } } template static typename std::enable_if>::value,Json>::type to_json_(const duration_type& val) { return Json(val.count(), semantic_tag::epoch_second); } template static typename std::enable_if::value,Json>::type to_json_(const duration_type& val) { return Json(val.count(), semantic_tag::epoch_milli); } template static typename std::enable_if::value,Json>::type to_json_(const duration_type& val) { return Json(val.count(), semantic_tag::epoch_nano); } }; // std::nullptr_t template struct json_type_traits { using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { return j.is_null(); } static std::nullptr_t as(const Json& j) { if (!j.is_null()) { JSONCONS_THROW(conv_error(conv_errc::not_nullptr)); } return nullptr; } static Json to_json(const std::nullptr_t&, const allocator_type& = allocator_type()) { return Json::null(); } }; // std::bitset struct null_back_insertable_byte_container { using value_type = uint8_t; void push_back(value_type) { } }; template struct json_type_traits> { using allocator_type = typename Json::allocator_type; static bool is(const Json& j) noexcept { if (j.is_byte_string()) { return true; } else if (j.is_string()) { jsoncons::string_view sv = j.as_string_view(); null_back_insertable_byte_container cont; auto result = decode_base16(sv.begin(), sv.end(), cont); return result.ec == conv_errc::success ? true : false; } return false; } static std::bitset as(const Json& j) { if (j.template is()) { auto bits = j.template as(); std::bitset bs = static_cast(bits); return bs; } else if (j.is_byte_string() || j.is_string()) { std::bitset bs; std::vector bits; if (j.is_byte_string()) { bits = j.template as>(); } else { jsoncons::string_view sv = j.as_string_view(); auto result = decode_base16(sv.begin(), sv.end(), bits); if (result.ec != conv_errc::success) { JSONCONS_THROW(conv_error(conv_errc::not_bitset)); } } std::uint8_t byte = 0; std::uint8_t mask = 0; std::size_t pos = 0; for (std::size_t i = 0; i < N; ++i) { if (mask == 0) { if (pos >= bits.size()) { JSONCONS_THROW(conv_error(conv_errc::not_bitset)); } byte = bits.at(pos++); mask = 0x80; } if (byte & mask) { bs[i] = 1; } mask = static_cast(mask >> 1); } return bs; } else { JSONCONS_THROW(conv_error(conv_errc::not_bitset)); } } static Json to_json(const std::bitset& val, const allocator_type& alloc = allocator_type()) { std::vector bits; uint8_t byte = 0; uint8_t mask = 0x80; for (std::size_t i = 0; i < N; ++i) { if (val[i]) { byte |= mask; } mask = static_cast(mask >> 1); if (mask == 0) { bits.push_back(byte); byte = 0; mask = 0x80; } } // Encode remainder if (mask != 0x80) { bits.push_back(byte); } Json j(byte_string_arg, bits, semantic_tag::base16, alloc); return j; } }; } // namespace jsoncons #endif // JSONCONS_JSON_TYPE_TRAITS_HPP jsoncons-1.3.2/include/jsoncons/json_visitor.hpp000066400000000000000000001102231477700171100220750ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_JSON_VISITOR_HPP #define JSONCONS_JSON_VISITOR_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { template class basic_json_visitor { public: using char_type = CharT; using char_traits_type = std::char_traits; using string_view_type = jsoncons::basic_string_view; basic_json_visitor() = default; virtual ~basic_json_visitor() = default; void flush() { visit_flush(); } JSONCONS_VISITOR_RETURN_TYPE begin_object(semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_begin_object(tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE begin_object(std::size_t length, semantic_tag tag=semantic_tag::none, const ser_context& context = ser_context()) { std::error_code ec; visit_begin_object(length, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE end_object(const ser_context& context = ser_context()) { std::error_code ec; visit_end_object(context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE begin_array(semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_begin_array(tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE begin_array(std::size_t length, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_begin_array(length, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE end_array(const ser_context& context=ser_context()) { std::error_code ec; visit_end_array(context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE key(const string_view_type& name, const ser_context& context=ser_context()) { std::error_code ec; visit_key(name, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE null_value(semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_null(tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE bool_value(bool value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_bool(value, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE string_value(const string_view_type& value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_string(value, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } template JSONCONS_VISITOR_RETURN_TYPE byte_string_value(const ByteStringLike& b, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context(), typename std::enable_if::value,int>::type = 0) { std::error_code ec; visit_byte_string(byte_string_view(reinterpret_cast(b.data()),b.size()), tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } template JSONCONS_VISITOR_RETURN_TYPE byte_string_value(const ByteStringLike& b, uint64_t ext_tag, const ser_context& context=ser_context(), typename std::enable_if::value,int>::type = 0) { std::error_code ec; visit_byte_string(byte_string_view(reinterpret_cast(b.data()),b.size()), ext_tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE uint64_value(uint64_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_uint64(value, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE int64_value(int64_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_int64(value, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE half_value(uint16_t value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_half(value, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE double_value(double value, semantic_tag tag = semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_double(value, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE begin_object(semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_begin_object(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE begin_object(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_begin_object(length, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE end_object(const ser_context& context, std::error_code& ec) { visit_end_object(context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE begin_array(semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE begin_array(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_begin_array(length, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE end_array(const ser_context& context, std::error_code& ec) { visit_end_array(context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE key(const string_view_type& name, const ser_context& context, std::error_code& ec) { visit_key(name, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE null_value(semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_null(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE bool_value(bool value, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_bool(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE string_value(const string_view_type& value, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_string(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } template JSONCONS_VISITOR_RETURN_TYPE byte_string_value(const Source& b, semantic_tag tag, const ser_context& context, std::error_code& ec, typename std::enable_if::value,int>::type = 0) { visit_byte_string(byte_string_view(reinterpret_cast(b.data()),b.size()), tag, context, ec); JSONCONS_VISITOR_RETURN; } template JSONCONS_VISITOR_RETURN_TYPE byte_string_value(const Source& b, uint64_t ext_tag, const ser_context& context, std::error_code& ec, typename std::enable_if::value,int>::type = 0) { visit_byte_string(byte_string_view(reinterpret_cast(b.data()),b.size()), ext_tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE uint64_value(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_uint64(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE int64_value(int64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_int64(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE half_value(uint16_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_half(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE double_value(double value, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_double(value, tag, context, ec); JSONCONS_VISITOR_RETURN; } template JSONCONS_VISITOR_RETURN_TYPE typed_array(const jsoncons::span& data, semantic_tag tag=semantic_tag::none, const ser_context& context=ser_context()) { std::error_code ec; visit_typed_array(data, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } template JSONCONS_VISITOR_RETURN_TYPE typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_typed_array(data, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE typed_array(half_arg_t, const jsoncons::span& s, semantic_tag tag = semantic_tag::none, const ser_context& context = ser_context()) { std::error_code ec; visit_typed_array(half_arg, s, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE typed_array(half_arg_t, const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_typed_array(half_arg, s, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE begin_multi_dim(const jsoncons::span& shape, semantic_tag tag = semantic_tag::multi_dim_row_major, const ser_context& context=ser_context()) { std::error_code ec; visit_begin_multi_dim(shape, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE begin_multi_dim(const jsoncons::span& shape, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_begin_multi_dim(shape, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE end_multi_dim(const ser_context& context=ser_context()) { std::error_code ec; visit_end_multi_dim(context, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, context.line(), context.column())); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE end_multi_dim(const ser_context& context, std::error_code& ec) { visit_end_multi_dim(context, ec); JSONCONS_VISITOR_RETURN; } private: virtual void visit_flush() = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(std::size_t /*length*/, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_begin_object(tag, context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context& context, std::error_code& ec) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(std::size_t /*length*/, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context& context, std::error_code& ec) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type& name, const ser_context& context, std::error_code&) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool value, semantic_tag tag, const ser_context& context, std::error_code&) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& value, semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& value, semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& value, uint64_t /* ext_tag */, const ser_context& context, std::error_code& ec) { visit_byte_string(value, semantic_tag::none, context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_half(uint16_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_double(binary::decode_half(value), tag, context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_double(double value, semantic_tag tag, const ser_context& context, std::error_code& ec) = 0; virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag, context, ec); for (auto p = s.begin(); p != s.end(); ++p) { uint64_value(*p, semantic_tag::none, context, ec); } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag, context, ec); for (auto p = s.begin(); p != s.end(); ++p) { uint64_value(*p, semantic_tag::none, context, ec); } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag, context, ec); for (auto p = s.begin(); p != s.end(); ++p) { uint64_value(*p, semantic_tag::none, context, ec); } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag, context, ec); for (auto p = s.begin(); p != s.end(); ++p) { uint64_value(*p,semantic_tag::none,context, ec); } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag,context, ec); for (auto p = s.begin(); p != s.end(); ++p) { int64_value(*p,semantic_tag::none,context, ec); } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag,context, ec); for (auto p = s.begin(); p != s.end(); ++p) { int64_value(*p,semantic_tag::none,context, ec); } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag,context, ec); for (auto p = s.begin(); p != s.end(); ++p) { int64_value(*p,semantic_tag::none,context, ec); } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag,context, ec); for (auto p = s.begin(); p != s.end(); ++p) { int64_value(*p,semantic_tag::none,context, ec); } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(half_arg_t, const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag, context, ec); for (auto p = s.begin(); p != s.end(); ++p) { half_value(*p, semantic_tag::none, context, ec); } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag,context, ec); for (auto p = s.begin(); p != s.end(); ++p) { double_value(*p,semantic_tag::none,context, ec); } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& s, semantic_tag tag, const ser_context& context, std::error_code& ec) { begin_array(s.size(), tag,context, ec); for (auto p = s.begin(); p != s.end(); ++p) { double_value(*p,semantic_tag::none,context, ec); } end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_begin_multi_dim(const jsoncons::span& shape, semantic_tag tag, const ser_context& context, std::error_code& ec) { visit_begin_array(2, tag, context, ec); visit_begin_array(shape.size(), tag, context, ec); for (auto it = shape.begin(); it != shape.end(); ++it) { visit_uint64(*it, semantic_tag::none, context, ec); } visit_end_array(context, ec); JSONCONS_VISITOR_RETURN; } virtual JSONCONS_VISITOR_RETURN_TYPE visit_end_multi_dim(const ser_context& context, std::error_code& ec) { visit_end_array(context, ec); JSONCONS_VISITOR_RETURN; } }; template class basic_default_json_visitor : public basic_json_visitor { public: using typename basic_json_visitor::string_view_type; basic_default_json_visitor() = default; private: void visit_flush() override { } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type&, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type&, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view&, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_half(uint16_t, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_double(double, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } }; template class basic_json_diagnostics_visitor : public basic_default_json_visitor { public: using stream_type = std::basic_ostream; using string_type = std::basic_string; private: using supertype = basic_default_json_visitor; using string_view_type = typename supertype::string_view_type; struct enabler {}; static constexpr CharT visit_begin_array_name[] = {'v','i','s','i','t','_','b','e','g','i','n','_','a','r','r','a','y', 0}; static constexpr CharT visit_end_array_name[] = {'v','i','s','i','t','_','e','n','d','_','a','r','r','a','y', 0}; static constexpr CharT visit_begin_object_name[] = {'v','i','s','i','t','_','b','e','g','i','n','_','o','b','j','e','c','t', 0}; static constexpr CharT visit_end_object_name[] = {'v','i','s','i','t','_','e','n','d','_','o','b','j','e','c','t', 0}; static constexpr CharT visit_key_name[] = {'v','i','s','i','t','_','k','e','y', 0}; static constexpr CharT visit_string_name[] = {'v','i','s','i','t','_','s','t','r','i','n','g', 0}; static constexpr CharT visit_byte_string_name[] = {'v','i','s','i','t','_','b','y','t','e','_','s','t','r','i','n','g', 0}; static constexpr CharT visit_null_name[] = {'v','i','s','i','t','_','n','u','l','l', 0}; static constexpr CharT visit_bool_name[] = {'v','i','s','i','t','_','b','o','o','l', 0}; static constexpr CharT visit_uint64_name[] = {'v','i','s','i','t','_','u','i','n','t','6','4', 0}; static constexpr CharT visit_int64_name[] = {'v','i','s','i','t','_','i','n','t','6','4', 0}; static constexpr CharT visit_half_name[] = {'v','i','s','i','t','_','h','a','l','f', 0}; static constexpr CharT visit_double_name[] = {'v','i','s','i','t','_','d','o','u','b','l','e', 0}; static constexpr CharT separator_ = ':'; stream_type& output_; string_type indentation_; long level_{0}; public: // If CharT is char, then enable the default constructor which binds to // std::cout. template basic_json_diagnostics_visitor( typename std::enable_if::value, U>::type = enabler{}) : basic_json_diagnostics_visitor(std::cout) { } // If CharT is wchar_t, then enable the default constructor which binds // to std::wcout. template basic_json_diagnostics_visitor( typename std::enable_if::value, U>::type = enabler{}) : basic_json_diagnostics_visitor(std::wcout) { } explicit basic_json_diagnostics_visitor( stream_type& output, string_type indentation = string_type()) : output_(output), indentation_(std::move(indentation)) { } private: void indent() { for (long i=0; i= 201703L // not needed for C++17 #else template constexpr C basic_json_diagnostics_visitor::visit_begin_array_name[]; template constexpr C basic_json_diagnostics_visitor::visit_end_array_name[]; template constexpr C basic_json_diagnostics_visitor::visit_begin_object_name[]; template constexpr C basic_json_diagnostics_visitor::visit_end_object_name[]; template constexpr C basic_json_diagnostics_visitor::visit_key_name[]; template constexpr C basic_json_diagnostics_visitor::visit_string_name[]; template constexpr C basic_json_diagnostics_visitor::visit_byte_string_name[]; template constexpr C basic_json_diagnostics_visitor::visit_null_name[]; template constexpr C basic_json_diagnostics_visitor::visit_bool_name[]; template constexpr C basic_json_diagnostics_visitor::visit_uint64_name[]; template constexpr C basic_json_diagnostics_visitor::visit_int64_name[]; template constexpr C basic_json_diagnostics_visitor::visit_half_name[]; template constexpr C basic_json_diagnostics_visitor::visit_double_name[]; #endif // C++17 check using json_visitor = basic_json_visitor; using wjson_visitor = basic_json_visitor; using default_json_visitor = basic_default_json_visitor; using wdefault_json_visitor = basic_default_json_visitor; using json_diagnostics_visitor = basic_json_diagnostics_visitor; using wjson_diagnostics_visitor = basic_json_diagnostics_visitor; } // namespace jsoncons #endif // JSONCONS_JSON_VISITOR_HPP jsoncons-1.3.2/include/jsoncons/pretty_print.hpp000066400000000000000000000042161477700171100221140ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_PRETTY_PRINT_HPP #define JSONCONS_PRETTY_PRINT_HPP #include #include #include #include #include #include #include namespace jsoncons { template class json_printable { public: using char_type = typename Json::char_type; json_printable(const Json& j, indenting indent) : j_(&j), indenting_(indent) { } json_printable(const Json& j, const basic_json_encode_options& options, indenting indent) : j_(&j), options_(options), indenting_(indent) { } void dump(std::basic_ostream& os) const { j_->dump(os, options_, indenting_); } friend std::basic_ostream& operator<<(std::basic_ostream& os, const json_printable& pr) { pr.dump(os); return os; } const Json *j_; basic_json_encode_options options_; indenting indenting_; private: json_printable(); }; template json_printable print(const Json& j) { return json_printable(j, indenting::no_indent); } template json_printable print(const Json& j, const basic_json_encode_options& options) { return json_printable(j, options, indenting::no_indent); } template json_printable pretty_print(const Json& j) { return json_printable(j, indenting::indent); } template json_printable pretty_print(const Json& j, const basic_json_encode_options& options) { return json_printable(j, options, indenting::indent); } } // namespace jsoncons #endif // JSONCONS_PRETTY_PRINT_HPP jsoncons-1.3.2/include/jsoncons/ser_context.hpp000066400000000000000000000014761477700171100217130ustar00rootroot00000000000000/// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_SER_CONTEXT_HPP #define JSONCONS_SER_CONTEXT_HPP #include namespace jsoncons { class ser_context { public: virtual ~ser_context() = default; virtual size_t line() const { return 0; } virtual size_t column() const { return 0; } virtual size_t position() const { return 0; } virtual size_t begin_position() const { return 0; } virtual size_t end_position() const { return 0; } }; } // namespace jsoncons #endif // JSONCONS_SER_CONTEXT_HPP jsoncons-1.3.2/include/jsoncons/sink.hpp000066400000000000000000000172631477700171100203230ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_SINK_HPP #define JSONCONS_SINK_HPP #include #include #include // std::memcpy #include // std::addressof #include #include #include #include namespace jsoncons { // stream_sink template class stream_sink { public: using value_type = CharT; using container_type = std::basic_ostream; private: static constexpr size_t default_buffer_length = 16384; std::basic_ostream* stream_ptr_; std::vector buffer_; CharT * begin_buffer_; const CharT* end_buffer_; CharT* p_; public: // Noncopyable stream_sink(const stream_sink&) = delete; stream_sink(stream_sink&&) = default; stream_sink(std::basic_ostream& os) : stream_ptr_(std::addressof(os)), buffer_(default_buffer_length), begin_buffer_(buffer_.data()), end_buffer_(begin_buffer_+buffer_.size()), p_(begin_buffer_) { } stream_sink(std::basic_ostream& os, std::size_t buflen) : stream_ptr_(std::addressof(os)), buffer_(buflen), begin_buffer_(buffer_.data()), end_buffer_(begin_buffer_+buffer_.size()), p_(begin_buffer_) { } ~stream_sink() noexcept { stream_ptr_->write(begin_buffer_, buffer_length()); stream_ptr_->flush(); } // Movable stream_sink& operator=(const stream_sink&) = delete; stream_sink& operator=(stream_sink&&) = default; void flush() { stream_ptr_->write(begin_buffer_, buffer_length()); stream_ptr_->flush(); p_ = buffer_.data(); } void append(const CharT* s, std::size_t length) { std::size_t diff = end_buffer_ - p_; if (diff >= length) { std::memcpy(p_, s, length*sizeof(CharT)); p_ += length; } else { stream_ptr_->write(begin_buffer_, buffer_length()); stream_ptr_->write(s,length); p_ = begin_buffer_; } } void push_back(CharT ch) { if (p_ < end_buffer_) { *p_++ = ch; } else { stream_ptr_->write(begin_buffer_, buffer_length()); p_ = begin_buffer_; push_back(ch); } } private: std::size_t buffer_length() const { return p_ - begin_buffer_; } }; // binary_stream_sink class binary_stream_sink { public: typedef uint8_t value_type; using container_type = std::basic_ostream; private: static constexpr size_t default_buffer_length = 16384; std::basic_ostream* stream_ptr_; std::vector buffer_; uint8_t * begin_buffer_; const uint8_t* end_buffer_; uint8_t* p_; public: // Noncopyable binary_stream_sink(const binary_stream_sink&) = delete; binary_stream_sink(binary_stream_sink&&) = default; binary_stream_sink(std::basic_ostream& os) : stream_ptr_(std::addressof(os)), buffer_(default_buffer_length), begin_buffer_(buffer_.data()), end_buffer_(begin_buffer_+buffer_.size()), p_(begin_buffer_) { } binary_stream_sink(std::basic_ostream& os, std::size_t buflen) : stream_ptr_(std::addressof(os)), buffer_(buflen), begin_buffer_(buffer_.data()), end_buffer_(begin_buffer_+buffer_.size()), p_(begin_buffer_) { } ~binary_stream_sink() noexcept { stream_ptr_->write((char*)begin_buffer_, buffer_length()); stream_ptr_->flush(); } binary_stream_sink& operator=(const binary_stream_sink&) = delete; binary_stream_sink& operator=(binary_stream_sink&&) = default; void flush() { stream_ptr_->write((char*)begin_buffer_, buffer_length()); p_ = buffer_.data(); } void append(const uint8_t* s, std::size_t length) { std::size_t diff = end_buffer_ - p_; if (diff >= length) { std::memcpy(p_, s, length*sizeof(uint8_t)); p_ += length; } else { stream_ptr_->write((char*)begin_buffer_, buffer_length()); stream_ptr_->write((const char*)s,length); p_ = begin_buffer_; } } void push_back(uint8_t ch) { if (p_ < end_buffer_) { *p_++ = ch; } else { stream_ptr_->write((char*)begin_buffer_, buffer_length()); p_ = begin_buffer_; push_back(ch); } } private: std::size_t buffer_length() const { return p_ - begin_buffer_; } }; // string_sink template class string_sink { public: using value_type = typename StringT::value_type; using container_type = StringT; private: container_type* buf_ptr{nullptr}; public: // Noncopyable string_sink(const string_sink&) = delete; string_sink(string_sink&& other) noexcept { std::swap(buf_ptr,other.buf_ptr); } string_sink(container_type& buf) : buf_ptr(std::addressof(buf)) { } ~string_sink() = default; string_sink& operator=(const string_sink&) = delete; string_sink& operator=(string_sink&& other) noexcept { // TODO: Shouldn't other.buf_ptr be nullified? // Also see move constructor above. std::swap(buf_ptr,other.buf_ptr); return *this; } void flush() { } void append(const value_type* s, std::size_t length) { buf_ptr->insert(buf_ptr->end(), s, s+length); } void push_back(value_type ch) { buf_ptr->push_back(ch); } }; // bytes_sink template class bytes_sink { }; template class bytes_sink::value>::type> { public: using container_type = Container; using value_type = typename Container::value_type; private: container_type* buf_ptr; public: // Noncopyable bytes_sink(const bytes_sink&) = delete; bytes_sink(bytes_sink&&) = default; bytes_sink(container_type& buf) : buf_ptr(std::addressof(buf)) { } ~bytes_sink() = default; bytes_sink& operator=(const bytes_sink&) = delete; bytes_sink& operator=(bytes_sink&&) = default; void flush() { } void push_back(uint8_t ch) { buf_ptr->push_back(static_cast(ch)); } }; } // namespace jsoncons #endif // JSONCONS_SINK_HPP jsoncons-1.3.2/include/jsoncons/source.hpp000066400000000000000000000564661477700171100206670ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_SOURCE_HPP #define JSONCONS_SOURCE_HPP #include #include // std::memcpy #include #include #include #include #include // std::addressof #include #include // std::enable_if #include #include #include // jsoncons::byte_traits #include #include namespace jsoncons { template class basic_null_istream : public std::basic_istream { class null_buffer : public std::basic_streambuf { public: using typename std::basic_streambuf::int_type; using typename std::basic_streambuf::traits_type; null_buffer() = default; null_buffer(const null_buffer&) = delete; null_buffer(null_buffer&&) = default; null_buffer& operator=(const null_buffer&) = delete; null_buffer& operator=(null_buffer&&) = default; int_type overflow( int_type ch = typename std::basic_streambuf::traits_type::eof() ) override { return ch; } } nb_; public: basic_null_istream() : std::basic_istream(&nb_) { } basic_null_istream(const null_buffer&) = delete; basic_null_istream& operator=(const null_buffer&) = delete; basic_null_istream(basic_null_istream&&) noexcept : std::basic_istream(&nb_) { } basic_null_istream& operator=(basic_null_istream&&) noexcept { return *this; } }; template struct char_result { CharT value; bool eof; }; // text sources template class stream_source { public: using value_type = CharT; static constexpr std::size_t default_max_buffer_size = 16384; private: using char_type = typename std::conditional::type; basic_null_istream null_is_; std::basic_istream* stream_ptr_; std::basic_streambuf* sbuf_; std::size_t position_{0}; std::vector buffer_; const value_type* buffer_data_; std::size_t buffer_length_{0}; public: stream_source() : stream_ptr_(&null_is_), sbuf_(null_is_.rdbuf()), buffer_(1), buffer_data_(buffer_.data()) { } // Noncopyable stream_source(const stream_source&) = delete; stream_source(stream_source&& other) noexcept : stream_ptr_(&null_is_), sbuf_(null_is_.rdbuf()), buffer_(), buffer_data_(buffer_.data()) { if (other.stream_ptr_ != &other.null_is_) { stream_ptr_ = other.stream_ptr_; sbuf_ = other.sbuf_; position_ = other.position_; buffer_ = std::move(other.buffer_); buffer_data_ = buffer_.data() + (other.buffer_data_ - other.buffer_.data()); buffer_length_ = other.buffer_length_; other = stream_source(); } } stream_source(std::basic_istream& is, std::size_t buf_size = default_max_buffer_size) : stream_ptr_(std::addressof(is)), sbuf_(is.rdbuf()), buffer_(buf_size), buffer_data_(buffer_.data()) { } ~stream_source() = default; stream_source& operator=(const stream_source&) = delete; stream_source& operator=(stream_source&& other) noexcept { if (other.stream_ptr_ != &other.null_is_) { stream_ptr_ = other.stream_ptr_; sbuf_ = other.sbuf_; position_ = other.position_; buffer_ = std::move(other.buffer_); buffer_data_ = buffer_.data() + (other.buffer_data_ - other.buffer_.data()); buffer_length_ = other.buffer_length_; other = stream_source(); } else { stream_ptr_ = &null_is_; sbuf_ = null_is_.rdbuf(); position_ = 0; buffer_data_ = buffer_.data(); buffer_length_ = 0; } return *this; } bool eof() const { return buffer_length_ == 0 && stream_ptr_->eof(); } bool is_error() const { return stream_ptr_->bad(); } std::size_t position() const { return position_; } void ignore(std::size_t length) { std::size_t len = 0; if (buffer_length_ > 0) { len = (std::min)(buffer_length_, length); position_ += len; buffer_data_ += len; buffer_length_ -= len; } while (len < length) { fill_buffer(); if (buffer_length_ == 0) { break; } std::size_t len2 = (std::min)(buffer_length_, length-len); position_ += len2; buffer_data_ += len2; buffer_length_ -= len2; len += len2; } } char_result peek() { if (buffer_length_ == 0) { fill_buffer(); } if (buffer_length_ > 0) { value_type c = *buffer_data_; return char_result{c, false}; } else { return char_result{0, true}; } } span read_buffer() { if (buffer_length_ == 0) { fill_buffer(); } const value_type* data = buffer_data_; std::size_t length = buffer_length_; buffer_data_ += buffer_length_; position_ += buffer_length_; buffer_length_ = 0; return span(data, length); } std::size_t read(value_type* p, std::size_t length) { std::size_t len = 0; if (buffer_length_ > 0) { len = (std::min)(buffer_length_, length); std::memcpy(p, buffer_data_, len*sizeof(value_type)); buffer_data_ += len; buffer_length_ -= len; position_ += len; } if (length - len == 0) { return len; } else if (length - len < buffer_.size()) { fill_buffer(); if (buffer_length_ > 0) { std::size_t len2 = (std::min)(buffer_length_, length-len); std::memcpy(p+len, buffer_data_, len2*sizeof(value_type)); buffer_data_ += len2; buffer_length_ -= len2; position_ += len2; len += len2; } return len; } else { if (stream_ptr_->eof()) { buffer_length_ = 0; return 0; } JSONCONS_TRY { std::streamsize count = sbuf_->sgetn(reinterpret_cast(p+len), length-len); std::size_t len2 = static_cast(count); if (len2 < length-len) { stream_ptr_->clear(stream_ptr_->rdstate() | std::ios::eofbit); } len += len2; position_ += len2; return len; } JSONCONS_CATCH(const std::exception&) { stream_ptr_->clear(stream_ptr_->rdstate() | std::ios::badbit | std::ios::eofbit); return 0; } } } private: void fill_buffer() { if (stream_ptr_->eof()) { buffer_length_ = 0; return; } buffer_data_ = buffer_.data(); JSONCONS_TRY { std::streamsize count = sbuf_->sgetn(reinterpret_cast(buffer_.data()), buffer_.size()); buffer_length_ = static_cast(count); if (buffer_length_ < buffer_.size()) { stream_ptr_->clear(stream_ptr_->rdstate() | std::ios::eofbit); } } JSONCONS_CATCH(const std::exception&) { stream_ptr_->clear(stream_ptr_->rdstate() | std::ios::badbit | std::ios::eofbit); buffer_length_ = 0; } } }; // string_source template class string_source { public: using value_type = CharT; using string_view_type = jsoncons::basic_string_view; private: const value_type* data_{nullptr}; const value_type* current_{nullptr}; const value_type* end_{nullptr}; public: string_source() noexcept = default; // Noncopyable string_source(const string_source&) = delete; string_source(string_source&& other) = default; template string_source(const Sourceable& s, typename std::enable_if::value>::type* = 0) : data_(s.data()), current_(s.data()), end_(s.data()+s.size()) { } string_source(const value_type* data) : data_(data), current_(data), end_(data+std::char_traits::length(data)) { } string_source& operator=(const string_source&) = delete; string_source& operator=(string_source&& other) = default; bool eof() const { return current_ == end_; } bool is_error() const { return false; } std::size_t position() const { return (current_ - data_)/sizeof(value_type); } void ignore(std::size_t count) { std::size_t len; if (std::size_t(end_ - current_) < count) { len = end_ - current_; } else { len = count; } current_ += len; } char_result peek() { return current_ < end_ ? char_result{*current_, false} : char_result{0, true}; } span read_buffer() { const value_type* data = current_; std::size_t length = end_ - current_; current_ = end_; return span(data, length); } std::size_t read(value_type* p, std::size_t length) { std::size_t len; if (std::size_t(end_ - current_) < length) { len = end_ - current_; } else { len = length; } std::memcpy(p, current_, len*sizeof(value_type)); current_ += len; return len; } }; // iterator source template class iterator_source { public: using value_type = typename std::iterator_traits::value_type; private: static constexpr std::size_t default_max_buffer_size = 16384; IteratorT current_; IteratorT end_; std::size_t position_{0}; std::vector buffer_; std::size_t buffer_length_{0}; using difference_type = typename std::iterator_traits::difference_type; using iterator_category = typename std::iterator_traits::iterator_category; public: // Noncopyable iterator_source(const iterator_source&) = delete; iterator_source(iterator_source&& other) = default; iterator_source(const IteratorT& first, const IteratorT& last, std::size_t buf_size = default_max_buffer_size) : current_(first), end_(last), buffer_(buf_size) { } ~iterator_source() = default; iterator_source& operator=(const iterator_source&) = delete; iterator_source& operator=(iterator_source&& other) = default; bool eof() const { return !(current_ != end_); } bool is_error() const { return false; } std::size_t position() const { return position_; } void ignore(std::size_t count) { while (count-- > 0 && current_ != end_) { ++position_; ++current_; } } char_result peek() { return current_ != end_ ? char_result{*current_, false} : char_result{0, true}; } span read_buffer() { if (buffer_length_ == 0) { buffer_length_ = read(buffer_.data(), buffer_.size()); } std::size_t length = buffer_length_; buffer_length_ = 0; return span(buffer_.data(), length); } template typename std::enable_if::value, std::size_t>::type read(value_type* data, std::size_t length) { std::size_t count = (std::min)(length, static_cast(std::distance(current_, end_))); //JSONCONS_COPY(current_, current_ + count, data); auto end = current_ + count; value_type* p = data; while (current_ != end) { *p++ = *current_++; } //current_ += count; position_ += count; return count; } template typename std::enable_if::value, std::size_t>::type read(value_type* data, std::size_t length) { value_type* p = data; value_type* pend = data + length; while (p < pend && current_ != end_) { *p = static_cast(*current_); ++p; ++current_; } position_ += (p - data); return p - data; } }; // binary sources using binary_stream_source = stream_source; class bytes_source { public: typedef uint8_t value_type; private: const value_type* data_{nullptr}; const value_type* current_{nullptr}; const value_type* end_{nullptr}; public: bytes_source() noexcept = default; // Noncopyable bytes_source(const bytes_source&) = delete; bytes_source(bytes_source&&) = default; template bytes_source(const Sourceable& source, typename std::enable_if::value,int>::type = 0) : data_(reinterpret_cast(source.data())), current_(data_), end_(data_+source.size()) { } bytes_source& operator=(const bytes_source&) = delete; bytes_source& operator=(bytes_source&&) = default; bool eof() const { return current_ == end_; } bool is_error() const { return false; } std::size_t position() const { return current_ - data_; } void ignore(std::size_t count) { std::size_t len; if (std::size_t(end_ - current_) < count) { len = end_ - current_; } else { len = count; } current_ += len; } char_result peek() { return current_ < end_ ? char_result{*current_, false} : char_result{0, true}; } span read_buffer() { const value_type* data = current_; std::size_t length = end_ - current_; current_ = end_; return span(data, length); } std::size_t read(value_type* p, std::size_t length) { std::size_t len; if (std::size_t(end_ - current_) < length) { len = end_ - current_; } else { len = length; } std::memcpy(p, current_, len*sizeof(value_type)); current_ += len; return len; } }; // binary_iterator source template class binary_iterator_source { public: using value_type = uint8_t; private: static constexpr std::size_t default_max_buffer_size = 16384; IteratorT current_; IteratorT end_; std::size_t position_{0}; std::vector buffer_; std::size_t buffer_length_{0}; using difference_type = typename std::iterator_traits::difference_type; using iterator_category = typename std::iterator_traits::iterator_category; public: // Noncopyable binary_iterator_source(const binary_iterator_source&) = delete; binary_iterator_source(binary_iterator_source&& other) = default; binary_iterator_source(const IteratorT& first, const IteratorT& last, std::size_t buf_size = default_max_buffer_size) : current_(first), end_(last), buffer_(buf_size) { } binary_iterator_source& operator=(const binary_iterator_source&) = delete; binary_iterator_source& operator=(binary_iterator_source&& other) = default; bool eof() const { return !(current_ != end_); } bool is_error() const { return false; } std::size_t position() const { return position_; } void ignore(std::size_t count) { while (count-- > 0 && current_ != end_) { ++position_; ++current_; } } char_result peek() { return current_ != end_ ? char_result{static_cast(*current_), false} : char_result{0, true}; } span read_buffer() { if (buffer_length_ == 0) { buffer_length_ = read(buffer_.data(), buffer_.size()); } std::size_t length = buffer_length_; buffer_length_ = 0; return span(buffer_.data(), length); } template typename std::enable_if::value, std::size_t>::type read(value_type* data, std::size_t length) { std::size_t count = (std::min)(length, static_cast(std::distance(current_, end_))); //JSONCONS_COPY(current_, current_ + count, data); auto end = current_ + count; value_type* p = data; while (current_ != end) { *p++ = *current_++; } //current_ += count; position_ += count; return count; } template typename std::enable_if::value, std::size_t>::type read(value_type* data, std::size_t length) { value_type* p = data; value_type* pend = data + length; while (p < pend && current_ != end_) { *p = static_cast(*current_); ++p; ++current_; } position_ += (p - data); return p - data; } }; template struct source_reader { using value_type = typename Source::value_type; static constexpr std::size_t max_buffer_length = 16384; template static typename std::enable_if::value && extension_traits::has_reserve::value && extension_traits::has_data_exact::value , std::size_t>::type read(Source& source, Container& v, std::size_t length) { std::size_t unread = length; std::size_t n = (std::min)(max_buffer_length, unread); while (n > 0 && !source.eof()) { std::size_t offset = v.size(); v.resize(v.size()+n); std::size_t actual = source.read(v.data()+offset, n); unread -= actual; n = (std::min)(max_buffer_length, unread); } return length - unread; } template static typename std::enable_if::value && extension_traits::has_reserve::value && !extension_traits::has_data_exact::value , std::size_t>::type read(Source& source, Container& v, std::size_t length) { std::size_t unread = length; std::size_t n = (std::min)(max_buffer_length, unread); while (n > 0 && !source.eof()) { v.reserve(v.size()+n); std::size_t actual = 0; while (actual < n) { typename Source::value_type c; if (source.read(&c,1) != 1) { break; } v.push_back(c); ++actual; } unread -= actual; n = (std::min)(max_buffer_length, unread); } return length - unread; } }; #if __cplusplus >= 201703L // not needed for C++17 #else template constexpr std::size_t source_reader::max_buffer_length; #endif } // namespace jsoncons #endif // JSONCONS_SOURCE_HPP jsoncons-1.3.2/include/jsoncons/source_adaptor.hpp000066400000000000000000000073021477700171100223620ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_SOURCE_ADAPTOR_HPP #define JSONCONS_SOURCE_ADAPTOR_HPP #include #include #include // json_errc #include #include namespace jsoncons { // text_source_adaptor template class text_source_adaptor { public: using value_type = typename Source::value_type; private: Source source_; bool bof_; public: text_source_adaptor() : bof_(true) { } template text_source_adaptor(Sourceable&& source) : source_(std::forward(source)), bof_(true) { } bool eof() const { return source_.eof(); } bool is_error() const { return source_.is_error(); } span read_buffer(std::error_code& ec) { if (source_.eof()) { return span(); } auto s = source_.read_buffer(); const value_type* data = s.data(); std::size_t length = s.size(); if (bof_ && length > 0) { auto r = unicode_traits::detect_encoding_from_bom(data, length); if (!(r.encoding == unicode_traits::encoding_kind::utf8 || r.encoding == unicode_traits::encoding_kind::undetected)) { ec = json_errc::illegal_unicode_character; return span(); } length -= (r.ptr - data); data = r.ptr; bof_ = false; } return span(data, length); } }; // json_source_adaptor template class json_source_adaptor { public: using value_type = typename Source::value_type; private: Source source_; bool bof_; public: json_source_adaptor() : bof_(true) { } template json_source_adaptor(Sourceable&& source) : source_(std::forward(source)), bof_(true) { } bool eof() const { return source_.eof(); } bool is_error() const { return source_.is_error(); } span read_buffer(std::error_code& ec) { if (source_.eof()) { return span(); } auto s = source_.read_buffer(); const value_type* data = s.data(); std::size_t length = s.size(); if (bof_ && length > 0) { auto r = unicode_traits::detect_json_encoding(data, length); if (!(r.encoding == unicode_traits::encoding_kind::utf8 || r.encoding == unicode_traits::encoding_kind::undetected)) { ec = json_errc::illegal_unicode_character; return span(); } length -= (r.ptr - data); data = r.ptr; bof_ = false; } return span(data, length); } }; } // namespace jsoncons #endif // JSONCONS_SOURCE_ADAPTOR_HPP jsoncons-1.3.2/include/jsoncons/staj_cursor.hpp000066400000000000000000000613411477700171100217110ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_STAJ_CURSOR_HPP #define JSONCONS_STAJ_CURSOR_HPP #include // std::array #include #include #include // std::function #include #include // std::allocator #include #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { // basic_staj_visitor enum class staj_cursor_state { typed_array = 1, multi_dim, shape }; template class basic_staj_visitor : public basic_json_visitor { using super_type = basic_json_visitor; public: using char_type = CharT; using typename super_type::string_view_type; private: basic_staj_event event_; staj_cursor_state state_; typed_array_view data_; jsoncons::span shape_; std::size_t index_{0}; public: basic_staj_visitor() : event_(staj_event_type::null_value), state_(), data_(), shape_() { } ~basic_staj_visitor() = default; void reset() { event_ = staj_event_type::null_value; state_ = {}; data_ = {}; shape_ = {}; index_ = 0; } const basic_staj_event& event() const { return event_; } bool in_available() const { return state_ != staj_cursor_state(); } void send_available(std::error_code& ec) { switch (state_) { case staj_cursor_state::typed_array: advance_typed_array(ec); break; case staj_cursor_state::multi_dim: case staj_cursor_state::shape: advance_multi_dim(ec); break; default: break; } } bool is_typed_array() const { return data_.type() != typed_array_type(); } staj_cursor_state state() const { return state_; } void advance_typed_array(std::error_code& ec) { if (is_typed_array()) { if (index_ < data_.size()) { switch (data_.type()) { case typed_array_type::uint8_value: { this->uint64_value(data_.data(uint8_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::uint16_value: { this->uint64_value(data_.data(uint16_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::uint32_value: { this->uint64_value(data_.data(uint32_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::uint64_value: { this->uint64_value(data_.data(uint64_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::int8_value: { this->int64_value(data_.data(int8_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::int16_value: { this->int64_value(data_.data(int16_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::int32_value: { this->int64_value(data_.data(int32_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::int64_value: { this->int64_value(data_.data(int64_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::half_value: { this->half_value(data_.data(half_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::float_value: { this->double_value(data_.data(float_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::double_value: { this->double_value(data_.data(double_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } default: break; } ++index_; } else { this->end_array(); state_ = staj_cursor_state(); data_ = typed_array_view(); index_ = 0; } } } void advance_multi_dim(std::error_code& ec) { if (shape_.size() != 0) { if (state_ == staj_cursor_state::multi_dim) { this->begin_array(shape_.size(), semantic_tag::none, ser_context(), ec); state_ = staj_cursor_state::shape; } else if (index_ < shape_.size()) { this->uint64_value(shape_[index_], semantic_tag::none, ser_context(), ec); ++index_; } else { state_ = staj_cursor_state(); this->end_array(ser_context(), ec); shape_ = jsoncons::span(); index_ = 0; } } } void dump(basic_json_visitor& visitor, const ser_context& context, std::error_code& ec) { if (is_typed_array()) { if (index_ != 0) { event().send_json_event(visitor, context, ec); const std::size_t len = data_.size(); switch (data_.type()) { case typed_array_type::uint8_value: { for (auto i = index_; i < len; ++i) { visitor.uint64_value(data_.data(uint8_array_arg)[i]); } break; } case typed_array_type::uint16_value: { for (auto i = index_; i < len; ++i) { visitor.uint64_value(data_.data(uint16_array_arg)[i]); } break; } case typed_array_type::uint32_value: { for (auto i = index_; i < len; ++i) { visitor.uint64_value(data_.data(uint32_array_arg)[i]); } break; } case typed_array_type::uint64_value: { for (auto i = index_; i < len; ++i) { visitor.uint64_value(data_.data(uint64_array_arg)[i]); } break; } case typed_array_type::int8_value: { for (auto i = index_; i < len; ++i) { visitor.int64_value(data_.data(int8_array_arg)[i]); } break; } case typed_array_type::int16_value: { for (auto i = index_; i < len; ++i) { visitor.int64_value(data_.data(int16_array_arg)[i]); } break; } case typed_array_type::int32_value: { for (auto i = index_; i < len; ++i) { visitor.int64_value(data_.data(int32_array_arg)[i]); } break; } case typed_array_type::int64_value: { for (auto i = index_; i < len; ++i) { visitor.int64_value(data_.data(int64_array_arg)[i]); } break; } case typed_array_type::float_value: { for (auto i = index_; i < len; ++i) { visitor.double_value(data_.data(float_array_arg)[i]); } break; } case typed_array_type::double_value: { for (auto i = index_; i < len; ++i) { visitor.double_value(data_.data(double_array_arg)[i]); } break; } default: break; } state_ = staj_cursor_state(); data_ = typed_array_view(); index_ = 0; } else { switch (data_.type()) { case typed_array_type::uint8_value: { visitor.typed_array(data_.data(uint8_array_arg)); break; } case typed_array_type::uint16_value: { visitor.typed_array(data_.data(uint16_array_arg)); break; } case typed_array_type::uint32_value: { visitor.typed_array(data_.data(uint32_array_arg)); break; } case typed_array_type::uint64_value: { visitor.typed_array(data_.data(uint64_array_arg)); break; } case typed_array_type::int8_value: { visitor.typed_array(data_.data(int8_array_arg)); break; } case typed_array_type::int16_value: { visitor.typed_array(data_.data(int16_array_arg)); break; } case typed_array_type::int32_value: { visitor.typed_array(data_.data(int32_array_arg)); break; } case typed_array_type::int64_value: { visitor.typed_array(data_.data(int64_array_arg)); break; } case typed_array_type::float_value: { visitor.typed_array(data_.data(float_array_arg)); break; } case typed_array_type::double_value: { visitor.typed_array(data_.data(double_array_arg)); break; } default: break; } state_ = staj_cursor_state(); data_ = typed_array_view(); } } else { event().send_json_event(visitor, context, ec); } } private: static constexpr bool accept(const basic_staj_event&, const ser_context&) { return true; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(staj_event_type::begin_object, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(std::size_t length, semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(staj_event_type::begin_object, length, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context&, std::error_code&) override { event_ = basic_staj_event(staj_event_type::end_object); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(staj_event_type::begin_array, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(std::size_t length, semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(staj_event_type::begin_array, length, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context&, std::error_code&) override { event_ = basic_staj_event(staj_event_type::end_array); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type& name, const ser_context&, std::error_code&) override { event_ = basic_staj_event(name, staj_event_type::key); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(staj_event_type::null_value, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool value, semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(value, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& s, semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(s, staj_event_type::string_value, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& s, semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(s, staj_event_type::byte_string_value, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& s, uint64_t ext_tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(s, staj_event_type::byte_string_value, ext_tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t value, semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(value, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t value, semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(value, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_half(uint16_t value, semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(half_arg, value, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_double(double value, semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(value, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& v, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(v.data(), v.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(half_arg_t, const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } /* JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span&, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } */ JSONCONS_VISITOR_RETURN_TYPE visit_begin_multi_dim(const jsoncons::span& shape, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::multi_dim; shape_ = shape; this->begin_array(2, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_multi_dim(const ser_context& context, std::error_code& ec) override { this->end_array(context, ec); JSONCONS_VISITOR_RETURN; } void visit_flush() override { } }; // basic_staj_cursor template class basic_staj_cursor { public: virtual ~basic_staj_cursor() = default; virtual void array_expected(std::error_code& ec) { if (!(current().event_type() == staj_event_type::begin_array || current().event_type() == staj_event_type::byte_string_value)) { ec = conv_errc::not_vector; } } virtual bool done() const = 0; virtual const basic_staj_event& current() const = 0; virtual void read_to(basic_json_visitor& visitor) = 0; virtual void read_to(basic_json_visitor& visitor, std::error_code& ec) = 0; virtual void next() = 0; virtual void next(std::error_code& ec) = 0; virtual const ser_context& context() const = 0; }; template class basic_staj_filter_view : basic_staj_cursor { basic_staj_cursor* cursor_; std::function&, const ser_context&)> pred_; public: basic_staj_filter_view(basic_staj_cursor& cursor, std::function&, const ser_context&)> pred) : cursor_(std::addressof(cursor)), pred_(pred) { while (!done() && !pred_(current(),context())) { cursor_->next(); } } bool done() const override { return cursor_->done(); } const basic_staj_event& current() const override { return cursor_->current(); } void read_to(basic_json_visitor& visitor) override { cursor_->read_to(visitor); } void read_to(basic_json_visitor& visitor, std::error_code& ec) override { cursor_->read_to(visitor, ec); } void next() override { cursor_->next(); while (!done() && !pred_(current(),context())) { cursor_->next(); } } void next(std::error_code& ec) override { cursor_->next(ec); while (!done() && !pred_(current(),context()) && !ec) { cursor_->next(ec); } } const ser_context& context() const override { return cursor_->context(); } friend basic_staj_filter_view operator|(basic_staj_filter_view& cursor, std::function&, const ser_context&)> pred) { return basic_staj_filter_view(cursor, pred); } }; using staj_event = basic_staj_event; using wstaj_event = basic_staj_event; using staj_cursor = basic_staj_cursor; using wstaj_cursor = basic_staj_cursor; using staj_filter_view = basic_staj_filter_view; using wstaj_filter_view = basic_staj_filter_view; } // namespace jsoncons #endif // JSONCONS_STAJ_CURSOR_HPP jsoncons-1.3.2/include/jsoncons/staj_event.hpp000066400000000000000000000472561477700171100215260ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_STAJ_EVENT_HPP #define JSONCONS_STAJ_EVENT_HPP #include // std::array #include #include #include // std::function #include #include // std::allocator #include #include // std::enable_if #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { enum class staj_event_type : uint8_t { key = 0, // 0000 string_value = 1, // 0001 byte_string_value = 2, // 0010 null_value = 3, // 0011 bool_value = 4, // 0100 int64_value = 5, // 0101 uint64_value = 6, // 0110 half_value = 8, // 1000 double_value = 9, // 1001 begin_object = 13, // 1101 end_object = 7, // 0111 begin_array = 14, // 1110 end_array = 15 // 1111 }; inline bool is_begin_container(staj_event_type event_type) noexcept { static const uint8_t mask{ uint8_t(staj_event_type::begin_object) & uint8_t(staj_event_type::begin_array) }; return (uint8_t(event_type) & mask) == mask; } inline bool is_end_container(staj_event_type event_type) noexcept { static const uint8_t mask{ uint8_t(staj_event_type::end_object) & uint8_t(staj_event_type::end_array) }; return (uint8_t(event_type) & mask) == mask; } template std::basic_ostream& operator<<(std::basic_ostream& os, staj_event_type tag) { static constexpr const CharT* begin_array_name = JSONCONS_CSTRING_CONSTANT(CharT, "begin_array"); static constexpr const CharT* end_array_name = JSONCONS_CSTRING_CONSTANT(CharT, "end_array"); static constexpr const CharT* begin_object_name = JSONCONS_CSTRING_CONSTANT(CharT, "begin_object"); static constexpr const CharT* end_object_name = JSONCONS_CSTRING_CONSTANT(CharT, "end_object"); static constexpr const CharT* key_name = JSONCONS_CSTRING_CONSTANT(CharT, "key"); static constexpr const CharT* string_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "string_value"); static constexpr const CharT* byte_string_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "byte_string_value"); static constexpr const CharT* null_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "null_value"); static constexpr const CharT* bool_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "bool_value"); static constexpr const CharT* uint64_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "uint64_value"); static constexpr const CharT* int64_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "int64_value"); static constexpr const CharT* half_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "half_value"); static constexpr const CharT* double_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "double_value"); switch (tag) { case staj_event_type::begin_array: { os << begin_array_name; break; } case staj_event_type::end_array: { os << end_array_name; break; } case staj_event_type::begin_object: { os << begin_object_name; break; } case staj_event_type::end_object: { os << end_object_name; break; } case staj_event_type::key: { os << key_name; break; } case staj_event_type::string_value: { os << string_value_name; break; } case staj_event_type::byte_string_value: { os << byte_string_value_name; break; } case staj_event_type::null_value: { os << null_value_name; break; } case staj_event_type::bool_value: { os << bool_value_name; break; } case staj_event_type::int64_value: { os << int64_value_name; break; } case staj_event_type::uint64_value: { os << uint64_value_name; break; } case staj_event_type::half_value: { os << half_value_name; break; } case staj_event_type::double_value: { os << double_value_name; break; } } return os; } template class basic_staj_event { staj_event_type event_type_; semantic_tag tag_; uint64_t ext_tag_{0}; union { bool bool_value_; int64_t int64_value_; uint64_t uint64_value_; uint16_t half_value_; double double_value_; const CharT* string_data_; const uint8_t* byte_string_data_; } value_; std::size_t length_{0}; public: using string_view_type = jsoncons::basic_string_view; basic_staj_event(staj_event_type event_type, semantic_tag tag = semantic_tag::none) : event_type_(event_type), tag_(tag), value_() { } basic_staj_event(staj_event_type event_type, std::size_t length, semantic_tag tag = semantic_tag::none) : event_type_(event_type), tag_(tag), value_(), length_(length) { } basic_staj_event(null_type, semantic_tag tag) : event_type_(staj_event_type::null_value), tag_(tag), value_() { } basic_staj_event(bool value, semantic_tag tag) : event_type_(staj_event_type::bool_value), tag_(tag) { value_.bool_value_ = value; } basic_staj_event(int64_t value, semantic_tag tag) : event_type_(staj_event_type::int64_value), tag_(tag) { value_.int64_value_ = value; } basic_staj_event(uint64_t value, semantic_tag tag) : event_type_(staj_event_type::uint64_value), tag_(tag) { value_.uint64_value_ = value; } basic_staj_event(half_arg_t, uint16_t value, semantic_tag tag) : event_type_(staj_event_type::half_value), tag_(tag) { value_.half_value_ = value; } basic_staj_event(double value, semantic_tag tag) : event_type_(staj_event_type::double_value), tag_(tag) { value_.double_value_ = value; } basic_staj_event(const string_view_type& s, staj_event_type event_type, semantic_tag tag = semantic_tag::none) : event_type_(event_type), tag_(tag), length_(s.length()) { value_.string_data_ = s.data(); } basic_staj_event(const byte_string_view& s, staj_event_type event_type, semantic_tag tag = semantic_tag::none) : event_type_(event_type), tag_(tag), length_(s.size()) { value_.byte_string_data_ = s.data(); } basic_staj_event(const byte_string_view& s, staj_event_type event_type, uint64_t ext_tag) : event_type_(event_type), tag_(semantic_tag::ext), ext_tag_(ext_tag), length_(s.size()) { value_.byte_string_data_ = s.data(); } ~basic_staj_event() = default; std::size_t size() const { return length_; } template T get() const { std::error_code ec; T val = get(ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } return val; } template T get(std::error_code& ec) const { return get_(std::allocator{}, ec); } template typename std::enable_if::value && std::is_same::value, T>::type get_(Allocator,std::error_code& ec) const { switch (event_type_) { case staj_event_type::key: case staj_event_type::string_value: { value_converter,T> converter; return converter.convert(jsoncons::basic_string_view(value_.string_data_, length_), tag(), ec); } case staj_event_type::byte_string_value: { value_converter converter; return converter.convert(byte_string_view(value_.byte_string_data_,length_),tag(),ec); } case staj_event_type::uint64_value: { value_converter converter; return converter.convert(value_.uint64_value_, tag(), ec); } case staj_event_type::int64_value: { value_converter converter; return converter.convert(value_.int64_value_, tag(), ec); } case staj_event_type::half_value: { value_converter converter; return converter.convert(value_.half_value_, tag(), ec); } case staj_event_type::double_value: { value_converter converter; return converter.convert(value_.double_value_, tag(), ec); } case staj_event_type::bool_value: { value_converter converter; return converter.convert(value_.bool_value_,tag(),ec); } case staj_event_type::null_value: { value_converter converter; return converter.convert(tag(), ec); } default: { ec = conv_errc::not_string; return T{}; } } } template typename std::enable_if::value && std::is_same::value, T>::type get_(Allocator, std::error_code& ec) const { T s; switch (event_type_) { case staj_event_type::key: case staj_event_type::string_value: s = T(value_.string_data_, length_); break; default: ec = conv_errc::not_string_view; break; } return s; } template typename std::enable_if::value, T>::type get_(Allocator, std::error_code& ec) const { T s; switch (event_type_) { case staj_event_type::byte_string_value: s = T(value_.byte_string_data_, length_); break; default: ec = conv_errc::not_byte_string_view; break; } return s; } template typename std::enable_if::value && std::is_same::value,T>::type get_(Allocator, std::error_code& ec) const { switch (event_type_) { case staj_event_type::byte_string_value: { value_converter converter; return converter.convert(byte_string_view(value_.byte_string_data_, length_), tag(), ec); } case staj_event_type::string_value: { value_converter,T> converter; return converter.convert(jsoncons::basic_string_view(value_.string_data_, length_), tag(), ec); } default: ec = conv_errc::not_byte_string; return T{}; } } template typename std::enable_if::value, IntegerType>::type get_(Allocator, std::error_code& ec) const { switch (event_type_) { case staj_event_type::string_value: { IntegerType val; auto result = jsoncons::detail::to_integer(value_.string_data_, length_, val); if (!result) { ec = conv_errc::not_integer; return IntegerType(); } return val; } case staj_event_type::half_value: return static_cast(value_.half_value_); case staj_event_type::double_value: return static_cast(value_.double_value_); case staj_event_type::int64_value: return static_cast(value_.int64_value_); case staj_event_type::uint64_value: return static_cast(value_.uint64_value_); case staj_event_type::bool_value: return static_cast(value_.bool_value_ ? 1 : 0); default: ec = conv_errc::not_integer; return IntegerType(); } } template typename std::enable_if::value, T>::type get_(Allocator, std::error_code& ec) const { return static_cast(as_double(ec)); } template typename std::enable_if::value, T>::type get_(Allocator, std::error_code& ec) const { return as_bool(ec); } staj_event_type event_type() const noexcept { return event_type_; } semantic_tag tag() const noexcept { return tag_; } uint64_t ext_tag() const noexcept { return ext_tag_; } private: double as_double(std::error_code& ec) const { switch (event_type_) { case staj_event_type::key: case staj_event_type::string_value: { jsoncons::detail::chars_to f; return f(value_.string_data_, length_); } case staj_event_type::double_value: return value_.double_value_; case staj_event_type::int64_value: return static_cast(value_.int64_value_); case staj_event_type::uint64_value: return static_cast(value_.uint64_value_); case staj_event_type::half_value: { double x = binary::decode_half(value_.half_value_); return static_cast(x); } default: ec = conv_errc::not_double; return double(); } } bool as_bool(std::error_code& ec) const { switch (event_type_) { case staj_event_type::bool_value: return value_.bool_value_; case staj_event_type::double_value: return value_.double_value_ != 0.0; case staj_event_type::int64_value: return value_.int64_value_ != 0; case staj_event_type::uint64_value: return value_.uint64_value_ != 0; default: ec = conv_errc::not_bool; return bool(); } } public: void send_json_event(basic_json_visitor& visitor, const ser_context& context, std::error_code& ec) const { switch (event_type()) { case staj_event_type::begin_array: visitor.begin_array(tag(), context); break; case staj_event_type::end_array: visitor.end_array(context); break; case staj_event_type::begin_object: visitor.begin_object(tag(), context, ec); break; case staj_event_type::end_object: visitor.end_object(context, ec); break; case staj_event_type::key: visitor.key(string_view_type(value_.string_data_,length_), context); break; case staj_event_type::string_value: visitor.string_value(string_view_type(value_.string_data_,length_), tag(), context); break; case staj_event_type::byte_string_value: visitor.byte_string_value(byte_string_view(value_.byte_string_data_,length_), tag(), context); break; case staj_event_type::null_value: visitor.null_value(tag(), context); break; case staj_event_type::bool_value: visitor.bool_value(value_.bool_value_, tag(), context); break; case staj_event_type::int64_value: visitor.int64_value(value_.int64_value_, tag(), context); break; case staj_event_type::uint64_value: visitor.uint64_value(value_.uint64_value_, tag(), context); break; case staj_event_type::half_value: visitor.half_value(value_.half_value_, tag(), context); break; case staj_event_type::double_value: visitor.double_value(value_.double_value_, tag(), context); break; default: break; } } void send_value_event(basic_item_event_visitor& visitor, const ser_context& context, std::error_code& ec) const { switch (event_type()) { case staj_event_type::key: visitor.string_value(string_view_type(value_.string_data_,length_), tag(), context); break; case staj_event_type::begin_array: visitor.begin_array(tag(), context); break; case staj_event_type::end_array: visitor.end_array(context); break; case staj_event_type::begin_object: visitor.begin_object(tag(), context, ec); break; case staj_event_type::end_object: visitor.end_object(context, ec); break; case staj_event_type::string_value: visitor.string_value(string_view_type(value_.string_data_,length_), tag(), context); break; case staj_event_type::byte_string_value: visitor.byte_string_value(byte_string_view(value_.byte_string_data_,length_), tag(), context); break; case staj_event_type::null_value: visitor.null_value(tag(), context); break; case staj_event_type::bool_value: visitor.bool_value(value_.bool_value_, tag(), context); break; case staj_event_type::int64_value: visitor.int64_value(value_.int64_value_, tag(), context); break; case staj_event_type::uint64_value: visitor.uint64_value(value_.uint64_value_, tag(), context); break; case staj_event_type::half_value: visitor.half_value(value_.half_value_, tag(), context); break; case staj_event_type::double_value: visitor.double_value(value_.double_value_, tag(), context); break; default: break; } } }; } // namespace jsoncons #endif // JSONCONS_STAJ_EVENT_HPP jsoncons-1.3.2/include/jsoncons/staj_event_reader.hpp000066400000000000000000000664131477700171100230440ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_STAJ_EVENT_READER_HPP #define JSONCONS_STAJ_EVENT_READER_HPP #include // std::array #include #include #include // std::function #include #include // std::allocator #include #include #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { // basic_item_event_receiver enum class item_event_reader_state { typed_array = 1, multi_dim, shape }; template class basic_item_event_receiver : public basic_item_event_visitor { using super_type = basic_item_event_visitor; public: using char_type = CharT; using typename super_type::string_view_type; private: basic_staj_event event_; item_event_reader_state state_; typed_array_view data_; jsoncons::span shape_; std::size_t index_{0}; public: basic_item_event_receiver() : event_(staj_event_type::null_value), state_(), data_(), shape_() { } void reset() { event_ = staj_event_type::null_value; state_ = {}; data_ = {}; shape_ = {}; index_ = 0; } const basic_staj_event& event() const { return event_; } bool in_available() const { return state_ != item_event_reader_state(); } void send_available(std::error_code& ec) { switch (state_) { case item_event_reader_state::typed_array: advance_typed_array(ec); break; case item_event_reader_state::multi_dim: case item_event_reader_state::shape: advance_multi_dim(ec); break; default: break; } } bool is_typed_array() const { return data_.type() != typed_array_type(); } item_event_reader_state state() const { return state_; } void advance_typed_array(std::error_code& ec) { if (is_typed_array()) { if (index_ < data_.size()) { switch (data_.type()) { case typed_array_type::uint8_value: { this->uint64_value(data_.data(uint8_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::uint16_value: { this->uint64_value(data_.data(uint16_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::uint32_value: { this->uint64_value(data_.data(uint32_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::uint64_value: { this->uint64_value(data_.data(uint64_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::int8_value: { this->int64_value(data_.data(int8_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::int16_value: { this->int64_value(data_.data(int16_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::int32_value: { this->int64_value(data_.data(int32_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::int64_value: { this->int64_value(data_.data(int64_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::half_value: { this->half_value(data_.data(half_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::float_value: { this->double_value(data_.data(float_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::double_value: { this->double_value(data_.data(double_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } default: break; } ++index_; } else { this->end_array(); state_ = item_event_reader_state(); data_ = typed_array_view(); index_ = 0; } } } void advance_multi_dim(std::error_code& ec) { if (shape_.size() != 0) { if (state_ == item_event_reader_state::multi_dim) { this->begin_array(shape_.size(), semantic_tag::none, ser_context(), ec); state_ = item_event_reader_state::shape; } else if (index_ < shape_.size()) { this->uint64_value(shape_[index_], semantic_tag::none, ser_context(), ec); ++index_; } else { state_ = item_event_reader_state(); this->end_array(ser_context(), ec); shape_ = jsoncons::span(); index_ = 0; } } } void dump(basic_item_event_visitor& visitor, const ser_context& context, std::error_code& ec) { if (is_typed_array()) { if (index_ != 0) { event().send_value_event(visitor, context, ec); const std::size_t len = data_.size(); switch (data_.type()) { case typed_array_type::uint8_value: { for (auto i = index_; i < len; ++i) { visitor.uint64_value(data_.data(uint8_array_arg)[i]); } break; } case typed_array_type::uint16_value: { for (auto i = index_; i < len; ++i) { visitor.uint64_value(data_.data(uint16_array_arg)[i]); } break; } case typed_array_type::uint32_value: { for (auto i = index_; i < len; ++i) { visitor.uint64_value(data_.data(uint32_array_arg)[i]); } break; } case typed_array_type::uint64_value: { for (auto i = index_; i < len; ++i) { visitor.uint64_value(data_.data(uint64_array_arg)[i]); } break; } case typed_array_type::int8_value: { for (auto i = index_; i < len; ++i) { visitor.int64_value(data_.data(int8_array_arg)[i]); } break; } case typed_array_type::int16_value: { for (auto i = index_; i < len; ++i) { visitor.int64_value(data_.data(int16_array_arg)[i]); } break; } case typed_array_type::int32_value: { for (auto i = index_; i < len; ++i) { visitor.int64_value(data_.data(int32_array_arg)[i]); } break; } case typed_array_type::int64_value: { for (auto i = index_; i < len; ++i) { visitor.int64_value(data_.data(int64_array_arg)[i]); } break; } case typed_array_type::float_value: { for (auto i = index_; i < len; ++i) { visitor.double_value(data_.data(float_array_arg)[i]); } break; } case typed_array_type::double_value: { for (auto i = index_; i < len; ++i) { visitor.double_value(data_.data(double_array_arg)[i]); } break; } default: break; } state_ = item_event_reader_state(); data_ = typed_array_view(); index_ = 0; } else { switch (data_.type()) { case typed_array_type::uint8_value: { visitor.typed_array(data_.data(uint8_array_arg)); break; } case typed_array_type::uint16_value: { visitor.typed_array(data_.data(uint16_array_arg)); break; } case typed_array_type::uint32_value: { visitor.typed_array(data_.data(uint32_array_arg)); break; } case typed_array_type::uint64_value: { visitor.typed_array(data_.data(uint64_array_arg)); break; } case typed_array_type::int8_value: { visitor.typed_array(data_.data(int8_array_arg)); break; } case typed_array_type::int16_value: { visitor.typed_array(data_.data(int16_array_arg)); break; } case typed_array_type::int32_value: { visitor.typed_array(data_.data(int32_array_arg)); break; } case typed_array_type::int64_value: { visitor.typed_array(data_.data(int64_array_arg)); break; } case typed_array_type::float_value: { visitor.typed_array(data_.data(float_array_arg)); break; } case typed_array_type::double_value: { visitor.typed_array(data_.data(double_array_arg)); break; } default: break; } state_ = item_event_reader_state(); data_ = typed_array_view(); } } else { event().send_value_event(visitor, context, ec); } } private: JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(staj_event_type::begin_object, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(std::size_t length, semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(staj_event_type::begin_object, length, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context&, std::error_code&) override { event_ = basic_staj_event(staj_event_type::end_object); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(staj_event_type::begin_array, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(std::size_t length, semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(staj_event_type::begin_array, length, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context&, std::error_code&) override { event_ = basic_staj_event(staj_event_type::end_array); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(staj_event_type::null_value, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool value, semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(value, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& s, semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(s, staj_event_type::string_value, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& s, semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(s, staj_event_type::byte_string_value, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& s, uint64_t ext_tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(s, staj_event_type::byte_string_value, ext_tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t value, semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(value, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t value, semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(value, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_half(uint16_t value, semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(half_arg, value, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_double(double value, semantic_tag tag, const ser_context&, std::error_code&) override { event_ = basic_staj_event(value, tag); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& v, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = item_event_reader_state::typed_array; data_ = typed_array_view(v.data(), v.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = item_event_reader_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = item_event_reader_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = item_event_reader_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = item_event_reader_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = item_event_reader_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = item_event_reader_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = item_event_reader_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(half_arg_t, const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = item_event_reader_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = item_event_reader_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = item_event_reader_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; this->begin_array(tag, context, ec); JSONCONS_VISITOR_RETURN; } /* JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span&, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } */ JSONCONS_VISITOR_RETURN_TYPE visit_begin_multi_dim(const jsoncons::span& shape, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = item_event_reader_state::multi_dim; shape_ = shape; this->begin_array(2, tag, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_multi_dim(const ser_context& context, std::error_code& ec) override { this->end_array(context, ec); JSONCONS_VISITOR_RETURN; } void visit_flush() override { } }; // basic_staj_event_reader template class basic_staj_event_reader { public: virtual ~basic_staj_event_reader() = default; virtual void array_expected(std::error_code& ec) { if (!(current().event_type() == staj_event_type::begin_array || current().event_type() == staj_event_type::byte_string_value)) { ec = conv_errc::not_vector; } } virtual bool done() const = 0; virtual const basic_staj_event& current() const = 0; virtual void read_to(basic_item_event_visitor& visitor) = 0; virtual void read_to(basic_item_event_visitor& visitor, std::error_code& ec) = 0; virtual void next() = 0; virtual void next(std::error_code& ec) = 0; virtual const ser_context& context() const = 0; }; template class basic_staj2_filter_view : basic_staj_event_reader { basic_staj_event_reader* cursor_; std::function&, const ser_context&)> pred_; public: basic_staj2_filter_view(basic_staj_event_reader& cursor, std::function&, const ser_context&)> pred) : cursor_(std::addressof(cursor)), pred_(pred) { while (!done() && !pred_(current(),context())) { cursor_->next(); } } bool done() const override { return cursor_->done(); } const basic_staj_event& current() const override { return cursor_->current(); } void read_to(basic_item_event_visitor& visitor) override { cursor_->read_to(visitor); } void read_to(basic_item_event_visitor& visitor, std::error_code& ec) override { cursor_->read_to(visitor, ec); } void next() override { cursor_->next(); while (!done() && !pred_(current(),context())) { cursor_->next(); } } void next(std::error_code& ec) override { cursor_->next(ec); while (!done() && !pred_(current(),context()) && !ec) { cursor_->next(ec); } } const ser_context& context() const override { return cursor_->context(); } friend basic_staj2_filter_view operator|(basic_staj2_filter_view& cursor, std::function&, const ser_context&)> pred) { return basic_staj2_filter_view(cursor, pred); } }; using item_event = basic_staj_event; using witem_event = basic_staj_event; using staj_event_reader = basic_staj_event_reader; using wstaj_event_reader = basic_staj_event_reader; using staj2_filter_view = basic_staj2_filter_view; using wstaj2_filter_view = basic_staj2_filter_view; } // namespace jsoncons #endif // JSONCONS_STAJ_EVENT_READER_HPP jsoncons-1.3.2/include/jsoncons/staj_iterator.hpp000066400000000000000000000302451477700171100222240ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_STAJ_ITERATOR_HPP #define JSONCONS_STAJ_ITERATOR_HPP #include #include #include // std::input_iterator_tag #include #include // placement new #include #include #include #include #include #include #include #include #include #include namespace jsoncons { // staj_array_view template class staj_array_view; template class staj_array_iterator { using char_type = typename Json::char_type; using value_type = T; using difference_type = std::ptrdiff_t; using pointer = T*; using reference = T&; using iterator_category = std::input_iterator_tag; private: staj_array_view* view_{nullptr}; bool done_{false}; std::exception_ptr eptr_; public: staj_array_iterator() noexcept : done_(true) { } staj_array_iterator(staj_array_view& view) : view_(std::addressof(view)) { if (view_->cursor_->done()) { done_ = true; } else if (view_->cursor_->current().event_type() == staj_event_type::begin_array) { next(); } else { done_ = true; } } staj_array_iterator(staj_array_view& view, std::error_code& ec) : view_(std::addressof(view)) { if (view_->cursor_->done()) { done_ = true; } else if (view_->cursor_->current().event_type() == staj_event_type::begin_array) { next(ec); if (JSONCONS_UNLIKELY(ec)) {done_ = true;} } else { done_ = true; } } ~staj_array_iterator() noexcept = default; bool has_value() const { return !eptr_; } const T& operator*() const { if (JSONCONS_UNLIKELY(eptr_)) { std::rethrow_exception(eptr_); } return *view_->value_; } const T* operator->() const { if (JSONCONS_UNLIKELY(eptr_)) { std::rethrow_exception(eptr_); } return view_->value_.operator->(); } staj_array_iterator& operator++() { next(); return *this; } staj_array_iterator& increment(std::error_code& ec) { next(ec); if (JSONCONS_UNLIKELY(ec)) {done_ = true;} return *this; } staj_array_iterator operator++(int) // postfix increment { staj_array_iterator temp(*this); next(); return temp; } friend bool operator==(const staj_array_iterator& a, const staj_array_iterator& b) { return (a.done() && b.done()); } friend bool operator!=(const staj_array_iterator& a, const staj_array_iterator& b) { return !(a == b); } private: bool done() const { return done_; } void next() { if (JSONCONS_UNLIKELY(done_)) { return; } std::error_code ec; next(ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, view_->cursor_->context().line(), view_->cursor_->context().column())); } } void next(std::error_code& ec) { if (JSONCONS_UNLIKELY(done_)) { return; } if (view_->cursor_->done()) { done_ = true; return; } view_->cursor_->next(ec); if (JSONCONS_UNLIKELY(ec)) { done_ = true; return; } if (JSONCONS_UNLIKELY(view_->cursor_->current().event_type() == staj_event_type::end_array)) { done_ = true; return; } eptr_ = std::exception_ptr(); JSONCONS_TRY { view_->value_ = decode_traits::decode(*view_->cursor_, view_->decoder_, ec); } JSONCONS_CATCH(const conv_error&) { eptr_ = std::current_exception(); } } }; template class staj_array_view { friend class staj_array_iterator; public: using char_type = typename Json::char_type; using iterator = staj_array_iterator; private: basic_staj_cursor* cursor_; json_decoder decoder_; jsoncons::optional value_; public: staj_array_view(basic_staj_cursor& cursor) : cursor_(std::addressof(cursor)) { } iterator begin() { return staj_array_iterator(*this); } iterator end() { return staj_array_iterator(); } }; // staj_object_view template class staj_object_view; template class staj_object_iterator { using char_type = typename Json::char_type; using key_type = std::basic_string; using value_type = std::pair; using difference_type = std::ptrdiff_t; using pointer = value_type*; using reference = value_type&; using iterator_category = std::input_iterator_tag; private: staj_object_view* view_{nullptr}; bool done_{false}; std::exception_ptr eptr_; public: staj_object_iterator() noexcept : done_(true) { } staj_object_iterator(staj_object_view& view) : view_(std::addressof(view)) { if (view_->cursor_->done()) { done_ = true; } else if (view_->cursor_->current().event_type() == staj_event_type::begin_object) { next(); } else { done_ = true; } } staj_object_iterator(staj_object_view& view, std::error_code& ec) : view_(std::addressof(view)) { if (view_->cursor_->done()) { done_ = true; } else if (view_->cursor_->current().event_type() == staj_event_type::begin_object) { next(ec); if (JSONCONS_UNLIKELY(ec)) {done_ = true;} } else { done_ = true; } } ~staj_object_iterator() noexcept = default; bool has_value() const { return !eptr_; } const value_type& operator*() const { if (JSONCONS_UNLIKELY(eptr_)) { std::rethrow_exception(eptr_); } return *view_->key_value_; } const value_type* operator->() const { if (JSONCONS_UNLIKELY(eptr_)) { std::rethrow_exception(eptr_); } else { return view_->key_value_.operator->(); } } staj_object_iterator& operator++() { next(); return *this; } staj_object_iterator& increment(std::error_code& ec) { next(ec); if (JSONCONS_UNLIKELY(ec)){done_ = true;} return *this; } staj_object_iterator operator++(int) // postfix increment { staj_object_iterator temp(*this); next(); return temp; } friend bool operator==(const staj_object_iterator& a, const staj_object_iterator& b) { return (a.done() && b.done()); } friend bool operator!=(const staj_object_iterator& a, const staj_object_iterator& b) { return !(a == b); } private: bool done() const { return done_; } void next() { if (JSONCONS_UNLIKELY(done_)) { return; } std::error_code ec; next(ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, view_->cursor_->context().line(), view_->cursor_->context().column())); } } void next(std::error_code& ec) { if (JSONCONS_UNLIKELY(done_)) { return; } if (view_->cursor_->done()) { done_ = true; return; } view_->cursor_->next(ec); if (JSONCONS_UNLIKELY(ec)) { done_ = true; return; } if (JSONCONS_UNLIKELY(view_->cursor_->current().event_type() == staj_event_type::end_object)) { done_ = true; return; } JSONCONS_ASSERT(view_->cursor_->current().event_type() == staj_event_type::key); auto key = view_->cursor_->current(). template get(); view_->cursor_->next(ec); if (JSONCONS_UNLIKELY(ec)) { done_ = true; return; } eptr_ = std::exception_ptr(); JSONCONS_TRY { view_->key_value_ = value_type(std::move(key),decode_traits::decode(*view_->cursor_, view_->decoder_, ec)); } JSONCONS_CATCH(const conv_error&) { eptr_ = std::current_exception(); } } }; // staj_object_view template class staj_object_view { friend class staj_object_iterator; public: using char_type = typename Json::char_type; using iterator = staj_object_iterator; using key_type = std::basic_string; using mapped_type = Json; using value_type = std::pair; private: basic_staj_cursor* cursor_; json_decoder decoder_; jsoncons::optional key_value_; public: staj_object_view(basic_staj_cursor& cursor) : cursor_(std::addressof(cursor)) { } iterator begin() { return staj_object_iterator(*this); } iterator end() { return staj_object_iterator(); } }; template ::value,T,basic_json>::type> staj_array_view staj_array(basic_staj_cursor& cursor) { return staj_array_view(cursor); } template ::value,T,basic_json>::type> staj_object_view staj_object(basic_staj_cursor& cursor) { return staj_object_view(cursor); } } // namespace jsoncons #endif // JSONCONS_STAJ_ITERATOR_HPP jsoncons-1.3.2/include/jsoncons/tag_type.hpp000066400000000000000000000154471477700171100211750ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_TAG_TYPE_HPP #define JSONCONS_TAG_TYPE_HPP #include #include #include namespace jsoncons { struct null_type { explicit null_type() = default; }; constexpr null_type null_arg{}; struct temp_allocator_arg_t { explicit temp_allocator_arg_t() = default; }; constexpr temp_allocator_arg_t temp_allocator_arg{}; struct half_arg_t { explicit half_arg_t() = default; }; constexpr half_arg_t half_arg{}; struct json_array_arg_t { explicit json_array_arg_t() = default; }; constexpr json_array_arg_t json_array_arg{}; struct json_object_arg_t { explicit json_object_arg_t() = default; }; constexpr json_object_arg_t json_object_arg{}; struct byte_string_arg_t { explicit byte_string_arg_t() = default; }; constexpr byte_string_arg_t byte_string_arg{}; struct json_const_pointer_arg_t { explicit json_const_pointer_arg_t() = default; }; constexpr json_const_pointer_arg_t json_const_pointer_arg{}; struct json_pointer_arg_t { explicit json_pointer_arg_t() = default; }; constexpr json_pointer_arg_t json_pointer_arg{}; enum class semantic_tag : uint8_t { none = 0, // 00000000 undefined = 1, // 00000001 datetime = 2, // 00000010 epoch_second = 3, // 00000011 epoch_milli = 4, // 00000100 epoch_nano = 5, // 00000101 base16 = 6, // 00000110 base64 = 7, // 00000111 base64url = 8, // 00001000 uri = 9, multi_dim_row_major = 10, multi_dim_column_major = 11, bigint = 12, // 00001100 bigdec = 13, // 00001101 bigfloat = 14, // 00001110 float128 = 15, // 00001111 clamped = 16, ext = 17, id = 18, regex = 19, code = 20 }; inline bool is_number_tag(semantic_tag tag) noexcept { static const uint8_t mask{ uint8_t(semantic_tag::bigint) & uint8_t(semantic_tag::bigdec) & uint8_t(semantic_tag::bigfloat) & uint8_t(semantic_tag::float128) }; return (uint8_t(tag) & mask) == mask; } template std::basic_ostream& operator<<(std::basic_ostream& os, semantic_tag tag) { static constexpr const CharT* na_name = JSONCONS_CSTRING_CONSTANT(CharT, "n/a"); static constexpr const CharT* undefined_name = JSONCONS_CSTRING_CONSTANT(CharT, "undefined"); static constexpr const CharT* datetime_name = JSONCONS_CSTRING_CONSTANT(CharT, "datetime"); static constexpr const CharT* epoch_second_name = JSONCONS_CSTRING_CONSTANT(CharT, "epoch-second"); static constexpr const CharT* epoch_milli_name = JSONCONS_CSTRING_CONSTANT(CharT, "epoch-milli"); static constexpr const CharT* epoch_nano_name = JSONCONS_CSTRING_CONSTANT(CharT, "epoch-nano"); static constexpr const CharT* bigint_name = JSONCONS_CSTRING_CONSTANT(CharT, "bigint"); static constexpr const CharT* bigdec_name = JSONCONS_CSTRING_CONSTANT(CharT, "bigdec"); static constexpr const CharT* bigfloat_name = JSONCONS_CSTRING_CONSTANT(CharT, "bigfloat"); static constexpr const CharT* base16_name = JSONCONS_CSTRING_CONSTANT(CharT, "base16"); static constexpr const CharT* base64_name = JSONCONS_CSTRING_CONSTANT(CharT, "base64"); static constexpr const CharT* base64url_name = JSONCONS_CSTRING_CONSTANT(CharT, "base64url"); static constexpr const CharT* uri_name = JSONCONS_CSTRING_CONSTANT(CharT, "uri"); static constexpr const CharT* clamped_name = JSONCONS_CSTRING_CONSTANT(CharT, "clamped"); static constexpr const CharT* multi_dim_row_major_name = JSONCONS_CSTRING_CONSTANT(CharT, "multi-dim-row-major"); static constexpr const CharT* multi_dim_column_major_name = JSONCONS_CSTRING_CONSTANT(CharT, "multi-dim-column-major"); static constexpr const CharT* ext_name = JSONCONS_CSTRING_CONSTANT(CharT, "ext"); static constexpr const CharT* id_name = JSONCONS_CSTRING_CONSTANT(CharT, "id"); static constexpr const CharT* float128_name = JSONCONS_CSTRING_CONSTANT(CharT, "float128"); static constexpr const CharT* regex_name = JSONCONS_CSTRING_CONSTANT(CharT, "regex"); static constexpr const CharT* code_name = JSONCONS_CSTRING_CONSTANT(CharT, "code"); switch (tag) { case semantic_tag::none: { os << na_name; break; } case semantic_tag::undefined: { os << undefined_name; break; } case semantic_tag::datetime: { os << datetime_name; break; } case semantic_tag::epoch_second: { os << epoch_second_name; break; } case semantic_tag::epoch_milli: { os << epoch_milli_name; break; } case semantic_tag::epoch_nano: { os << epoch_nano_name; break; } case semantic_tag::bigint: { os << bigint_name; break; } case semantic_tag::bigdec: { os << bigdec_name; break; } case semantic_tag::bigfloat: { os << bigfloat_name; break; } case semantic_tag::float128: { os << float128_name; break; } case semantic_tag::base16: { os << base16_name; break; } case semantic_tag::base64: { os << base64_name; break; } case semantic_tag::base64url: { os << base64url_name; break; } case semantic_tag::uri: { os << uri_name; break; } case semantic_tag::clamped: { os << clamped_name; break; } case semantic_tag::multi_dim_row_major: { os << multi_dim_row_major_name; break; } case semantic_tag::multi_dim_column_major: { os << multi_dim_column_major_name; break; } case semantic_tag::ext: { os << ext_name; break; } case semantic_tag::id: { os << id_name; break; } case semantic_tag::regex: { os << regex_name; break; } case semantic_tag::code: { os << code_name; break; } } return os; } } // namespace jsoncons #endif // JSONCONS_TAG_TYPE_HPP jsoncons-1.3.2/include/jsoncons/text_source_adaptor.hpp000066400000000000000000000072711477700171100234330ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_TEXT_SOURCE_ADAPTOR_HPP #define JSONCONS_TEXT_SOURCE_ADAPTOR_HPP #include #include #include // json_errc #include #include namespace jsoncons { // unicode_source_adaptor template class unicode_source_adaptor { public: using value_type = typename Source::value_type; using source_type = Source; private: source_type source_; bool bof_; public: template unicode_source_adaptor(Sourceable&& source) : source_(std::forward(source)), bof_(true) { } bool is_error() const { return source_.is_error(); } bool eof() const { return source_.eof(); } span read_buffer(std::error_code& ec) { if (source_.eof()) { return span(); } auto s = source_.read_buffer(); const value_type* data = s.data(); std::size_t length = s.size(); if (bof_ && length > 0) { auto r = unicode_traits::detect_encoding_from_bom(data, length); if (!(r.encoding == unicode_traits::encoding_kind::utf8 || r.encoding == unicode_traits::encoding_kind::undetected)) { ec = json_errc::illegal_unicode_character; return; } length -= (r.ptr - data); data = r.ptr; bof_ = false; } return span(data, length); } }; // json_source_adaptor template class json_source_adaptor { public: using value_type = typename Source::value_type; using source_type = Source; private: source_type source_; bool bof_; public: template json_source_adaptor(Sourceable&& source) : source_(std::forward(source)), bof_(true) { } bool is_error() const { return source_.is_error(); } bool eof() const { return source_.eof(); } span read_buffer(std::error_code& ec) { if (source_.eof()) { return span(); } auto s = source_.read_buffer(); const value_type* data = s.data(); std::size_t length = s.size(); if (bof_ && length > 0) { auto r = unicode_traits::detect_json_encoding(data, length); if (!(r.encoding == unicode_traits::encoding_kind::utf8 || r.encoding == unicode_traits::encoding_kind::undetected)) { ec = json_errc::illegal_unicode_character; return span(); } length -= (r.ptr - data); data = r.ptr; bof_ = false; } return span(data, length); } }; } // namespace jsoncons #endif // JSONCONS_TEXT_SOURCE_ADAPTOR_HPP jsoncons-1.3.2/include/jsoncons/typed_array_view.hpp000066400000000000000000000214021477700171100227220ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_TYPED_ARRAY_VIEW_HPP #define JSONCONS_TYPED_ARRAY_VIEW_HPP #include // std::array #include #include #include // std::function #include #include #include #include #include #include #include #include #include #include namespace jsoncons { struct uint8_array_arg_t {explicit uint8_array_arg_t() = default; }; constexpr uint8_array_arg_t uint8_array_arg = uint8_array_arg_t(); struct uint16_array_arg_t {explicit uint16_array_arg_t() = default; }; struct uint32_array_arg_t {explicit uint32_array_arg_t() = default; }; constexpr uint32_array_arg_t uint32_array_arg = uint32_array_arg_t(); struct uint64_array_arg_t {explicit uint64_array_arg_t() = default; }; constexpr uint64_array_arg_t uint64_array_arg = uint64_array_arg_t(); struct int8_array_arg_t {explicit int8_array_arg_t() = default; }; constexpr int8_array_arg_t int8_array_arg = int8_array_arg_t(); struct int16_array_arg_t {explicit int16_array_arg_t() = default; }; constexpr int16_array_arg_t int16_array_arg = int16_array_arg_t(); struct int32_array_arg_t {explicit int32_array_arg_t() = default; }; constexpr int32_array_arg_t int32_array_arg = int32_array_arg_t(); struct int64_array_arg_t {explicit int64_array_arg_t() = default; }; constexpr int64_array_arg_t int64_array_arg = int64_array_arg_t(); constexpr uint16_array_arg_t uint16_array_arg = uint16_array_arg_t(); struct half_array_arg_t {explicit half_array_arg_t() = default; }; constexpr half_array_arg_t half_array_arg = half_array_arg_t(); struct float_array_arg_t {explicit float_array_arg_t() = default; }; constexpr float_array_arg_t float_array_arg = float_array_arg_t(); struct double_array_arg_t {explicit double_array_arg_t() = default; }; constexpr double_array_arg_t double_array_arg = double_array_arg_t(); struct float128_array_arg_t {explicit float128_array_arg_t() = default; }; constexpr float128_array_arg_t float128_array_arg = float128_array_arg_t(); enum class typed_array_type{uint8_value=1,uint16_value,uint32_value,uint64_value, int8_value,int16_value,int32_value,int64_value, half_value, float_value,double_value}; class typed_array_view { typed_array_type type_; union { const uint8_t* uint8_data_; const uint16_t* uint16_data_; const uint32_t* uint32_data_; const uint64_t* uint64_data_; const int8_t* int8_data_; const int16_t* int16_data_; const int32_t* int32_data_; const int64_t* int64_data_; const float* float_data_; const double* double_data_; } data_; std::size_t size_{0}; public: typed_array_view() : type_(), data_() { } typed_array_view(const typed_array_view& other) : type_(other.type_), data_(other.data_), size_(other.size()) { } typed_array_view(typed_array_view&& other) noexcept { swap(*this,other); } typed_array_view(const uint8_t* data, std::size_t size) : type_(typed_array_type::uint8_value), size_(size) { data_.uint8_data_ = data; } typed_array_view(const uint16_t* data, std::size_t size) : type_(typed_array_type::uint16_value), size_(size) { data_.uint16_data_ = data; } typed_array_view(const uint32_t* data, std::size_t size) : type_(typed_array_type::uint32_value), size_(size) { data_.uint32_data_ = data; } typed_array_view(const uint64_t* data, std::size_t size) : type_(typed_array_type::uint64_value), size_(size) { data_.uint64_data_ = data; } typed_array_view(const int8_t* data, std::size_t size) : type_(typed_array_type::int8_value), size_(size) { data_.int8_data_ = data; } typed_array_view(const int16_t* data, std::size_t size) : type_(typed_array_type::int16_value), size_(size) { data_.int16_data_ = data; } typed_array_view(const int32_t* data, std::size_t size) : type_(typed_array_type::int32_value), size_(size) { data_.int32_data_ = data; } typed_array_view(const int64_t* data, std::size_t size) : type_(typed_array_type::int64_value), size_(size) { data_.int64_data_ = data; } typed_array_view(half_array_arg_t, const uint16_t* data, std::size_t size) : type_(typed_array_type::half_value), size_(size) { data_.uint16_data_ = data; } typed_array_view(const float* data, std::size_t size) : type_(typed_array_type::float_value), size_(size) { data_.float_data_ = data; } typed_array_view(const double* data, std::size_t size) : type_(typed_array_type::double_value), size_(size) { data_.double_data_ = data; } typed_array_view& operator=(const typed_array_view& other) { typed_array_view temp(other); swap(*this,temp); return *this; } typed_array_type type() const {return type_;} std::size_t size() const { return size_; } jsoncons::span data(uint8_array_arg_t) const { JSONCONS_ASSERT(type_ == typed_array_type::uint8_value); return jsoncons::span(data_.uint8_data_, size_); } jsoncons::span data(uint16_array_arg_t) const { JSONCONS_ASSERT(type_ == typed_array_type::uint16_value); return jsoncons::span(data_.uint16_data_, size_); } jsoncons::span data(uint32_array_arg_t) const { JSONCONS_ASSERT(type_ == typed_array_type::uint32_value); return jsoncons::span(data_.uint32_data_, size_); } jsoncons::span data(uint64_array_arg_t) const { JSONCONS_ASSERT(type_ == typed_array_type::uint64_value); return jsoncons::span(data_.uint64_data_, size_); } jsoncons::span data(int8_array_arg_t) const { JSONCONS_ASSERT(type_ == typed_array_type::int8_value); return jsoncons::span(data_.int8_data_, size_); } jsoncons::span data(int16_array_arg_t) const { JSONCONS_ASSERT(type_ == typed_array_type::int16_value); return jsoncons::span(data_.int16_data_, size_); } jsoncons::span data(int32_array_arg_t) const { JSONCONS_ASSERT(type_ == typed_array_type::int32_value); return jsoncons::span(data_.int32_data_, size_); } jsoncons::span data(int64_array_arg_t) const { JSONCONS_ASSERT(type_ == typed_array_type::int64_value); return jsoncons::span(data_.int64_data_, size_); } jsoncons::span data(half_array_arg_t) const { JSONCONS_ASSERT(type_ == typed_array_type::half_value); return jsoncons::span(data_.uint16_data_, size_); } jsoncons::span data(float_array_arg_t) const { JSONCONS_ASSERT(type_ == typed_array_type::float_value); return jsoncons::span(data_.float_data_, size_); } jsoncons::span data(double_array_arg_t) const { JSONCONS_ASSERT(type_ == typed_array_type::double_value); return jsoncons::span(data_.double_data_, size_); } friend void swap(typed_array_view& a, typed_array_view& b) noexcept { std::swap(a.data_,b.data_); std::swap(a.type_,b.type_); std::swap(a.size_,b.size_); } }; } // namespace jsoncons #endif // JSONCONS_TYPED_ARRAY_VIEW_HPP jsoncons-1.3.2/include/jsoncons/utility/000077500000000000000000000000001477700171100203405ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons/utility/bigint.hpp000066400000000000000000001337511477700171100223370ustar00rootroot00000000000000// Copyright 2018 vDaniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_UTILITY_BIGINT_HPP #define JSONCONS_UTILITY_BIGINT_HPP #include // std::max, std::min, std::reverse #include // assert #include #include // std::fmod #include #include // std::memcpy #include #include // std::numeric_limits #include // std::allocator #include // std::string #include // std::enable_if #include // std::vector #include #include namespace jsoncons { /* This implementation is based on Chapter 2 and Appendix A of Ammeraal, L. (1996) Algorithms and Data Structures in C++, Chichester: John Wiley. */ namespace detail { template class basic_bigint_base { public: using allocator_type = Allocator; using basic_type_allocator_type = typename std::allocator_traits:: template rebind_alloc; private: basic_type_allocator_type alloc_; public: using allocator_traits_type = std::allocator_traits; using stored_allocator_type = allocator_type; using pointer = typename allocator_traits_type::pointer; using value_type = typename allocator_traits_type::value_type; using size_type = std::size_t; using pointer_traits = std::pointer_traits; basic_bigint_base() : alloc_() { } explicit basic_bigint_base(const allocator_type& alloc) : alloc_(basic_type_allocator_type(alloc)) { } basic_type_allocator_type get_allocator() const { return alloc_; } }; } // namespace detail template > class basic_bigint : protected detail::basic_bigint_base { using base_t = detail::basic_bigint_base; static constexpr uint64_t max_short_storage_size = 2; public: using size_type = typename base_t::size_type; using value_type = typename base_t::value_type; using base_t::get_allocator; using bigint_type = basic_bigint; static constexpr uint64_t max_basic_type = (std::numeric_limits::max)(); static constexpr uint64_t basic_type_bits = sizeof(uint64_t) * 8; // Number of bits static constexpr uint64_t basic_type_halfBits = basic_type_bits/2; static constexpr uint16_t word_length = 4; // Use multiples of word_length words static constexpr uint64_t r_mask = (uint64_t(1) << basic_type_halfBits) - 1; static constexpr uint64_t l_mask = max_basic_type - r_mask; static constexpr uint64_t l_bit = max_basic_type - (max_basic_type >> 1); static constexpr uint64_t max_uint64_div_10 = (std::numeric_limits::max)()/10u ; static constexpr uint64_t max_uint64_div_16 = (std::numeric_limits::max)()/16u ; private: struct common_storage { uint8_t is_dynamic_:1; uint8_t is_negative_:1; size_type length_; }; struct short_storage { uint8_t is_dynamic_:1; uint8_t is_negative_:1; size_type length_; uint64_t values_[max_short_storage_size]; short_storage() : is_dynamic_(false), is_negative_(false), length_(0), values_{0,0} { } template short_storage(T n, typename std::enable_if::value && sizeof(T) <= sizeof(int64_t) && std::is_signed::value>::type* = 0) : is_dynamic_(false), is_negative_(n < 0), length_(n == 0 ? 0 : 1) { values_[0] = n < 0 ? (uint64_t(0)-static_cast(n)) : static_cast(n); values_[1] = 0; } template short_storage(T n, typename std::enable_if::value && sizeof(T) <= sizeof(int64_t) && !std::is_signed::value>::type* = 0) : is_dynamic_(false), is_negative_(false), length_(n == 0 ? 0 : 1) { values_[0] = n; values_[1] = 0; } template short_storage(T n, typename std::enable_if::value && sizeof(int64_t) < sizeof(T) && std::is_signed::value>::type* = 0) : is_dynamic_(false), is_negative_(n < 0), length_(n == 0 ? 0 : max_short_storage_size) { using unsigned_type = typename std::make_unsigned::type; auto u = n < 0 ? (unsigned_type(0)-static_cast(n)) : static_cast(n); values_[0] = uint64_t(u & max_basic_type);; u >>= basic_type_bits; values_[1] = uint64_t(u & max_basic_type);; } template short_storage(T n, typename std::enable_if::value && sizeof(int64_t) < sizeof(T) && !std::is_signed::value>::type* = 0) : is_dynamic_(false), is_negative_(false), length_(n == 0 ? 0 : max_short_storage_size) { values_[0] = uint64_t(n & max_basic_type);; n >>= basic_type_bits; values_[1] = uint64_t(n & max_basic_type);; } short_storage(const short_storage& stor) : is_dynamic_(false), is_negative_(stor.is_negative_), length_(stor.length_) { values_[0] = stor.values_[0]; values_[1] = stor.values_[1]; } short_storage& operator=(const short_storage& stor) = delete; short_storage& operator=(short_storage&& stor) = delete; }; struct dynamic_storage { using real_allocator_type = typename std::allocator_traits:: template rebind_alloc; using pointer = typename std::allocator_traits::pointer; uint8_t is_dynamic_:1; uint8_t is_negative_:1; size_type length_{0}; size_type capacity_{0}; pointer data_{nullptr}; dynamic_storage() : is_dynamic_(true), is_negative_(false) { } dynamic_storage(const dynamic_storage& stor, real_allocator_type alloc) : is_dynamic_(true), is_negative_(stor.is_negative_), length_(stor.length_), capacity_(round_up(stor.length_)) { data_ = std::allocator_traits::allocate(alloc, capacity_); JSONCONS_TRY { std::allocator_traits::construct(alloc, extension_traits::to_plain_pointer(data_)); } JSONCONS_CATCH(...) { std::allocator_traits::deallocate(alloc, data_, capacity_); JSONCONS_RETHROW; } JSONCONS_ASSERT(stor.data_ != nullptr); std::memcpy(data_, stor.data_, size_type(stor.length_*sizeof(uint64_t))); } dynamic_storage(dynamic_storage&& stor) noexcept : is_dynamic_(true), is_negative_(stor.is_negative_), length_(stor.length_), capacity_(stor.capacity_), data_(stor.data_) { stor.length_ = 0; stor.capacity_ = 0; stor.data_ = nullptr; } void destroy(const real_allocator_type& a) noexcept { if (data_ != nullptr) { real_allocator_type alloc(a); std::allocator_traits::destroy(alloc, extension_traits::to_plain_pointer(data_)); std::allocator_traits::deallocate(alloc, data_,capacity_); } } void reserve(size_type n, const real_allocator_type& a) { real_allocator_type alloc(a); size_type capacity_new = round_up(n); uint64_t* data_old = data_; data_ = std::allocator_traits::allocate(alloc, capacity_new); if (length_ > 0) { std::memcpy( data_, data_old, size_type(length_*sizeof(uint64_t))); } if (capacity_ > 0 && data_ != nullptr) { std::allocator_traits::deallocate(alloc, data_old, capacity_); } capacity_ = capacity_new; } // Find suitable new block size constexpr size_type round_up(size_type i) const noexcept { return (i/word_length + 1) * word_length; } }; union { common_storage common_stor_; short_storage short_stor_; dynamic_storage dynamic_stor_; }; public: basic_bigint() { ::new (&short_stor_) short_storage(); } explicit basic_bigint(const Allocator& alloc) : base_t(alloc) { ::new (&short_stor_) short_storage(); } basic_bigint(const basic_bigint& n) : base_t(n.get_allocator()) { if (!n.is_dynamic()) { ::new (&short_stor_) short_storage(n.short_stor_); } else { ::new (&dynamic_stor_) dynamic_storage(n.dynamic_stor_, get_allocator()); } } basic_bigint(basic_bigint&& other) noexcept : base_t(other.get_allocator()) { if (!other.is_dynamic()) { ::new (&short_stor_) short_storage(other.short_stor_); } else { ::new (&dynamic_stor_) dynamic_storage(std::move(other.dynamic_stor_)); } } template basic_bigint(Integer n, typename std::enable_if::value>::type* = 0) { ::new (&short_stor_) short_storage(n); } ~basic_bigint() noexcept { destroy(); } constexpr bool is_dynamic() const { return common_stor_.is_dynamic_; } constexpr size_type length() const { return common_stor_.length_; } constexpr size_type capacity() const { return is_dynamic() ? dynamic_stor_.capacity_ : max_short_storage_size; } bool is_negative() const { return common_stor_.is_negative_; } void is_negative(bool value) { common_stor_.is_negative_ = value; } const uint64_t* data() const { const uint64_t* p = is_dynamic() ? dynamic_stor_.data_ : short_stor_.values_; JSONCONS_ASSERT(p != nullptr); return p; } uint64_t* data() { uint64_t* p = is_dynamic() ? dynamic_stor_.data_ : short_stor_.values_; JSONCONS_ASSERT(p != nullptr); return p; } template static basic_bigint from_string(const std::basic_string& s) { return from_string(s.data(), s.length()); } template static basic_bigint from_string(const CharT* s) { return from_string(s, std::char_traits::length(s)); } template static basic_bigint from_string(const CharT* data, size_type length) { bool neg; if (*data == '-') { neg = true; data++; --length; } else { neg = false; } basic_bigint v = 0; for (size_type i = 0; i < length; i++) { CharT c = data[i]; switch (c) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': v = (v * 10u) + (uint64_t)(c - '0'); break; default: JSONCONS_THROW(std::runtime_error(std::string("Invalid digit ") + "\'" + (char)c + "\'")); } } if (neg) { v.common_stor_.is_negative_ = true; } return v; } template static basic_bigint from_string_radix(const CharT* data, size_type length, uint8_t radix) { if (!(radix >= 2 && radix <= 16u)) { JSONCONS_THROW(std::runtime_error("Unsupported radix")); } bool neg; if (*data == '-') { neg = true; data++; --length; } else { neg = false; } basic_bigint v = 0; for (size_type i = 0; i < length; i++) { CharT c = data[i]; uint64_t d; switch (c) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': d = (uint64_t)(c - '0'); break; case 'a':case 'b':case 'c':case 'd':case 'e':case 'f': d = (uint64_t)(c - ('a' - 10u)); break; case 'A':case 'B':case 'C':case 'D':case 'E':case 'F': d = (uint64_t)(c - ('A' - 10u)); break; default: JSONCONS_THROW(std::runtime_error(std::string("Invalid digit in radix ") + std::to_string(radix) + ": \'" + (char)c + "\'")); } if (d >= radix) { JSONCONS_THROW(std::runtime_error(std::string("Invalid digit in radix ") + std::to_string(radix) + ": \'" + (char)c + "\'")); } v = (v * radix) + d; } if ( neg ) { v.common_stor_.is_negative_ = true; } return v; } static basic_bigint from_bytes_be(int signum, const uint8_t* str, std::size_t n) { static const double radix_log2 = std::log2(next_power_of_two(256)); // Estimate how big the result will be, so we can pre-allocate it. double bits = radix_log2 * n; double big_digits = std::ceil(bits / 64.0); //std::cout << "ESTIMATED: " << big_digits << "\n"; bigint_type v = 0; v.reserve(static_cast(big_digits)); if (n > 0) { for (std::size_t i = 0; i < n; i++) { v = (v * 256) + (uint64_t)(str[i]); } } //std::cout << "ACTUAL: " << v.length() << "\n"; if (signum < 0) { v.common_stor_.is_negative_ = true; } return v; } uint64_t* begin() { return is_dynamic() ? dynamic_stor_.data_ : short_stor_.values_; } const uint64_t* begin() const { return is_dynamic() ? dynamic_stor_.data_ : short_stor_.values_; } uint64_t* end() { return begin() + length(); } const uint64_t* end() const { return begin() + length(); } void resize(size_type new_length) { size_type old_length = common_stor_.length_; reserve(new_length); common_stor_.length_ = new_length; if (old_length < new_length) { if (is_dynamic()) { std::memset(dynamic_stor_.data_+old_length, 0, size_type((new_length-old_length)*sizeof(uint64_t))); } else { JSONCONS_ASSERT(new_length <= max_short_storage_size); for (size_type i = old_length; i < max_short_storage_size; ++i) { short_stor_.values_[i] = 0; } } } } void reserve(size_type n) { if (capacity() < n) { if (!is_dynamic()) { size_type size = short_stor_.length_; size_type is_neg = short_stor_.is_negative_; uint64_t values[max_short_storage_size] = {short_stor_.values_[0], short_stor_.values_[1]}; ::new (&dynamic_stor_) dynamic_storage(); dynamic_stor_.reserve(n, get_allocator()); dynamic_stor_.length_ = size; dynamic_stor_.is_negative_ = is_neg; dynamic_stor_.data_[0] = values[0]; dynamic_stor_.data_[1] = values[1]; } else { dynamic_stor_.reserve(n, get_allocator()); } } } // operators bool operator!() const { return length() == 0 ? true : false; } basic_bigint operator-() const { basic_bigint v(*this); v.common_stor_.is_negative_ = !v.is_negative(); return v; } basic_bigint& operator=( const basic_bigint& y ) { if ( this != &y ) { resize( y.length() ); common_stor_.is_negative_ = y.is_negative(); if ( y.length() > 0 ) { std::memcpy( data(), y.data(), size_type(y.length()*sizeof(uint64_t)) ); } } return *this; } basic_bigint& operator+=( const basic_bigint& y ) { const uint64_t* y_data = y.data(); if ( is_negative() != y.is_negative() ) return *this -= -y; uint64_t d; uint64_t carry = 0; resize( (std::max)(y.length(), length()) + 1 ); uint64_t* this_data = data(); for (size_type i = 0; i < length(); i++ ) { if ( i >= y.length() && carry == 0 ) break; d = this_data[i] + carry; carry = d < carry; if ( i < y.length() ) { this_data[i] = d + y_data[i]; if ( this_data[i] < d ) carry = 1; } else this_data[i] = d; } reduce(); return *this; } basic_bigint& operator-=( const basic_bigint& y ) { const uint64_t* y_data = y.data(); if ( is_negative() != y.is_negative() ) return *this += -y; if ( (!is_negative() && y > *this) || (is_negative() && y < *this) ) return *this = -(y - *this); uint64_t borrow = 0; uint64_t d; for (size_type i = 0; i < length(); i++ ) { if ( i >= y.length() && borrow == 0 ) break; d = data()[i] - borrow; borrow = d > data()[i]; if ( i < y.length()) { data()[i] = d - y_data[i]; if ( data()[i] > d ) borrow = 1; } else data()[i] = d; } reduce(); return *this; } basic_bigint& operator*=( int64_t y ) { *this *= uint64_t(y < 0 ? -y : y); if ( y < 0 ) common_stor_.is_negative_ = !is_negative(); return *this; } basic_bigint& operator*=( uint64_t y ) { size_type len0 = length(); uint64_t hi; uint64_t lo; uint64_t dig = data()[0]; uint64_t carry = 0; resize( length() + 1 ); uint64_t* this_data = data(); size_type i = 0; for (i = 0; i < len0; i++ ) { DDproduct( dig, y, hi, lo ); this_data[i] = lo + carry; dig = this_data[i+1]; carry = hi + (this_data[i] < lo); } this_data[i] = carry; reduce(); return *this; } basic_bigint& operator*=(const basic_bigint& y) { const uint64_t* y_data = y.data(); if ( length() == 0 || y.length() == 0 ) return *this = 0; bool difSigns = is_negative() != y.is_negative(); if ( length() + y.length() == max_short_storage_size ) // length() = y.length() = 1 { uint64_t a = data()[0], b = y_data[0]; data()[0] = a * b; if ( data()[0] / a != b ) { resize( max_short_storage_size ); DDproduct( a, b, data()[1], data()[0] ); } common_stor_.is_negative_ = difSigns; return *this; } if ( length() == 1 ) // && y.length() > 1 { uint64_t digit = data()[0]; *this = y; *this *= digit; } else { if ( y.length() == 1 ) *this *= y_data[0]; else { size_type lenProd = length() + y.length(), jA, jB; uint64_t sumHi = 0, sumLo, hi, lo, sumLo_old, sumHi_old, carry=0; basic_bigint x = *this; const uint64_t* x_data = x.data(); resize( lenProd ); // Give *this length lenProd uint64_t* this_data = data(); for (size_type i = 0; i < lenProd; i++ ) { sumLo = sumHi; sumHi = carry; carry = 0; for ( jA=0; jA < x.length(); jA++ ) { jB = i - jA; if ( jB >= 0 && jB < y.length() ) { DDproduct( x_data[jA], y_data[jB], hi, lo ); sumLo_old = sumLo; sumHi_old = sumHi; sumLo += lo; if ( sumLo < sumLo_old ) sumHi++; sumHi += hi; carry += (sumHi < sumHi_old); } } this_data[i] = sumLo; } } } reduce(); common_stor_.is_negative_ = difSigns; return *this; } basic_bigint& operator/=( const basic_bigint& divisor ) { basic_bigint r; divide( divisor, *this, r, false ); return *this; } basic_bigint& operator%=( const basic_bigint& divisor ) { basic_bigint q; divide( divisor, q, *this, true ); return *this; } basic_bigint& operator<<=( uint64_t k ) { size_type q = size_type(k / basic_type_bits); if ( q ) // Increase common_stor_.length_ by q: { resize(length() + q); uint64_t* this_data = data(); for (size_type i = length(); i-- > 0; ) this_data[i] = ( i < q ? 0 : this_data[i - q]); k %= basic_type_bits; } if ( k ) // 0 < k < basic_type_bits: { uint64_t k1 = basic_type_bits - k; uint64_t mask = (uint64_t(1) << k) - uint64_t(1); resize( length() + 1 ); uint64_t* this_data = data(); for (size_type i = length(); i-- > 0; ) { this_data[i] <<= k; if ( i > 0 ) this_data[i] |= (this_data[i-1] >> k1) & mask; } } reduce(); return *this; } basic_bigint& operator>>=(uint64_t k) { size_type q = size_type(k / basic_type_bits); if ( q >= length() ) { resize( 0 ); return *this; } if (q > 0) { memmove( data(), data()+q, size_type((length() - q)*sizeof(uint64_t)) ); resize( size_type(length() - q) ); k %= basic_type_bits; if ( k == 0 ) { reduce(); return *this; } } uint64_t* this_data = data(); size_type n = size_type(length() - 1); int64_t k1 = basic_type_bits - k; uint64_t mask = (uint64_t(1) << k) - 1; for (size_type i = 0; i <= n; i++) { this_data[i] >>= k; if ( i < n ) this_data[i] |= ((this_data[i+1] & mask) << k1); } reduce(); return *this; } basic_bigint& operator++() { *this += 1; return *this; } basic_bigint operator++(int) { basic_bigint old = *this; ++(*this); return old; } basic_bigint& operator--() { *this -= 1; return *this; } basic_bigint operator--(int) { basic_bigint old = *this; --(*this); return old; } basic_bigint& operator|=( const basic_bigint& a ) { if ( length() < a.length() ) { resize( a.length() ); } const uint64_t* qBegin = a.begin(); const uint64_t* q = a.end() - 1; uint64_t* p = begin() + a.length() - 1; while ( q >= qBegin ) { *p-- |= *q--; } reduce(); return *this; } basic_bigint& operator^=( const basic_bigint& a ) { if ( length() < a.length() ) { resize( a.length() ); } const uint64_t* qBegin = a.begin(); const uint64_t* q = a.end() - 1; uint64_t* p = begin() + a.length() - 1; while ( q >= qBegin ) { *p-- ^= *q--; } reduce(); return *this; } basic_bigint& operator&=( const basic_bigint& a ) { size_type old_length = length(); resize( (std::min)( length(), a.length() ) ); const uint64_t* pBegin = begin(); uint64_t* p = end() - 1; const uint64_t* q = a.begin() + length() - 1; while ( p >= pBegin ) { *p-- &= *q--; } const size_type new_length = length(); if ( old_length > new_length ) { if (is_dynamic()) { std::memset( dynamic_stor_.data_ + new_length, 0, size_type(old_length - new_length*sizeof(uint64_t)) ); } else { JSONCONS_ASSERT(new_length <= max_short_storage_size); for (size_type i = new_length; i < max_short_storage_size; ++i) { short_stor_.values_[i] = 0; } } } reduce(); return *this; } explicit operator bool() const { return length() != 0 ? true : false; } explicit operator int64_t() const { int64_t x = 0; if ( length() > 0 ) { x = static_cast(data()[0]); } return is_negative() ? -x : x; } explicit operator uint64_t() const { uint64_t u = 0; if ( length() > 0 ) { u = data() [0]; } return u; } explicit operator double() const { double x = 0.0; double factor = 1.0; double values = (double)max_basic_type + 1.0; const uint64_t* p = begin(); const uint64_t* pEnd = end(); while ( p < pEnd ) { x += *p*factor; factor *= values; ++p; } return is_negative() ? -x : x; } explicit operator long double() const { long double x = 0.0; long double factor = 1.0; long double values = (long double)max_basic_type + 1.0; const uint64_t* p = begin(); const uint64_t* pEnd = end(); while ( p < pEnd ) { x += *p*factor; factor *= values; ++p; } return is_negative() ? -x : x; } template void write_bytes_be(int& signum, std::vector& data) const { basic_bigint n(*this); signum = (n < 0) ? -1 : (n > 0 ? 1 : 0); basic_bigint divisor(256); while (n >= 256) { basic_bigint q; basic_bigint r; n.divide(divisor, q, r, true); n = q; data.push_back((uint8_t)(uint64_t)r); } if (n >= 0) { data.push_back((uint8_t)(uint64_t)n); } std::reverse(data.begin(),data.end()); } std::string to_string() const { std::string s; write_string(s); return s; } template void write_string(std::basic_string& data) const { basic_bigint v(*this); std::size_t len = (v.length() * basic_type_bits / 3) + 2; data.reserve(len); static uint64_t p10 = 1; static uint64_t ip10 = 0; if ( v.length() == 0 ) { data.push_back('0'); } else { uint64_t r; if ( p10 == 1 ) { while ( p10 <= max_uint64_div_10) { p10 *= 10u; ip10++; } } // p10 is max unsigned power of 10 basic_bigint R; basic_bigint LP10 = p10; // LP10 = p10 = ::pow(10, ip10) do { v.divide( LP10, v, R, true ); r = (R.length() ? R.data()[0] : 0); for ( size_type j=0; j < ip10; j++ ) { data.push_back(char(r % 10u + '0')); r /= 10u; if ( r + v.length() == 0 ) break; } } while ( v.length() ); if (is_negative()) { data.push_back('-'); } std::reverse(data.begin(),data.end()); } } std::string to_string_hex() const { std::string s; write_string_hex(s); return s; } template void write_string_hex(std::basic_string& data) const { basic_bigint v(*this); std::size_t len = (v.length() * basic_bigint::basic_type_bits / 3) + 2; data.reserve(len); // 1/3 > ln(2)/ln(10) static uint64_t p10 = 1; static uint64_t ip10 = 0; if ( v.length() == 0 ) { data.push_back('0'); } else { uint64_t r; if ( p10 == 1 ) { while ( p10 <= max_uint64_div_16) { p10 *= 16u; ip10++; } } // p10 is max unsigned power of 16 basic_bigint R; basic_bigint LP10 = p10; // LP10 = p10 = ::pow(16, ip10) do { v.divide( LP10, v, R, true ); r = (R.length() ? R.data()[0] : 0); for ( size_type j=0; j < ip10; j++ ) { uint8_t c = r % 16u; data.push_back((c < 10u) ? ('0' + c) : ('A' - 10u + c)); r /= 16u; if ( r + v.length() == 0 ) break; } } while (v.length()); if (is_negative()) { data.push_back('-'); } std::reverse(data.begin(),data.end()); } } // Global Operators friend bool operator==( const basic_bigint& x, const basic_bigint& y ) noexcept { return x.compare(y) == 0 ? true : false; } friend bool operator==( const basic_bigint& x, int y ) noexcept { return x.compare(y) == 0 ? true : false; } friend bool operator!=( const basic_bigint& x, const basic_bigint& y ) noexcept { return x.compare(y) != 0 ? true : false; } friend bool operator!=( const basic_bigint& x, int y ) noexcept { return x.compare(basic_bigint(y)) != 0 ? true : false; } friend bool operator<( const basic_bigint& x, const basic_bigint& y ) noexcept { return x.compare(y) < 0 ? true : false; } friend bool operator<( const basic_bigint& x, int64_t y ) noexcept { return x.compare(y) < 0 ? true : false; } friend bool operator>( const basic_bigint& x, const basic_bigint& y ) noexcept { return x.compare(y) > 0 ? true : false; } friend bool operator>( const basic_bigint& x, int y ) noexcept { return x.compare(basic_bigint(y)) > 0 ? true : false; } friend bool operator<=( const basic_bigint& x, const basic_bigint& y ) noexcept { return x.compare(y) <= 0 ? true : false; } friend bool operator<=( const basic_bigint& x, int y ) noexcept { return x.compare(y) <= 0 ? true : false; } friend bool operator>=( const basic_bigint& x, const basic_bigint& y ) noexcept { return x.compare(y) >= 0 ? true : false; } friend bool operator>=( const basic_bigint& x, int y ) noexcept { return x.compare(y) >= 0 ? true : false; } friend basic_bigint operator+( basic_bigint x, const basic_bigint& y ) { return x += y; } friend basic_bigint operator+( basic_bigint x, int64_t y ) { return x += y; } friend basic_bigint operator-( basic_bigint x, const basic_bigint& y ) { return x -= y; } friend basic_bigint operator-( basic_bigint x, int64_t y ) { return x -= y; } friend basic_bigint operator*( int64_t x, const basic_bigint& y ) { return basic_bigint(y) *= x; } friend basic_bigint operator*( basic_bigint x, const basic_bigint& y ) { return x *= y; } friend basic_bigint operator*( basic_bigint x, int64_t y ) { return x *= y; } friend basic_bigint operator/( basic_bigint x, const basic_bigint& y ) { return x /= y; } friend basic_bigint operator/( basic_bigint x, int y ) { return x /= y; } friend basic_bigint operator%( basic_bigint x, const basic_bigint& y ) { return x %= y; } friend basic_bigint operator<<( basic_bigint u, unsigned k ) { return u <<= k; } friend basic_bigint operator<<( basic_bigint u, int k ) { return u <<= k; } friend basic_bigint operator>>( basic_bigint u, unsigned k ) { return u >>= k; } friend basic_bigint operator>>( basic_bigint u, int k ) { return u >>= k; } friend basic_bigint operator|( basic_bigint x, const basic_bigint& y ) { return x |= y; } friend basic_bigint operator|( basic_bigint x, int y ) { return x |= y; } friend basic_bigint operator|( basic_bigint x, unsigned y ) { return x |= y; } friend basic_bigint operator^( basic_bigint x, const basic_bigint& y ) { return x ^= y; } friend basic_bigint operator^( basic_bigint x, int y ) { return x ^= y; } friend basic_bigint operator^( basic_bigint x, unsigned y ) { return x ^= y; } friend basic_bigint operator&( basic_bigint x, const basic_bigint& y ) { return x &= y; } friend basic_bigint operator&( basic_bigint x, int y ) { return x &= y; } friend basic_bigint operator&( basic_bigint x, unsigned y ) { return x &= y; } friend basic_bigint abs( const basic_bigint& a ) { if ( a.is_negative() ) { return -a; } return a; } friend basic_bigint power( basic_bigint x, unsigned n ) { basic_bigint y = 1; while ( n ) { if ( n & 1 ) { y *= x; } x *= x; n >>= 1; } return y; } friend basic_bigint sqrt( const basic_bigint& a ) { basic_bigint x = a; basic_bigint b = a; basic_bigint q; b <<= 1; while ( (void)(b >>= 2), b > 0 ) { x >>= 1; } while ( x > (q = a/x) + 1 || x < q - 1 ) { x += q; x >>= 1; } return x < q ? x : q; } template friend std::basic_ostream& operator<<(std::basic_ostream& os, const basic_bigint& v) { std::basic_string s; v.write_string(s); os << s; return os; } int compare( const basic_bigint& y ) const noexcept { const uint64_t* y_data = y.data(); if ( is_negative() != y.is_negative() ) return y.is_negative() - is_negative(); int code = 0; if ( length() == 0 && y.length() == 0 ) code = 0; else if ( length() < y.length() ) code = -1; else if ( length() > y.length() ) code = +1; else { for (size_type i = length(); i-- > 0; ) { if (data()[i] > y_data[i]) { code = 1; break; } else if (data()[i] < y_data[i]) { code = -1; break; } } } return is_negative() ? -code : code; } void divide( basic_bigint denom, basic_bigint& quot, basic_bigint& rem, bool remDesired ) const { if ( denom.length() == 0 ) { JSONCONS_THROW(std::runtime_error( "Zero divide." )); } bool quot_neg = is_negative() ^ denom.is_negative(); bool rem_neg = is_negative(); int x = 0; basic_bigint num = *this; num.common_stor_.is_negative_ = denom.common_stor_.is_negative_ = false; if ( num < denom ) { quot = uint64_t(0); rem = num; rem.common_stor_.is_negative_ = rem_neg; return; } if ( denom.length() == 1 && num.length() == 1 ) { quot = uint64_t( num.data()[0]/denom.data()[0] ); rem = uint64_t( num.data()[0]%denom.data()[0] ); quot.common_stor_.is_negative_ = quot_neg; rem.common_stor_.is_negative_ = rem_neg; return; } else if (denom.length() == 1 && (denom.data()[0] & l_mask) == 0 ) { // Denominator fits into a half word uint64_t divisor = denom.data()[0], dHi = 0, q1, r, q2, dividend; quot.resize(length()); for (size_type i=length(); i-- > 0; ) { dividend = (dHi << basic_type_halfBits) | (data()[i] >> basic_type_halfBits); q1 = dividend/divisor; r = dividend % divisor; dividend = (r << basic_type_halfBits) | (data()[i] & r_mask); q2 = dividend/divisor; dHi = dividend % divisor; quot.data()[i] = (q1 << basic_type_halfBits) | q2; } quot.reduce(); rem = dHi; quot.common_stor_.is_negative_ = quot_neg; rem.common_stor_.is_negative_ = rem_neg; return; } basic_bigint num0 = num, denom0 = denom; int second_done = normalize(denom, num, x); size_type l = denom.length() - 1; size_type n = num.length() - 1; quot.resize(n - l); for (size_type i=quot.length(); i-- > 0; ) quot.data()[i] = 0; rem = num; if ( rem.data()[n] >= denom.data()[l] ) { rem.resize(rem.length() + 1); n++; quot.resize(quot.length() + 1); } uint64_t d = denom.data()[l]; for ( size_type k = n; k > l; k-- ) { uint64_t q = DDquotient(rem.data()[k], rem.data()[k-1], d); subtractmul( rem.data() + k - l - 1, denom.data(), l + 1, q ); quot.data()[k - l - 1] = q; } quot.reduce(); quot.common_stor_.is_negative_ = quot_neg; if ( remDesired ) { unnormalize(rem, x, second_done); rem.common_stor_.is_negative_ = rem_neg; } } private: void destroy() noexcept { if (is_dynamic()) { dynamic_stor_.destroy(get_allocator()); } } void DDproduct( uint64_t A, uint64_t B, uint64_t& hi, uint64_t& lo ) const // Multiplying two digits: (hi, lo) = A * B { uint64_t hiA = A >> basic_type_halfBits, loA = A & r_mask, hiB = B >> basic_type_halfBits, loB = B & r_mask, mid1, mid2, old; lo = loA * loB; hi = hiA * hiB; mid1 = loA * hiB; mid2 = hiA * loB; old = lo; lo += mid1 << basic_type_halfBits; hi += (lo < old) + (mid1 >> basic_type_halfBits); old = lo; lo += mid2 << basic_type_halfBits; hi += (lo < old) + (mid2 >> basic_type_halfBits); } uint64_t DDquotient( uint64_t A, uint64_t B, uint64_t d ) const // Divide double word (A, B) by d. Quotient = (qHi, qLo) { uint64_t left, middle, right, qHi, qLo, x, dLo1, dHi = d >> basic_type_halfBits, dLo = d & r_mask; qHi = A/(dHi + 1); // This initial guess of qHi may be too small. middle = qHi * dLo; left = qHi * dHi; x = B - (middle << basic_type_halfBits); A -= (middle >> basic_type_halfBits) + left + (x > B); B = x; dLo1 = dLo << basic_type_halfBits; // Increase qHi if necessary: while ( A > dHi || (A == dHi && B >= dLo1) ) { x = B - dLo1; A -= dHi + (x > B); B = x; qHi++; } qLo = ((A << basic_type_halfBits) | (B >> basic_type_halfBits))/(dHi + 1); // This initial guess of qLo may be too small. right = qLo * dLo; middle = qLo * dHi; x = B - right; A -= (x > B); B = x; x = B - (middle << basic_type_halfBits); A -= (middle >> basic_type_halfBits) + (x > B); B = x; // Increase qLo if necessary: while ( A || B >= d ) { x = B - d; A -= (x > B); B = x; qLo++; } return (qHi << basic_type_halfBits) + qLo; } void subtractmul( uint64_t* a, uint64_t* b, size_type n, uint64_t& q ) const // a -= q * b: b in n positions; correct q if necessary { uint64_t hi, lo, d, carry = 0; size_type i; for ( i = 0; i < n; i++ ) { DDproduct( b[i], q, hi, lo ); d = a[i]; a[i] -= lo; if ( a[i] > d ) carry++; d = a[i + 1]; a[i + 1] -= hi + carry; carry = a[i + 1] > d; } if ( carry ) // q was too large { q--; carry = 0; for ( i = 0; i < n; i++ ) { d = a[i] + carry; carry = d < carry; a[i] = d + b[i]; if ( a[i] < d ) carry = 1; } a[n] = 0; } } int normalize( basic_bigint& denom, basic_bigint& num, int& x ) const { size_type r = denom.length() - 1; uint64_t y = denom.data()[r]; x = 0; while ( (y & l_bit) == 0 ) { y <<= 1; x++; } denom <<= x; num <<= x; if ( r > 0 && denom.data()[r] < denom.data()[r-1] ) { denom *= max_basic_type; num *= max_basic_type; return 1; } return 0; } void unnormalize( basic_bigint& rem, int x, int secondDone ) const { if ( secondDone ) { rem /= max_basic_type; } if ( x > 0 ) { rem >>= x; } else { rem.reduce(); } } size_type round_up(size_type i) const // Find suitable new block size { return (i/word_length + 1) * word_length; } void reduce() { uint64_t* p = end() - 1; uint64_t* pBegin = begin(); while ( p >= pBegin ) { if ( *p ) { break; } --common_stor_.length_; --p; } if ( length() == 0 ) { common_stor_.is_negative_ = false; } } static uint64_t next_power_of_two(uint64_t n) { n = n - 1; n |= n >> 1u; n |= n >> 2u; n |= n >> 4u; n |= n >> 8u; n |= n >> 16u; n |= n >> 32u; return n + 1; } }; using bigint = basic_bigint>; } // namespace jsoncons #endif // JSONCONS_UTILITY_BIGINT_HPP jsoncons-1.3.2/include/jsoncons/utility/binary.hpp000066400000000000000000000141671477700171100223460ustar00rootroot00000000000000#ifndef JSONCONS_UTILITY_BINARY_HPP #define JSONCONS_UTILITY_BINARY_HPP #include #include #include #include #include // std::memcpy #include // std::enable_if #include namespace jsoncons { namespace binary { // byte_swap template typename std::enable_if::value && sizeof(T) == sizeof(uint8_t),T>::type byte_swap(T val) { return val; } template typename std::enable_if::value && sizeof(T) == sizeof(uint16_t),T>::type byte_swap(T val) { #if defined(JSONCONS_BYTE_SWAP_16) return JSONCONS_BYTE_SWAP_16(val); #else return (static_cast(val) >> 8) | (static_cast(val) << 8); #endif } template typename std::enable_if::value && sizeof(T) == sizeof(uint32_t),T>::type byte_swap(T val) { #if defined(JSONCONS_BYTE_SWAP_32) return JSONCONS_BYTE_SWAP_32(val); #else uint32_t tmp = ((static_cast(val) << 8) & 0xff00ff00) | ((static_cast(val) >> 8) & 0xff00ff); return (tmp << 16) | (tmp >> 16); #endif } template typename std::enable_if::value && sizeof(T) == sizeof(uint64_t),T>::type byte_swap(T val) { #if defined(JSONCONS_BYTE_SWAP_64) return JSONCONS_BYTE_SWAP_64(val); #else uint64_t tmp = ((static_cast(val) & 0x00000000ffffffffull) << 32) | ((static_cast(val) & 0xffffffff00000000ull) >> 32); tmp = ((tmp & 0x0000ffff0000ffffull) << 16) | ((tmp & 0xffff0000ffff0000ull) >> 16); return ((tmp & 0x00ff00ff00ff00ffull) << 8) | ((tmp & 0xff00ff00ff00ff00ull) >> 8); #endif } template typename std::enable_if::value && sizeof(T) == sizeof(uint32_t),T>::type byte_swap(T val) { uint32_t x; std::memcpy(&x,&val,sizeof(uint32_t)); uint32_t y = byte_swap(x); T val2; std::memcpy(&val2,&y,sizeof(uint32_t)); return val2; } template typename std::enable_if::value && sizeof(T) == sizeof(uint64_t),T>::type byte_swap(T val) { uint64_t x; std::memcpy(&x,&val,sizeof(uint64_t)); uint64_t y = byte_swap(x); T val2; std::memcpy(&val2,&y,sizeof(uint64_t)); return val2; } struct uint128_holder { uint64_t lo; uint64_t hi; }; template typename std::enable_if::value && sizeof(T) == 2*sizeof(uint64_t),T>::type byte_swap(T val) { uint128_holder x; uint8_t buf[2*sizeof(uint64_t)]; std::memcpy(buf,&val,2*sizeof(uint64_t)); std::memcpy(&x.lo,buf,sizeof(uint64_t)); std::memcpy(&x.hi,buf+sizeof(uint64_t),sizeof(uint64_t)); uint128_holder y; y.lo = byte_swap(x.hi); y.hi = byte_swap(x.lo); T val2; std::memcpy(&val2,&y,2*sizeof(uint64_t)); return val2; } // native_to_big template typename std::enable_if::type native_to_big(T val, OutputIt d_first) { uint8_t buf[sizeof(T)]; std::memcpy(buf, &val, sizeof(T)); for (auto item : buf) { *d_first++ = item; } } template typename std::enable_if::type native_to_big(T val, OutputIt d_first) { T val2 = byte_swap(val); uint8_t buf[sizeof(T)]; std::memcpy(buf, &val2, sizeof(T)); for (auto item : buf) { *d_first++ = item; } } // native_to_little template typename std::enable_if::type native_to_little(T val, OutputIt d_first) { uint8_t buf[sizeof(T)]; std::memcpy(buf, &val, sizeof(T)); for (auto item : buf) { *d_first++ = item; } } template typename std::enable_if::type native_to_little(T val, OutputIt d_first) { T val2 = byte_swap(val); uint8_t buf[sizeof(T)]; std::memcpy(buf, &val2, sizeof(T)); for (auto item : buf) { *d_first++ = item; } } // big_to_native template typename std::enable_if::type big_to_native(const uint8_t* first, std::size_t count) { if (sizeof(T) > count) { return T{}; } T val; std::memcpy(&val,first,sizeof(T)); return val; } template typename std::enable_if::type big_to_native(const uint8_t* first, std::size_t count) { if (sizeof(T) > count) { return T{}; } T val; std::memcpy(&val,first,sizeof(T)); return byte_swap(val); } // little_to_native template typename std::enable_if::type little_to_native(const uint8_t* first, std::size_t count) { if (sizeof(T) > count) { return T{}; } T val; std::memcpy(&val,first,sizeof(T)); return val; } template typename std::enable_if::type little_to_native(const uint8_t* first, std::size_t count) { if (sizeof(T) > count) { return T{}; } T val; std::memcpy(&val,first,sizeof(T)); return byte_swap(val); } } // namespace binary } // namespace jsoncons #endif // JSONCONS_UTILITY_BINARY_HPP jsoncons-1.3.2/include/jsoncons/utility/byte_string.hpp000066400000000000000000000656721477700171100234220ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_BYTE_STRING_HPP #define JSONCONS_BYTE_STRING_HPP #include #include #include // std::memcmp #include #include // std::setw #include #include // std::allocator #include #include #include #include // std::move #include #include #include #include #include namespace jsoncons { // Algorithms namespace detail { template typename std::enable_if::value_type,uint8_t>::value,size_t>::type encode_base64_generic(InputIt first, InputIt last, const char alphabet[65], Container& result) { std::size_t count = 0; unsigned char a3[3]; unsigned char a4[4]; unsigned char fill = alphabet[64]; int i = 0; int j = 0; while (first != last) { a3[i++] = *first++; if (i == 3) { a4[0] = (a3[0] & 0xfc) >> 2; a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4); a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6); a4[3] = a3[2] & 0x3f; for (i = 0; i < 4; i++) { result.push_back(alphabet[a4[i]]); ++count; } i = 0; } } if (i > 0) { for (j = i; j < 3; ++j) { a3[j] = 0; } a4[0] = (a3[0] & 0xfc) >> 2; a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4); a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6); for (j = 0; j < i + 1; ++j) { result.push_back(alphabet[a4[j]]); ++count; } if (fill != 0) { while (i++ < 3) { result.push_back(fill); ++count; } } } return count; } template typename std::enable_if::value,decode_result>::type decode_base64_generic(InputIt first, InputIt last, const uint8_t reverse_alphabet[256], F f, Container& result) { uint8_t a4[4], a3[3]; uint8_t i = 0; uint8_t j = 0; while (first != last && *first != '=') { if (!f(*first)) { return decode_result{first, conv_errc::conversion_failed}; } a4[i++] = static_cast(*first++); if (i == 4) { for (i = 0; i < 4; ++i) { a4[i] = reverse_alphabet[a4[i]]; } a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4); a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2); a3[2] = ((a4[2] & 0x3) << 6) + a4[3]; for (i = 0; i < 3; i++) { result.push_back(a3[i]); } i = 0; } } if (i > 0) { for (j = 0; j < i; ++j) { a4[j] = reverse_alphabet[a4[j]]; } a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4); a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2); for (j = 0; j < i - 1; ++j) { result.push_back(a3[j]); } } return decode_result{last, conv_errc::success}; } } // namespace detail template typename std::enable_if::value_type,uint8_t>::value,size_t>::type encode_base16(InputIt first, InputIt last, Container& result) { static constexpr char characters[] = "0123456789ABCDEF"; for (auto it = first; it != last; ++it) { uint8_t c = *it; result.push_back(characters[c >> 4]); result.push_back(characters[c & 0xf]); } return (last-first)*2; } template typename std::enable_if::value_type,uint8_t>::value,size_t>::type encode_base64url(InputIt first, InputIt last, Container& result) { static constexpr char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789-_" "\0"; return detail::encode_base64_generic(first, last, alphabet, result); } template typename std::enable_if::value_type,uint8_t>::value,size_t>::type encode_base64(InputIt first, InputIt last, Container& result) { static constexpr char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/" "="; return detail::encode_base64_generic(first, last, alphabet, result); } template bool is_base64(Char c) { return (c >= 0 && c < 128) && (isalnum((int)c) || c == '+' || c == '/'); } template bool is_base64url(Char c) { return (c >= 0 && c < 128) && (isalnum((int)c) || c == '-' || c == '_'); } inline static bool is_base64url(int c) { return isalnum(c) || c == '-' || c == '_'; } // decode template typename std::enable_if::value,decode_result>::type decode_base64url(InputIt first, InputIt last, Container& result) { static constexpr uint8_t reverse_alphabet[256] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 62, 0xff, 0xff, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 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, 0xff, 0xff, 0xff, 0xff, 63, 0xff, 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, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; auto retval = jsoncons::detail::decode_base64_generic(first, last, reverse_alphabet, is_base64url::value_type>, result); return retval.ec == conv_errc::success ? retval : decode_result{retval.it, conv_errc::not_base64url}; } template typename std::enable_if::value,decode_result>::type decode_base64(InputIt first, InputIt last, Container& result) { static constexpr uint8_t reverse_alphabet[256] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 62, 0xff, 0xff, 0xff, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 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, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 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, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; auto retval = jsoncons::detail::decode_base64_generic(first, last, reverse_alphabet, is_base64::value_type>, result); return retval.ec == conv_errc::success ? retval : decode_result{retval.it, conv_errc::not_base64}; } template typename std::enable_if::value,decode_result>::type decode_base16(InputIt first, InputIt last, Container& result) { std::size_t len = std::distance(first,last); if (len & 1) { return decode_result{first, conv_errc::not_base16}; } InputIt it = first; while (it != last) { uint8_t val; auto a = *it++; if (a >= '0' && a <= '9') { val = static_cast(a - '0') << 4; } else if ((a | 0x20) >= 'a' && (a | 0x20) <= 'f') { val = (static_cast((a | 0x20) - 'a') + 10) << 4; } else { return decode_result{first, conv_errc::not_base16}; } auto b = *it++; if (b >= '0' && b <= '9') { val |= (b - '0'); } else if ((b | 0x20) >= 'a' && (b | 0x20) <= 'f') { val |= ((b | 0x20) - 'a' + 10); } else { return decode_result{first, conv_errc::not_base16}; } result.push_back(val); } return decode_result{last, conv_errc::success}; } struct byte_traits { using char_type = uint8_t; static constexpr int eof() { return std::char_traits::eof(); } static int compare(const char_type* s1, const char_type* s2, std::size_t count) noexcept { return std::memcmp(s1,s2,count); } }; // basic_byte_string template class basic_byte_string; // byte_string_view class byte_string_view { const uint8_t* data_{nullptr}; std::size_t size_{0}; public: using traits_type = byte_traits; using const_iterator = const uint8_t*; using iterator = const_iterator; using size_type = std::size_t; using value_type = uint8_t; using reference = uint8_t&; using const_reference = const uint8_t&; using difference_type = std::ptrdiff_t; using pointer = uint8_t*; using const_pointer = const uint8_t*; constexpr byte_string_view() noexcept { } constexpr byte_string_view(const uint8_t* data, std::size_t length) noexcept : data_(data), size_(length) { } template constexpr explicit byte_string_view(const Container& cont, typename std::enable_if::value,int>::type = 0) : data_(reinterpret_cast(cont.data())), size_(cont.size()) { } template constexpr byte_string_view(const basic_byte_string& bytes); constexpr byte_string_view(const byte_string_view&) = default; JSONCONS_CPP14_CONSTEXPR byte_string_view(byte_string_view&& other) noexcept { const_pointer temp_data = data_; data_ = other.data_; other.data_ = temp_data; size_type temp_size = size_; size_ = other.size_; other.size_ = temp_size; } byte_string_view& operator=(const byte_string_view&) = default; byte_string_view& operator=(byte_string_view&& other) noexcept { std::swap(data_, other.data_); std::swap(size_, other.size_); return *this; } constexpr const uint8_t* data() const noexcept { return data_; } constexpr size_t size() const noexcept { return size_; } // iterator support constexpr const_iterator begin() const noexcept { return data_; } constexpr const_iterator end() const noexcept { return data_ + size_; } constexpr const_iterator cbegin() const noexcept { return data_; } constexpr const_iterator cend() const noexcept { return data_ + size_; } constexpr uint8_t operator[](size_type pos) const { return data_[pos]; } JSONCONS_CPP14_CONSTEXPR byte_string_view substr(size_type pos) const { if (pos > size_) { JSONCONS_THROW(std::out_of_range("pos exceeds size")); } std::size_t n = size_ - pos; return byte_string_view(data_ + pos, n); } byte_string_view substr(size_type pos, size_type n) const { if (pos > size_) { JSONCONS_THROW(std::out_of_range("pos exceeds size")); } if (pos + n > size_) { n = size_ - pos; } return byte_string_view(data_ + pos, n); } int compare(const byte_string_view& s) const noexcept { const int rc = traits_type::compare(data_, s.data(), (std::min)(size_, s.size())); return rc != 0 ? rc : (size_ == s.size() ? 0 : size_ < s.size() ? -1 : 1); } template int compare(const basic_byte_string& s) const noexcept { const int rc = traits_type::compare(data_, s.data(), (std::min)(size_, s.size())); return rc != 0 ? rc : (size_ == s.size() ? 0 : size_ < s.size() ? -1 : 1); } template friend std::basic_ostream& operator<<(std::basic_ostream& os, const byte_string_view& bstr) { std::basic_ostringstream ss; ss.flags(std::ios::hex); ss.fill('0'); bool first = true; for (auto b : bstr) { if (first) { first = false; } else { ss << ','; } ss << std::setw(2) << static_cast(b); } os << ss.str(); return os; } }; // basic_byte_string template > class basic_byte_string { using byte_allocator_type = typename std::allocator_traits:: template rebind_alloc; std::vector data_; public: using traits_type = byte_traits; using allocator_type = byte_allocator_type; using value_type = typename std::vector::value_type; using size_type = typename std::vector::size_type; using difference_type = typename std::vector::difference_type; using reference = typename std::vector::reference; using const_reference = typename std::vector::const_reference; using pointer = typename std::vector::pointer; using const_pointer = typename std::vector::const_pointer; using iterator = typename std::vector::iterator; using const_iterator = typename std::vector::const_iterator; basic_byte_string() = default; explicit basic_byte_string(const Allocator& alloc) : data_(alloc) { } basic_byte_string(std::initializer_list init) : data_(std::move(init)) { } basic_byte_string(std::initializer_list init, const Allocator& alloc) : data_(std::move(init), alloc) { } explicit basic_byte_string(const byte_string_view& v) : data_(v.begin(),v.end()) { } basic_byte_string(const basic_byte_string& v) : data_(v.data_) { } basic_byte_string(basic_byte_string&& v) noexcept : data_(std::move(v.data_)) { } basic_byte_string(const byte_string_view& v, const Allocator& alloc) : data_(v.begin(),v.end(),alloc) { } basic_byte_string(const uint8_t* data, std::size_t length, const Allocator& alloc = Allocator()) : data_(data, data+length,alloc) { } Allocator get_allocator() const { return data_.get_allocator(); } basic_byte_string& operator=(const basic_byte_string& s) = default; basic_byte_string& operator=(basic_byte_string&& other) noexcept { data_.swap(other.data_); return *this; } void reserve(std::size_t new_cap) { data_.reserve(new_cap); } void push_back(uint8_t b) { data_.push_back(b); } void assign(const uint8_t* s, std::size_t count) { data_.clear(); data_.insert(data_.end(), s, s+count); } void append(const uint8_t* s, std::size_t count) { data_.insert(data_.end(), s, s+count); } void clear() { data_.clear(); } uint8_t operator[](size_type pos) const { return data_[pos]; } // iterator support iterator begin() noexcept { return data_.begin(); } iterator end() noexcept { return data_.end(); } const_iterator begin() const noexcept { return data_.begin(); } const_iterator end() const noexcept { return data_.end(); } uint8_t* data() { return data_.data(); } const uint8_t* data() const { return data_.data(); } std::size_t size() const { return data_.size(); } int compare(const byte_string_view& s) const noexcept { const int rc = traits_type::compare(data(), s.data(), (std::min)(size(), s.size())); return rc != 0 ? rc : (size() == s.size() ? 0 : size() < s.size() ? -1 : 1); } int compare(const basic_byte_string& s) const noexcept { const int rc = traits_type::compare(data(), s.data(), (std::min)(size(), s.size())); return rc != 0 ? rc : (size() == s.size() ? 0 : size() < s.size() ? -1 : 1); } template friend std::basic_ostream& operator<<(std::basic_ostream& os, const basic_byte_string& o) { os << byte_string_view(o); return os; } }; template constexpr byte_string_view::byte_string_view(const basic_byte_string& bytes) : data_(bytes.data()), size_(bytes.size()) { } // == inline bool operator==(const byte_string_view& lhs, const byte_string_view& rhs) noexcept { return lhs.compare(rhs) == 0; } template bool operator==(const byte_string_view& lhs, const basic_byte_string& rhs) noexcept { return lhs.compare(rhs) == 0; } template bool operator==(const basic_byte_string& lhs, const byte_string_view& rhs) noexcept { return rhs.compare(lhs) == 0; } template bool operator==(const basic_byte_string& lhs, const basic_byte_string& rhs) noexcept { return rhs.compare(lhs) == 0; } // != inline bool operator!=(const byte_string_view& lhs, const byte_string_view& rhs) noexcept { return lhs.compare(rhs) != 0; } template bool operator!=(const byte_string_view& lhs, const basic_byte_string& rhs) noexcept { return lhs.compare(rhs) != 0; } template bool operator!=(const basic_byte_string& lhs, const byte_string_view& rhs) noexcept { return rhs.compare(lhs) != 0; } template bool operator!=(const basic_byte_string& lhs, const basic_byte_string& rhs) noexcept { return rhs.compare(lhs) != 0; } // <= inline bool operator<=(const byte_string_view& lhs, const byte_string_view& rhs) noexcept { return lhs.compare(rhs) <= 0; } template bool operator<=(const byte_string_view& lhs, const basic_byte_string& rhs) noexcept { return lhs.compare(rhs) <= 0; } template bool operator<=(const basic_byte_string& lhs, const byte_string_view& rhs) noexcept { return rhs.compare(lhs) >= 0; } template bool operator<=(const basic_byte_string& lhs, const basic_byte_string& rhs) noexcept { return rhs.compare(lhs) >= 0; } // < inline bool operator<(const byte_string_view& lhs, const byte_string_view& rhs) noexcept { return lhs.compare(rhs) < 0; } template bool operator<(const byte_string_view& lhs, const basic_byte_string& rhs) noexcept { return lhs.compare(rhs) < 0; } template bool operator<(const basic_byte_string& lhs, const byte_string_view& rhs) noexcept { return rhs.compare(lhs) > 0; } template bool operator<(const basic_byte_string& lhs, const basic_byte_string& rhs) noexcept { return rhs.compare(lhs) > 0; } // >= inline bool operator>=(const byte_string_view& lhs, const byte_string_view& rhs) noexcept { return lhs.compare(rhs) >= 0; } template bool operator>=(const byte_string_view& lhs, const basic_byte_string& rhs) noexcept { return lhs.compare(rhs) >= 0; } template bool operator>=(const basic_byte_string& lhs, const byte_string_view& rhs) noexcept { return rhs.compare(lhs) <= 0; } template bool operator>=(const basic_byte_string& lhs, const basic_byte_string& rhs) noexcept { return rhs.compare(lhs) <= 0; } // > inline bool operator>(const byte_string_view& lhs, const byte_string_view& rhs) noexcept { return lhs.compare(rhs) > 0; } template bool operator>(const byte_string_view& lhs, const basic_byte_string& rhs) noexcept { return lhs.compare(rhs) > 0; } template bool operator>(const basic_byte_string& lhs, const byte_string_view& rhs) noexcept { return rhs.compare(lhs) < 0; } template bool operator>(const basic_byte_string& lhs, const basic_byte_string& rhs) noexcept { return rhs.compare(lhs) < 0; } using byte_string = basic_byte_string>; namespace extension_traits { template struct is_basic_byte_string : std::false_type {}; template struct is_basic_byte_string> : std::true_type {}; } // namespace extension_traits } // namespace jsoncons #endif // JSONCONS_BYTE_STRING_HPP jsoncons-1.3.2/include/jsoncons/utility/extension_traits.hpp000066400000000000000000000772761477700171100244760ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_UTILITY_EXTENSION_TRAITS_HPP #define JSONCONS_UTILITY_EXTENSION_TRAITS_HPP #include // std::array #include // CHAR_BIT #include #include #include #include // std::byte #include // std::iterator_traits #include #include #include // std::enable_if, std::true_type #include // std::declval #include #if defined(JSONCONS_HAS_POLYMORPHIC_ALLOCATOR) #include #endif namespace jsoncons { namespace extension_traits { // is_char8 template struct is_char8 : std::false_type {}; template struct is_char8::value && !std::is_same::value && sizeof(uint8_t) == sizeof(CharT)>::type> : std::true_type {}; // is_char16 template struct is_char16 : std::false_type {}; template struct is_char16::value && !std::is_same::value && (std::is_same::value || sizeof(uint16_t) == sizeof(CharT))>::type> : std::true_type {}; // is_char32 template struct is_char32 : std::false_type {}; template struct is_char32::value && !std::is_same::value && (std::is_same::value || (!std::is_same::value && sizeof(uint32_t) == sizeof(CharT)))>::type> : std::true_type {}; // is_int128 template struct is_int128_type : std::false_type {}; #if defined(JSONCONS_HAS_INT128) template struct is_int128_type::value>::type> : std::true_type {}; #endif // is_unsigned_integer template struct is_uint128_type : std::false_type {}; #if defined (JSONCONS_HAS_INT128) template struct is_uint128_type::value>::type> : std::true_type {}; #endif template class integer_limits { public: static constexpr bool is_specialized = false; }; template class integer_limits::value && !std::is_same::value>::type> { public: static constexpr bool is_specialized = true; static constexpr bool is_signed = std::numeric_limits::is_signed; static constexpr int digits = std::numeric_limits::digits; static constexpr std::size_t buffer_size = static_cast(sizeof(T)*CHAR_BIT*0.302) + 3; static constexpr T(max)() noexcept { return (std::numeric_limits::max)(); } static constexpr T(min)() noexcept { return (std::numeric_limits::min)(); } static constexpr T lowest() noexcept { return std::numeric_limits::lowest(); } }; template class integer_limits::value && is_int128_type::value>::type> { public: static constexpr bool is_specialized = true; static constexpr bool is_signed = true; static constexpr int digits = sizeof(T)*CHAR_BIT - 1; static constexpr std::size_t buffer_size = (sizeof(T)*CHAR_BIT*0.302) + 3; static constexpr T(max)() noexcept { return (((((T)1 << (digits - 1)) - 1) << 1) + 1); } static constexpr T(min)() noexcept { return -(max)() - 1; } static constexpr T lowest() noexcept { return (min)(); } }; template class integer_limits::value && is_uint128_type::value>::type> { public: static constexpr bool is_specialized = true; static constexpr bool is_signed = false; static constexpr int digits = sizeof(T)*CHAR_BIT; static constexpr T(max)() noexcept { return T(T(~0)); } static constexpr T(min)() noexcept { return 0; } static constexpr T lowest() noexcept { return std::numeric_limits::lowest(); } }; #ifndef JSONCONS_HAS_VOID_T // follows https://en.cppreference.com/w/cpp/types/void_t template struct make_void { typedef void type;}; template using void_t = typename make_void::type; #else using void_t = std::void_t; #endif // follows http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4436.pdf // detector // primary template handles all types not supporting the archetypal Op template< class Default, class, // always void; supplied externally template class Op, typename... Args > struct detector { constexpr static auto value = false; using type = Default; }; // specialization recognizes and handles only types supporting Op template< class Default, template class Op, typename... Args > struct detector>, Op, Args...> { constexpr static auto value = true; using type = Op; }; // is_detected, is_detected_t template< template class Op,typename... Args > using is_detected = detector; template< template class Op,typename... Args > using is_detected_t = typename is_detected::type; // detected_or, detected_or_t template class Op,typename... Args > using detected_or = detector; template class Op,typename... Args > using detected_or_t = typename detected_or::type; // is_detected_exact template< class Expected, template class Op,typename... Args > using is_detected_exact = std::is_same< Expected, is_detected_t >; // is_detected_convertible template< class To, template class Op,typename... Args > using is_detected_convertible = std::is_convertible< is_detected_t, To >; // to_plain_pointer template inline typename std::pointer_traits::element_type* to_plain_pointer(Pointer ptr) { return (std::addressof(*ptr)); } template inline T * to_plain_pointer(T * ptr) { return (ptr); } // is_std_byte template struct is_std_byte : std::false_type {}; #if defined(JSONCONS_HAS_STD_BYTE) template struct is_std_byte::value >::type> : std::true_type {}; #endif // is_byte template struct is_byte : std::false_type {}; template struct is_byte::value || std::is_same::value || std::is_same::value || is_std_byte::value >::type> : std::true_type {}; // is_character template struct is_character : std::false_type {}; template struct is_character::value || #ifdef __cpp_char8_t std::is_same::value || #endif std::is_same::value >::type> : std::true_type {}; // is_narrow_character template struct is_narrow_character : std::false_type {}; template struct is_narrow_character::value && (sizeof(T) == sizeof(char)) >::type> : std::true_type {}; // is_wide_character template struct is_wide_character : std::false_type {}; template struct is_wide_character::value && (sizeof(T) != sizeof(char)) >::type> : std::true_type {}; // From boost namespace ut_detail { template struct is_cstring_impl : public std::false_type {}; template struct is_cstring_impl : public is_cstring_impl {}; template struct is_cstring_impl : public is_cstring_impl {}; template<> struct is_cstring_impl : public std::true_type {}; #ifdef __cpp_char8_t template<> struct is_cstring_impl : public std::true_type {}; #endif template<> struct is_cstring_impl : public std::true_type {}; } // namespace ut_detail template struct is_cstring : public ut_detail::is_cstring_impl::type> {}; // is_bool template struct is_bool : std::false_type {}; template struct is_bool::value >::type> : std::true_type {}; // is_u8_u16_u32_or_u64 template struct is_u8_u16_u32_or_u64 : std::false_type {}; template struct is_u8_u16_u32_or_u64::value || std::is_same::value || std::is_same::value || std::is_same::value >::type> : std::true_type {}; // is_int template struct is_i8_i16_i32_or_i64 : std::false_type {}; template struct is_i8_i16_i32_or_i64::value || std::is_same::value || std::is_same::value || std::is_same::value >::type> : std::true_type {}; // is_float_or_double template struct is_float_or_double : std::false_type {}; template struct is_float_or_double::value || std::is_same::value >::type> : std::true_type {}; // make_unsigned template struct make_unsigned_impl {using type = typename std::make_unsigned::type;}; #if defined(JSONCONS_HAS_INT128) template <> struct make_unsigned_impl {using type = uint128_type;}; template <> struct make_unsigned_impl {using type = uint128_type;}; #endif template struct make_unsigned : make_unsigned_impl::type> {}; // is_integer template struct is_integer : std::false_type {}; template struct is_integer::is_specialized>::type> : std::true_type {}; // is_signed_integer template struct is_signed_integer : std::false_type {}; template struct is_signed_integer::is_specialized && integer_limits::is_signed>::type> : std::true_type {}; // is_unsigned_integer template struct is_unsigned_integer : std::false_type {}; template struct is_unsigned_integer::is_specialized && !integer_limits::is_signed>::type> : std::true_type {}; // is_primitive template struct is_primitive : std::false_type {}; template struct is_primitive::value || is_bool::value || std::is_floating_point::value >::type> : std::true_type {}; // Containers template using container_npos_t = decltype(Container::npos); template using container_allocator_type_t = typename Container::allocator_type; template using container_mapped_type_t = typename Container::mapped_type; template using container_key_type_t = typename Container::key_type; template using container_value_type_t = typename std::iterator_traits::value_type; template using container_char_traits_t = typename Container::traits_type::char_type; template using container_push_back_t = decltype(std::declval().push_back(std::declval())); template using container_push_front_t = decltype(std::declval().push_front(std::declval())); template using container_insert_t = decltype(std::declval().insert(std::declval())); template using container_reserve_t = decltype(std::declval().reserve(typename Container::size_type())); template using container_data_t = decltype(std::declval().data()); template using container_size_t = decltype(std::declval().size()); // has_allocator_type template struct has_allocator_type : std::false_type {}; template struct has_allocator_type::value >::type> : std::true_type {}; // is_string_or_string_view template struct is_string_or_string_view : std::false_type {}; template struct is_string_or_string_view::value && is_detected_exact::value && is_detected::value >::type> : std::true_type {}; // is_string template struct is_string : std::false_type {}; template struct is_string::value && has_allocator_type::value >::type> : std::true_type {}; // is_string_view template struct is_string_view : std::false_type {}; template struct is_string_view::value && !is_detected::value >::type> : std::true_type {}; // is_map_like template struct is_map_like : std::false_type {}; template struct is_map_like::value && is_detected::value && is_detected::value && is_detected::value >::type> : std::true_type {}; // is_std_array template struct is_std_array : std::false_type {}; template struct is_std_array> : std::true_type {}; // is_array_like template struct is_array_like : std::false_type {}; template struct is_array_like::value && is_detected::value && !is_std_array::value && !is_detected_exact::value && !is_map_like::value >::type> : std::true_type {}; // is_constructible_from_const_pointer_and_size template struct is_constructible_from_const_pointer_and_size : std::false_type {}; template struct is_constructible_from_const_pointer_and_size::value >::type> : std::true_type {}; // has_reserve template using has_reserve = is_detected; // is_back_insertable template using is_back_insertable = is_detected; // is_front_insertable template using is_front_insertable = is_detected; // is_insertable template using is_insertable = is_detected; // has_data, has_data_exact template using has_data = is_detected; template using has_data_exact = is_detected_exact; // has_size template using has_size = is_detected; // has_data_and_size template struct has_data_and_size { static constexpr bool value = has_data::value && has_size::value; }; // is_byte_sequence template struct is_byte_sequence : std::false_type {}; template struct is_byte_sequence::value && has_size::value && is_byte::value >::type> : std::true_type {}; // is_char_sequence template struct is_char_sequence : std::false_type {}; template struct is_char_sequence::value && has_size::value && is_character::value >::type> : std::true_type {}; // is_sequence_of template struct is_sequence_of : std::false_type {}; template struct is_sequence_of::value && has_size::value && std::is_same::value >::type> : std::true_type {}; // is_back_insertable_byte_container template struct is_back_insertable_byte_container : std::false_type {}; template struct is_back_insertable_byte_container::value && is_byte::value >::type> : std::true_type {}; // is_back_insertable_char_container template struct is_back_insertable_char_container : std::false_type {}; template struct is_back_insertable_char_container::value && is_character::value >::type> : std::true_type {}; // is_back_insertable_container_of template struct is_back_insertable_container_of : std::false_type {}; template struct is_back_insertable_container_of::value && std::is_same::value >::type> : std::true_type {}; // is_c_array template struct is_c_array : std::false_type {}; template struct is_c_array : std::true_type {}; template struct is_c_array : std::true_type {}; namespace impl { template struct is_typed_array : std::false_type {}; template struct is_typed_array < T, typename std::enable_if::value && (std::is_same::type,uint8_t>::value || std::is_same::type,uint16_t>::value || std::is_same::type,uint32_t>::value || std::is_same::type,uint64_t>::value || std::is_same::type,int8_t>::value || std::is_same::type,int16_t>::value || std::is_same::type,int32_t>::value || std::is_same::type,int64_t>::value || std::is_same::type,float_t>::value || std::is_same::type,double_t>::value)>::type > : std::true_type{}; } // namespace impl template using is_typed_array = impl::is_typed_array::type>; // is_compatible_element template struct is_compatible_element : std::false_type {}; template struct is_compatible_element < Container, Element, typename std::enable_if::value>::type> : std::is_convertible< typename std::remove_pointer().data() )>::type(*)[], Element(*)[]> {}; template using construct_from_string_t = decltype(T(std::string{})); template using is_constructible_from_string = is_detected; template using construct_from_data_size_t = decltype(T(static_cast(nullptr),Size{})); template using is_constructible_from_data_size = is_detected; // is_unary_function_object // is_unary_function_object_exact template using unary_function_object_t = decltype(std::declval()(std::declval())); template using is_unary_function_object = is_detected; template using is_unary_function_object_exact = is_detected_exact; // is_binary_function_object // is_binary_function_object_exact template using binary_function_object_t = decltype(std::declval()(std::declval(),std::declval())); template using is_binary_function_object = is_detected; template using is_binary_function_object_exact = is_detected_exact; template struct is_convertible_to_string_view : std::false_type {}; template struct is_convertible_to_string_view::value || is_cstring::value >::type> : std::true_type {}; #if defined(JSONCONS_HAS_2017) template using is_nothrow_swappable = std::is_nothrow_swappable; #else template struct is_nothrow_swappable { static const bool value = noexcept(swap(std::declval(), std::declval())); }; #endif #if defined(JSONCONS_HAS_2014) template using alignment_of = std::alignment_of; template< typename T, T... Ints > using integer_sequence = std::integer_sequence; template using index_sequence = std::index_sequence; template using make_integer_sequence = std::make_integer_sequence; template using make_index_sequence = std::make_index_sequence; template using index_sequence_for = std::index_sequence_for; #else template struct alignment_of : std::integral_constant::type)> {}; template class integer_sequence { public: using value_type = T; static_assert(std::is_integral::value, "not integral type"); static constexpr std::size_t size() noexcept { return sizeof...(Ints); } }; template using index_sequence = integer_sequence; namespace detail_ { template struct IntSeqImpl { using TValue = T; static_assert(std::is_integral::value, "not integral type"); static_assert(Begin >= 0 && Begin < End, "unexpected argument (Begin<0 || Begin<=End)"); template struct IntSeqCombiner; template struct IntSeqCombiner, integer_sequence> { using TResult = integer_sequence; }; using TResult = typename IntSeqCombiner::TResult, typename IntSeqImpl::TResult>::TResult; }; template struct IntSeqImpl { using TValue = T; static_assert(std::is_integral::value, "not integral type"); static_assert(Begin >= 0, "unexpected argument (Begin<0)"); using TResult = integer_sequence; }; template struct IntSeqImpl { using TValue = T; static_assert(std::is_integral::value, "not integral type"); static_assert(Begin >= 0, "unexpected argument (Begin<0)"); using TResult = integer_sequence; }; } // namespace detail_ template using make_integer_sequence = typename detail_::IntSeqImpl::TResult; template using make_index_sequence = make_integer_sequence; template using index_sequence_for = make_index_sequence; #endif // is_propagating_allocator template using allocator_outer_allocator_type_t = typename Allocator::outer_allocator_type; template using allocator_inner_allocator_type_t = typename Allocator::inner_allocator_type; template struct is_propagating_allocator : std::false_type {}; template struct is_polymorphic_allocator : std::false_type {}; #if defined(JSONCONS_HAS_POLYMORPHIC_ALLOCATOR) template struct is_polymorphic_allocator < T, typename std::enable_if<(std::is_same>::value) >::type > : std::true_type{}; #endif template struct is_propagating_allocator < T, typename std::enable_if<(is_polymorphic_allocator::value) || (is_detected::value && is_detected::value)>::type > : std::true_type{}; } // extension_traits } // namespace jsoncons #endif // JSONCONS_UTILITY_EXTENSION_TRAITS_HPP jsoncons-1.3.2/include/jsoncons/utility/heap_string.hpp000066400000000000000000000145141477700171100233610ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_UTILITY_HEAP_STRING_HPP #define JSONCONS_UTILITY_HEAP_STRING_HPP #include #include // std::memcpy #include // std::allocator #include #include #include namespace jsoncons { namespace utility { inline char* align_up(char* ptr, std::size_t alignment) noexcept { return reinterpret_cast(~(alignment - 1) & (reinterpret_cast(ptr) + alignment - 1)); } template struct heap_string_base { Extra extra_; Allocator alloc_; Allocator& get_allocator() { return alloc_; } const Allocator& get_allocator() const { return alloc_; } heap_string_base(const Extra& extra, const Allocator& alloc) : extra_(extra), alloc_(alloc) { } ~heap_string_base() = default; }; template struct heap_string : public heap_string_base { using char_type = CharT; using allocator_type = typename std::allocator_traits::template rebind_alloc; using allocator_traits_type = std::allocator_traits; using pointer = typename allocator_traits_type::pointer; pointer p_{nullptr}; std::size_t length_{0}; uint8_t offset_{0}; uint8_t align_pad_{0}; heap_string(const heap_string&) = delete; heap_string(heap_string&&) = delete; heap_string(Extra extra, const Allocator& alloc) : heap_string_base(extra, alloc) { } ~heap_string() = default; const char_type* c_str() const { return extension_traits::to_plain_pointer(p_); } const char_type* data() const { return extension_traits::to_plain_pointer(p_); } std::size_t length() const { return length_; } Extra extra() const { return this->extra_; } heap_string& operator=(const heap_string&) = delete; heap_string& operator=(heap_string&&) = delete; }; template struct jsoncons_aligned_storage { struct type { alignas(Align) unsigned char data[Len]; }; }; // From boost 1_71 template T launder_cast(U* u) { #if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606 return std::launder(reinterpret_cast(u)); #elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) > 800 return __builtin_launder(reinterpret_cast(u)); #else return reinterpret_cast(u); #endif } // heap_string_factory template class heap_string_factory { public: using char_type = CharT; using heap_string_type = heap_string; private: using byte_allocator_type = typename std::allocator_traits::template rebind_alloc; using byte_pointer = typename std::allocator_traits::pointer; using heap_string_allocator_type = typename std::allocator_traits::template rebind_alloc; public: using pointer = typename std::allocator_traits::pointer; struct storage_t { heap_string_type data; char_type c[1]; }; typedef typename jsoncons_aligned_storage::type storage_type; static size_t aligned_size(std::size_t n) { return sizeof(storage_type) + n; } public: static pointer create(const char_type* s, std::size_t length, Extra extra, const Allocator& alloc) { std::size_t len = aligned_size(length*sizeof(char_type)); std::size_t align = alignof(storage_type); char* q = nullptr; char* storage = nullptr; byte_allocator_type byte_alloc(alloc); uint8_t align_pad = 0; if (align <= 8) { byte_pointer ptr = byte_alloc.allocate(len); q = extension_traits::to_plain_pointer(ptr); if (reinterpret_cast(q) % align == 0) { storage = q; } else { byte_alloc.deallocate(ptr, len); } } if (storage == nullptr) { align_pad = uint8_t(align-1); byte_pointer ptr = byte_alloc.allocate(align_pad+len); q = extension_traits::to_plain_pointer(ptr); storage = align_up(q, align); JSONCONS_ASSERT(storage >= q); } heap_string_type* ps = new(storage)heap_string_type(extra, byte_alloc); auto psa = launder_cast(storage); CharT* p = new(&psa->c)char_type[length + 1]; std::memcpy(p, s, length*sizeof(char_type)); p[length] = 0; ps->p_ = std::pointer_traits::pointer_to(*p); ps->length_ = length; ps->offset_ = (uint8_t)(storage - q); ps->align_pad_ = align_pad; return std::pointer_traits::pointer_to(*ps); } static void destroy(pointer ptr) { if (ptr != nullptr) { heap_string_type* rawp = extension_traits::to_plain_pointer(ptr); char* q = launder_cast(rawp); char* p = q - ptr->offset_; std::size_t mem_size = ptr->align_pad_ + aligned_size(ptr->length_*sizeof(char_type)); byte_allocator_type byte_alloc(ptr->get_allocator()); byte_alloc.deallocate(p,mem_size + ptr->offset_); } } }; } // namespace utility } // namespace jsoncons #endif // JSONCONS_UTILITY_HEAP_STRING_HPP jsoncons-1.3.2/include/jsoncons/utility/unicode_traits.hpp000066400000000000000000001435301477700171100240730ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/unicode_traits for latest version /* * Includes code derived from Unicode, Inc decomposition code in ConvertUTF.h and ConvertUTF.c * http://www.unicode.org/ * * "Unicode, Inc. hereby grants the right to freely use the information * supplied in this file in the creation of products supporting the * Unicode Standard." */ #ifndef JSONCONS_UTILITY_UNICODE_TRAITS_HPP #define JSONCONS_UTILITY_UNICODE_TRAITS_HPP #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace unicode_traits { enum class encoding_kind {undetected,utf8,utf16le,utf16be,utf32le,utf32be}; inline std::string to_string(encoding_kind encoding) { switch (encoding) { case encoding_kind::utf8: return "utf8"; case encoding_kind::utf16le: return "utf16le"; case encoding_kind::utf16be: return "utf16be"; case encoding_kind::utf32le: return "utf32le"; case encoding_kind::utf32be: return "utf32be"; default: return "undetected"; } } template struct detect_encoding_result { const Byte* ptr; encoding_kind encoding; }; template typename std::enable_if::value,detect_encoding_result>::type detect_encoding_from_bom(const CharT* data, std::size_t length) { const uint8_t bom_utf8[] = {0xef,0xbb,0xbf}; const uint8_t bom_utf16le[] = {0xff,0xfe}; const uint8_t bom_utf16be[] = {0xfe,0xff}; const uint8_t bom_utf32le[] = {0xff,0xfe,0x00,0x00}; const uint8_t bom_utf32be[] = {0x00,0x00,0xfe,0xff}; if (length >= 4 && !memcmp(data,bom_utf32le,4)) { return detect_encoding_result{data+4,encoding_kind::utf32le}; } else if (length >= 4 && !memcmp(data,bom_utf32be,4)) { return detect_encoding_result{data+4,encoding_kind::utf32be}; } else if (length >= 2 && !memcmp(data,bom_utf16le,2)) { return detect_encoding_result{data+2,encoding_kind::utf16le}; } else if (length >= 2 && !memcmp(data,bom_utf16be,2)) { return detect_encoding_result{data+2,encoding_kind::utf16be}; } else if (length >= 3 && !memcmp(data,bom_utf8,3)) { return detect_encoding_result{data+3,encoding_kind::utf8}; } else { return detect_encoding_result{data,encoding_kind::undetected}; } } template typename std::enable_if::value || extension_traits::is_char32::value,detect_encoding_result>::type detect_encoding_from_bom(const CharT* data, std::size_t) { return detect_encoding_result{data,encoding_kind::undetected}; } template typename std::enable_if::value,detect_encoding_result>::type detect_json_encoding(const CharT* data, std::size_t length) { detect_encoding_result r = detect_encoding_from_bom(data,length); if (r.encoding != encoding_kind::undetected) { return r; } else if (length < 4) { return detect_encoding_result{data,encoding_kind::utf8}; } else if (*data == 0 && *(data+1) == 0 && *(data+2) == 0) { return detect_encoding_result{data,encoding_kind::utf32be}; } else if (*data == 0 && *(data+2) == 0) { return detect_encoding_result{data,encoding_kind::utf16be}; } else if (*(data+1) == 0 && *(data+2) == 0 && *(data+3) == 0) { return detect_encoding_result{data,encoding_kind::utf32le}; } else if (*(data+1) == 0 && *(data+3) == 0) { return detect_encoding_result{data,encoding_kind::utf16le}; } else { return detect_encoding_result{data,encoding_kind::utf8}; } } template typename std::enable_if::value || extension_traits::is_char32::value,detect_encoding_result>::type detect_json_encoding(const CharT* data, std::size_t) { return detect_encoding_result{data,encoding_kind::undetected}; } /* * Magic values subtracted from a buffer value during UTF8 conversion. * This table contains as many values as there might be trailing bytes * in a UTF-8 sequence. Source: ConvertUTF.c */ const uint32_t offsets_from_utf8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; /* * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed * into the first byte, depending on how many bytes follow. There are * as many entries in this table as there are UTF-8 sequence types. * (I.e., one byte sequence, two byte... etc.). Remember that sequencs * for *legal* UTF-8 will be 4 or fewer bytes total. Source: ConvertUTF.c */ const uint8_t first_byte_mark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; /* * Index into the table below with the first byte of a UTF-8 sequence to * get the number of trailing bytes that are supposed to follow it. * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is * left as-is for anyone who may want to do such conversion, which was * allowed in earlier algorithms. Source: ConvertUTF.c */ const uint8_t trailing_bytes_for_utf8[256] = { 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, 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, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; // Some fundamental constants. Source: ConvertUTF.h const uint32_t replacement_char = 0x0000FFFD; const uint32_t max_bmp = 0x0000FFFF; const uint32_t max_utf16 = 0x0010FFFF; const uint32_t max_utf32 = 0x7FFFFFFF; const uint32_t max_legal_utf32 = 0x0010FFFF; const int half_shift = 10; // used for shifting by 10 bits const uint32_t half_base = 0x0010000UL; const uint32_t half_mask = 0x3FFUL; const uint16_t sur_high_start = 0xD800; const uint16_t sur_high_end = 0xDBFF; const uint16_t sur_low_start = 0xDC00; const uint16_t sur_low_end = 0xDFFF; inline static bool is_continuation_byte(unsigned char ch) { return (ch & 0xC0) == 0x80; } inline bool is_high_surrogate(uint32_t ch) noexcept { return (ch >= sur_high_start && ch <= sur_high_end); } inline bool is_low_surrogate(uint32_t ch) noexcept { return (ch >= sur_low_start && ch <= sur_low_end); } inline bool is_surrogate(uint32_t ch) noexcept { return (ch >= sur_high_start && ch <= sur_low_end); } enum class conv_flags { strict = 0, lenient }; // conv_errc enum class conv_errc { success = 0, over_long_utf8_sequence = 1, // over long utf8 sequence expected_continuation_byte, // expected continuation byte unpaired_high_surrogate, // unpaired high surrogate UTF-16 illegal_surrogate_value, // UTF-16 surrogate values are illegal in UTF-32 source_exhausted, // partial character in source, but hit end source_illegal // source sequence is illegal/malformed }; class Unicode_traits_error_category_impl_ : public std::error_category { public: virtual const char* name() const noexcept { return "unicode_traits conversion error"; } virtual std::string message(int ev) const { switch (static_cast(ev)) { case conv_errc::over_long_utf8_sequence: return "Over long utf8 sequence"; case conv_errc::expected_continuation_byte: return "Expected continuation byte"; case conv_errc::unpaired_high_surrogate: return "Unpaired high surrogate UTF-16"; case conv_errc::illegal_surrogate_value: return "UTF-16 surrogate values are illegal in UTF-32"; case conv_errc::source_exhausted: return "Partial character in source, but hit end"; case conv_errc::source_illegal: return "Source sequence is illegal/malformed"; default: return ""; break; } } }; inline const std::error_category& unicode_traits_error_category() { static Unicode_traits_error_category_impl_ instance; return instance; } inline std::error_code make_error_code(conv_errc result) { return std::error_code(static_cast(result),unicode_traits_error_category()); } } // unicode_traits } // namespace jsoncons namespace std { template<> struct is_error_code_enum : public true_type { }; } // namespace std namespace jsoncons { namespace unicode_traits { // utf8 template typename std::enable_if::value, conv_errc>::type is_legal_utf8(const CharT* first, std::size_t length) { uint8_t a; const CharT* srcptr = first+length; switch (length) { default: return conv_errc::over_long_utf8_sequence; case 4: if (((a = (*--srcptr))& 0xC0) != 0x80) return conv_errc::expected_continuation_byte; JSONCONS_FALLTHROUGH; case 3: if (((a = (*--srcptr))& 0xC0) != 0x80) return conv_errc::expected_continuation_byte; JSONCONS_FALLTHROUGH; case 2: if (((a = (*--srcptr))& 0xC0) != 0x80) return conv_errc::expected_continuation_byte; switch (static_cast(*first)) { // no fall-through in this inner switch case 0xE0: if (a < 0xA0) return conv_errc::source_illegal; break; case 0xED: if (a > 0x9F) return conv_errc::source_illegal; break; case 0xF0: if (a < 0x90) return conv_errc::source_illegal; break; case 0xF4: if (a > 0x8F) return conv_errc::source_illegal; break; default: if (a < 0x80) return conv_errc::source_illegal; } JSONCONS_FALLTHROUGH; case 1: if (static_cast(*first) >= 0x80 && static_cast(*first) < 0xC2) return conv_errc::source_illegal; break; } if (static_cast(*first) > 0xF4) return conv_errc::source_illegal; return conv_errc(); } template using void_t = void; template struct is_output_iterator : std::false_type {}; template struct is_output_iterator::iterator_category, decltype(*std::declval() = std::declval())>> : std::true_type {}; // is_same_size fixes issue with vs2013 // primary template template struct is_same_size : std::false_type { }; // specialization for non void types template struct is_same_size::value && !std::is_void::value>::type> { static constexpr bool value = (sizeof(T1) == sizeof(T2)); }; // convert template struct convert_result { const CharT* ptr; conv_errc ec; }; // to_codepoint template typename std::enable_if::value && extension_traits::is_char32::value, convert_result>::type to_codepoint(const CharT* first, const CharT* last, CodepointT& ch, conv_flags flags = conv_flags::strict) noexcept { ch = 0; if (first >= last) { return convert_result{first, conv_errc::source_exhausted}; } conv_errc result = conv_errc(); unsigned short extra_bytes_to_read = trailing_bytes_for_utf8[static_cast(*first)]; if (extra_bytes_to_read >= last - first) { result = conv_errc::source_exhausted; return convert_result{first, result}; } // Do this check whether lenient or strict if ((result=is_legal_utf8(first, extra_bytes_to_read+1)) != conv_errc()) { return convert_result{first, result}; } // The cases all fall through. See "Note A" below. switch (extra_bytes_to_read) { case 5: ch += static_cast(*first++); ch <<= 6; JSONCONS_FALLTHROUGH; case 4: ch += static_cast(*first++); ch <<= 6; JSONCONS_FALLTHROUGH; case 3: ch += static_cast(*first++); ch <<= 6; JSONCONS_FALLTHROUGH; case 2: ch += static_cast(*first++); ch <<= 6; JSONCONS_FALLTHROUGH; case 1: ch += static_cast(*first++); ch <<= 6; JSONCONS_FALLTHROUGH; case 0: ch += static_cast(*first++); break; } ch -= offsets_from_utf8[extra_bytes_to_read]; if (ch <= max_legal_utf32) { /* * UTF-16 surrogate values are illegal in UTF-32, and anything * over Plane 17 (> 0x10FFFF) is illegal. */ if (is_surrogate(ch) ) { if (flags == conv_flags::strict) { first -= (extra_bytes_to_read+1); // return to the illegal value itself result = conv_errc::source_illegal; return convert_result{first, result}; } else { ch = replacement_char; } } } else // i.e., ch > max_legal_utf32 { result = conv_errc::source_illegal; ch = replacement_char; } return convert_result{first,result} ; } template typename std::enable_if::value && extension_traits::is_char32::value, convert_result>::type to_codepoint(const CharT* first, const CharT* last, CodepointT& ch, conv_flags flags = conv_flags::strict) noexcept { ch = 0; if (first >= last) { return convert_result{first, conv_errc::source_exhausted}; } conv_errc result = conv_errc(); ch = *first++; // If we have a surrogate pair, convert to UTF32 first. if (is_high_surrogate(ch)) { // If the 16 bits following the high surrogate are in the first buffer... if (first < last) { uint32_t ch2 = *first; // If ptr's a low surrogate, convert to UTF32. if (ch2 >= sur_low_start && ch2 <= sur_low_end ) { ch = ((ch - sur_high_start) << half_shift) + (ch2 - sur_low_start) + half_base; ++first; } else if (flags == conv_flags::strict) // ptr's an unpaired high surrogate { --first; /* return to the illegal value itself */ result = conv_errc::source_illegal; return convert_result{first, result}; } } else { /* We don't have the 16 bits following the high surrogate. */ --first; /* return to the high surrogate */ result = conv_errc::source_exhausted; return convert_result{first, result}; } } else if (flags == conv_flags::strict) { /* UTF-16 surrogate values are illegal in UTF-32 */ if (is_low_surrogate(ch) ) { --first; /* return to the illegal value itself */ result = conv_errc::source_illegal; return convert_result{first, result}; } } return convert_result{first,result} ; } template typename std::enable_if::value && extension_traits::is_char32::value, convert_result>::type to_codepoint(const CharT* first, const CharT* last, CodepointT& ch, conv_flags flags = conv_flags::strict) noexcept { ch = 0; if (first >= last) { return convert_result{first, conv_errc::source_exhausted}; } conv_errc result = conv_errc(); ch = *first++; if (flags == conv_flags::strict ) { /* UTF-16 surrogate values are illegal in UTF-32 */ if (is_surrogate(ch)) { --first; /* return to the illegal value itself */ result = conv_errc::illegal_surrogate_value; return convert_result{first,result} ; } } if (!(ch <= max_legal_utf32)) { ch = replacement_char; result = conv_errc::source_illegal; } return convert_result{first,result} ; } // convert template typename std::enable_if::value && extension_traits::is_back_insertable::value && extension_traits::is_char8::value, convert_result>::type convert(const CharT* data, std::size_t length, Container& target, conv_flags flags=conv_flags::strict) { (void)flags; conv_errc result = conv_errc(); const CharT* last = data + length; while (data != last) { std::size_t len = trailing_bytes_for_utf8[static_cast(*data)] + 1; if (len > (std::size_t)(last - data)) { return convert_result{data, conv_errc::source_exhausted}; } if ((result=is_legal_utf8(data, len)) != conv_errc()) { return convert_result{data,result}; } switch (len) { case 4: target.push_back(static_cast(*data++)); JSONCONS_FALLTHROUGH; case 3: target.push_back(static_cast(*data++)); JSONCONS_FALLTHROUGH; case 2: target.push_back(static_cast(*data++)); JSONCONS_FALLTHROUGH; case 1: target.push_back(static_cast(*data++)); } } return convert_result{data,result} ; } template typename std::enable_if::value && extension_traits::is_back_insertable::value && extension_traits::is_char16::value, convert_result>::type convert(const CharT* data, std::size_t length, Container& target, conv_flags flags = conv_flags::strict) { conv_errc result = conv_errc(); const CharT* last = data + length; while (data != last) { unsigned short extra_bytes_to_read = trailing_bytes_for_utf8[static_cast(*data)]; if (extra_bytes_to_read >= last - data) { result = conv_errc::source_exhausted; break; } /* Do this check whether lenient or strict */ if ((result=is_legal_utf8(data, extra_bytes_to_read+1)) != conv_errc()) { break; } /* * The cases all fall through. See "Note A" below. */ uint32_t ch = 0; switch (extra_bytes_to_read) { case 5: ch += static_cast(*data++); ch <<= 6; /* remember, illegal UTF-8 */ JSONCONS_FALLTHROUGH; case 4: ch += static_cast(*data++); ch <<= 6; /* remember, illegal UTF-8 */ JSONCONS_FALLTHROUGH; case 3: ch += static_cast(*data++); ch <<= 6; JSONCONS_FALLTHROUGH; case 2: ch += static_cast(*data++); ch <<= 6; JSONCONS_FALLTHROUGH; case 1: ch += static_cast(*data++); ch <<= 6; JSONCONS_FALLTHROUGH; case 0: ch += static_cast(*data++); break; } ch -= offsets_from_utf8[extra_bytes_to_read]; if (ch <= max_bmp) { /* Target is a character <= 0xFFFF */ /* UTF-16 surrogate values are illegal in UTF-32 */ if (is_surrogate(ch) ) { if (flags == conv_flags::strict) { data -= (extra_bytes_to_read+1); /* return to the illegal value itself */ result = conv_errc::source_illegal; break; } else { target.push_back(replacement_char); } } else { target.push_back((uint16_t)ch); /* normal case */ } } else if (ch > max_utf16) { if (flags == conv_flags::strict) { result = conv_errc::source_illegal; data -= (extra_bytes_to_read+1); /* return to the start */ break; /* Bail out; shouldn't continue */ } else { target.push_back(replacement_char); } } else { /* target is a character in range 0xFFFF - 0x10FFFF. */ ch -= half_base; target.push_back((uint16_t)((ch >> half_shift) + sur_high_start)); target.push_back((uint16_t)((ch & half_mask) + sur_low_start)); } } return convert_result{data,result} ; } template typename std::enable_if::value && extension_traits::is_back_insertable::value && extension_traits::is_char32::value, convert_result>::type convert(const CharT* data, std::size_t length, Container& target, conv_flags flags = conv_flags::strict) { conv_errc result = conv_errc(); const CharT* last = data + length; while (data < last) { uint32_t ch = 0; unsigned short extra_bytes_to_read = trailing_bytes_for_utf8[static_cast(*data)]; if (extra_bytes_to_read >= last - data) { result = conv_errc::source_exhausted; break; } /* Do this check whether lenient or strict */ if ((result=is_legal_utf8(data, extra_bytes_to_read+1)) != conv_errc()) { break; } /* * The cases all fall through. See "Note A" below. */ switch (extra_bytes_to_read) { case 5: ch += static_cast(*data++); ch <<= 6; JSONCONS_FALLTHROUGH; case 4: ch += static_cast(*data++); ch <<= 6; JSONCONS_FALLTHROUGH; case 3: ch += static_cast(*data++); ch <<= 6; JSONCONS_FALLTHROUGH; case 2: ch += static_cast(*data++); ch <<= 6; JSONCONS_FALLTHROUGH; case 1: ch += static_cast(*data++); ch <<= 6; JSONCONS_FALLTHROUGH; case 0: ch += static_cast(*data++); break; } ch -= offsets_from_utf8[extra_bytes_to_read]; if (ch <= max_legal_utf32) { /* * UTF-16 surrogate values are illegal in UTF-32, and anything * over Plane 17 (> 0x10FFFF) is illegal. */ if (is_surrogate(ch) ) { if (flags == conv_flags::strict) { data -= (extra_bytes_to_read+1); /* return to the illegal value itself */ result = conv_errc::source_illegal; break; } else { target.push_back(replacement_char); } } else { target.push_back(ch); } } else { /* i.e., ch > max_legal_utf32 */ result = conv_errc::source_illegal; target.push_back(replacement_char); } } return convert_result{data,result} ; } // utf16 template typename std::enable_if::value && extension_traits::is_back_insertable::value && extension_traits::is_char8::value, convert_result>::type convert(const CharT* data, std::size_t length, Container& target, conv_flags flags = conv_flags::strict) { conv_errc result = conv_errc(); const CharT* last = data + length; while (data < last) { unsigned short bytes_to_write = 0; const uint32_t byteMask = 0xBF; const uint32_t byteMark = 0x80; uint32_t ch = *data++; /* If we have a surrogate pair, convert to uint32_t data. */ if (is_high_surrogate(ch)) { /* If the 16 bits following the high surrogate are in the data buffer... */ if (data < last) { uint32_t ch2 = *data; /* If ptr's a low surrogate, convert to uint32_t. */ if (ch2 >= sur_low_start && ch2 <= sur_low_end) { ch = ((ch - sur_high_start) << half_shift) + (ch2 - sur_low_start) + half_base; ++data; } else if (flags == conv_flags::strict) { /* ptr's an unpaired high surrogate */ --data; /* return to the illegal value itself */ result = conv_errc::unpaired_high_surrogate; break; } } else { /* We don't have the 16 bits following the high surrogate. */ --data; /* return to the high surrogate */ result = conv_errc::source_exhausted; break; } } else if (flags == conv_flags::strict) { /* UTF-16 surrogate values are illegal in UTF-32 */ if (is_low_surrogate(ch)) { --data; /* return to the illegal value itself */ result = conv_errc::source_illegal; break; } } /* Figure out how many bytes the result will require */ if (ch < (uint32_t)0x80) { bytes_to_write = 1; } else if (ch < (uint32_t)0x800) { bytes_to_write = 2; } else if (ch < (uint32_t)0x10000) { bytes_to_write = 3; } else if (ch < (uint32_t)0x110000) { bytes_to_write = 4; } else { bytes_to_write = 3; ch = replacement_char; } uint8_t byte1 = 0; uint8_t byte2 = 0; uint8_t byte3 = 0; uint8_t byte4 = 0; switch (bytes_to_write) { // note: everything falls through case 4: byte4 = (uint8_t)((ch | byteMark) & byteMask); ch >>= 6; JSONCONS_FALLTHROUGH; case 3: byte3 = (uint8_t)((ch | byteMark) & byteMask); ch >>= 6; JSONCONS_FALLTHROUGH; case 2: byte2 = (uint8_t)((ch | byteMark) & byteMask); ch >>= 6; JSONCONS_FALLTHROUGH; case 1: byte1 = (uint8_t)(ch | first_byte_mark[bytes_to_write]); break; } switch (bytes_to_write) { case 4: target.push_back(byte1); target.push_back(byte2); target.push_back(byte3); target.push_back(byte4); break; case 3: target.push_back(byte1); target.push_back(byte2); target.push_back(byte3); break; case 2: target.push_back(byte1); target.push_back(byte2); break; case 1: target.push_back(byte1); break; } } return convert_result{data,result} ; } template typename std::enable_if::value && extension_traits::is_back_insertable::value && extension_traits::is_char16::value, convert_result>::type convert(const CharT* data, std::size_t length, Container& target, conv_flags flags = conv_flags::strict) { conv_errc result = conv_errc(); const CharT* last = data + length; while (data != last) { uint32_t ch = *data++; /* If we have a surrogate pair, convert to uint32_t data. */ if (is_high_surrogate(ch)) { /* If the 16 bits following the high surrogate are in the data buffer... */ if (data < last) { uint32_t ch2 = *data; /* If ptr's a low surrogate, */ if (ch2 >= sur_low_start && ch2 <= sur_low_end) { target.push_back((uint16_t)ch); target.push_back((uint16_t)ch2); ++data; } else if (flags == conv_flags::strict) { /* ptr's an unpaired high surrogate */ --data; /* return to the illegal value itself */ result = conv_errc::unpaired_high_surrogate; break; } } else { /* We don't have the 16 bits following the high surrogate. */ --data; /* return to the high surrogate */ result = conv_errc::source_exhausted; break; } } else if (is_low_surrogate(ch)) { // illegal leading low surrogate if (flags == conv_flags::strict) { --data; /* return to the illegal value itself */ result = conv_errc::source_illegal; break; } else { target.push_back((uint16_t)ch); } } else { target.push_back((uint16_t)ch); } } return convert_result{data,result} ; } template typename std::enable_if::value && extension_traits::is_back_insertable::value && extension_traits::is_char32::value, convert_result>::type convert(const CharT* data, std::size_t length, Container& target, conv_flags flags = conv_flags::strict) { conv_errc result = conv_errc(); const CharT* last = data + length; while (data != last) { uint32_t ch = *data++; /* If we have a surrogate pair, convert to UTF32 data. */ if (is_high_surrogate(ch)) { /* If the 16 bits following the high surrogate are in the data buffer... */ if (data < last) { uint32_t ch2 = *data; /* If ptr's a low surrogate, convert to UTF32. */ if (ch2 >= sur_low_start && ch2 <= sur_low_end ) { ch = ((ch - sur_high_start) << half_shift) + (ch2 - sur_low_start) + half_base; ++data; } else if (flags == conv_flags::strict) { /* ptr's an unpaired high surrogate */ --data; /* return to the illegal value itself */ result = conv_errc::source_illegal; break; } } else { /* We don't have the 16 bits following the high surrogate. */ --data; /* return to the high surrogate */ result = conv_errc::source_exhausted; break; } } else if (flags == conv_flags::strict) { /* UTF-16 surrogate values are illegal in UTF-32 */ if (is_low_surrogate(ch) ) { --data; /* return to the illegal value itself */ result = conv_errc::source_illegal; break; } } target.push_back(ch); } return convert_result{data,result} ; } // utf32 template typename std::enable_if::value && extension_traits::is_back_insertable::value && extension_traits::is_char8::value, convert_result>::type convert(const CharT* data, std::size_t length, Container& target, conv_flags flags = conv_flags::strict) { conv_errc result = conv_errc(); const CharT* last = data + length; while (data < last) { unsigned short bytes_to_write = 0; const uint32_t byteMask = 0xBF; const uint32_t byteMark = 0x80; uint32_t ch = *data++; if (flags == conv_flags::strict ) { /* UTF-16 surrogate values are illegal in UTF-32 */ if (is_surrogate(ch)) { --data; /* return to the illegal value itself */ result = conv_errc::illegal_surrogate_value; break; } } /* * Figure out how many bytes the result will require. Turn any * illegally large UTF32 things (> Plane 17) into replacement chars. */ if (ch < (uint32_t)0x80) { bytes_to_write = 1; } else if (ch < (uint32_t)0x800) { bytes_to_write = 2; } else if (ch < (uint32_t)0x10000) { bytes_to_write = 3; } else if (ch <= max_legal_utf32) { bytes_to_write = 4; } else { bytes_to_write = 3; ch = replacement_char; result = conv_errc::source_illegal; } uint8_t byte1 = 0; uint8_t byte2 = 0; uint8_t byte3 = 0; uint8_t byte4 = 0; switch (bytes_to_write) { case 4: byte4 = (uint8_t)((ch | byteMark) & byteMask); ch >>= 6; JSONCONS_FALLTHROUGH; case 3: byte3 = (uint8_t)((ch | byteMark) & byteMask); ch >>= 6; JSONCONS_FALLTHROUGH; case 2: byte2 = (uint8_t)((ch | byteMark) & byteMask); ch >>= 6; JSONCONS_FALLTHROUGH; case 1: byte1 = (uint8_t) (ch | first_byte_mark[bytes_to_write]); break; } switch (bytes_to_write) { case 4: target.push_back(byte1); target.push_back(byte2); target.push_back(byte3); target.push_back(byte4); break; case 3: target.push_back(byte1); target.push_back(byte2); target.push_back(byte3); break; case 2: target.push_back(byte1); target.push_back(byte2); break; case 1: target.push_back(byte1); break; } } return convert_result{data,result} ; } template typename std::enable_if::value && extension_traits::is_back_insertable::value && extension_traits::is_char16::value, convert_result>::type convert(const CharT* data, std::size_t length, Container& target, conv_flags flags = conv_flags::strict) { conv_errc result = conv_errc(); const CharT* last = data + length; while (data != last) { uint32_t ch = *data++; if (ch <= max_bmp) { /* Target is a character <= 0xFFFF */ /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */ if (is_surrogate(ch) ) { if (flags == conv_flags::strict) { --data; /* return to the illegal value itself */ result = conv_errc::source_illegal; break; } else { target.push_back(replacement_char); } } else { target.push_back((uint16_t)ch); /* normal case */ } } else if (ch > max_legal_utf32) { if (flags == conv_flags::strict) { result = conv_errc::source_illegal; } else { target.push_back(replacement_char); } } else { /* target is a character in range 0xFFFF - 0x10FFFF. */ ch -= half_base; target.push_back((uint16_t)((ch >> half_shift) + sur_high_start)); target.push_back((uint16_t)((ch & half_mask) + sur_low_start)); } } return convert_result{data,result} ; } template typename std::enable_if::value && extension_traits::is_back_insertable::value && extension_traits::is_char32::value, convert_result>::type convert(const CharT* data, std::size_t length, Container& target, conv_flags flags = conv_flags::strict) { conv_errc result = conv_errc(); const CharT* last = data + length; while (data != last) { uint32_t ch = *data++; if (flags == conv_flags::strict ) { /* UTF-16 surrogate values are illegal in UTF-32 */ if (is_surrogate(ch)) { --data; /* return to the illegal value itself */ result = conv_errc::illegal_surrogate_value; break; } } if (ch <= max_legal_utf32) { target.push_back(ch); } else { target.push_back(replacement_char); result = conv_errc::source_illegal; } } return convert_result{data,result} ; } // validate template typename std::enable_if::value, convert_result>::type validate(const CharT* data, std::size_t length) noexcept { conv_errc result = conv_errc(); const CharT* last = data + length; while (data != last) { std::size_t len = static_cast(trailing_bytes_for_utf8[static_cast(*data)]) + 1; if (len > (std::size_t)(last - data)) { return convert_result{data, conv_errc::source_exhausted}; } if ((result=is_legal_utf8(data, len)) != conv_errc()) { return convert_result{data,result} ; } data += len; } return convert_result{data,result} ; } // utf16 template typename std::enable_if::value, convert_result>::type validate(const CharT* data, std::size_t length) noexcept { conv_errc result = conv_errc(); const CharT* last = data + length; while (data != last) { uint32_t ch = *data++; /* If we have a surrogate pair, validate to uint32_t data. */ if (is_high_surrogate(ch)) { /* If the 16 bits following the high surrogate are in the data buffer... */ if (data < last) { uint32_t ch2 = *data; /* If ptr's a low surrogate, */ if (ch2 >= sur_low_start && ch2 <= sur_low_end) { ++data; } else { --data; /* return to the illegal value itself */ result = conv_errc::unpaired_high_surrogate; break; } } else // We don't have the 16 bits following the high surrogate. { --data; /* return to the high surrogate */ result = conv_errc::source_exhausted; break; } } else if (is_low_surrogate(ch)) { /* UTF-16 surrogate values are illegal in UTF-32 */ --data; /* return to the illegal value itself */ result = conv_errc::source_illegal; break; } } return convert_result{data,result} ; } // utf32 template typename std::enable_if::value, convert_result>::type validate(const CharT* data, std::size_t length) noexcept { conv_errc result = conv_errc(); const CharT* last = data + length; while (data != last) { uint32_t ch = *data++; /* UTF-16 surrogate values are illegal in UTF-32 */ if (is_surrogate(ch)) { --data; /* return to the illegal value itself */ result = conv_errc::illegal_surrogate_value; break; } if (!(ch <= max_legal_utf32)) { result = conv_errc::source_illegal; } } return convert_result{data, result} ; } enum class encoding {u8,u16le,u16be,u32le,u32be,undetected}; template struct determine_encoding_result { Iterator it; encoding ec; }; template typename std::enable_if::value_type>::value && sizeof(typename std::iterator_traits::value_type) == sizeof(uint8_t), determine_encoding_result>::type detect_encoding(Iterator first, Iterator last) noexcept { Iterator it1 = first; if (std::distance(first,last) < 4) { if (std::distance(first,last) == 3) { Iterator it2 = ++first; Iterator it3 = ++first; if (static_cast(*it1) == 0xEF && static_cast(*it2) == 0xBB && static_cast(*it3) == 0xBF) { return determine_encoding_result{last,encoding::u8}; } } return determine_encoding_result{it1,encoding::undetected}; } else { Iterator it2 = ++first; Iterator it3 = ++first; Iterator it4 = ++first; uint32_t bom = static_cast(*it1) | (static_cast(*it2) << 8) | (static_cast(*it3) << 16) | (static_cast(*it4) << 24); if (bom == 0xFFFE0000) { return determine_encoding_result{it4++,encoding::u32be}; } else if (bom == 0x0000FEFF) { return determine_encoding_result{first,encoding::u32le}; } else if ((bom & 0xFFFF) == 0xFFFE) { return determine_encoding_result{it3,encoding::u16be}; } else if ((bom & 0xFFFF) == 0xFEFF) { return determine_encoding_result{it3,encoding::u16le}; } else if ((bom & 0xFFFFFF) == 0xBFBBEF) { return determine_encoding_result{it4,encoding::u8}; } else { uint32_t pattern = (static_cast(*it1) ? 1 : 0) | (static_cast(*it2) ? 2 : 0) | (static_cast(*it3) ? 4 : 0) | (static_cast(*it4) ? 8 : 0); switch (pattern) { case 0x08: return determine_encoding_result{it1,encoding::u32be}; case 0x0A: return determine_encoding_result{it1,encoding::u16be}; case 0x01: return determine_encoding_result{it1,encoding::u32le}; case 0x05: return determine_encoding_result{it1,encoding::u16le}; case 0x0F: return determine_encoding_result{it1,encoding::u8}; default: return determine_encoding_result{it1,encoding::undetected}; } } } } // count_codepoints template typename std::enable_if::value || extension_traits::is_char16::value || extension_traits::is_char32::value, std::size_t>::type count_codepoints(const CharT* data, std::size_t length, conv_flags flags = conv_flags::strict) noexcept { conv_errc ec = conv_errc(); std::size_t count = 0; const CharT* ptr = data; const CharT* last = data + length; for (; ptr < last; ++count) { uint32_t cp = 0; auto r = to_codepoint(ptr, last, cp, flags); if (r.ec != conv_errc()) { ec = r.ec; break; } ptr = r.ptr; } return ec == conv_errc() && ptr == last ? count : 0; } } // unicode_traits } // namespace jsoncons #endif //JSONCONS_UTILITY_UNICODE_TRAITS_HPP jsoncons-1.3.2/include/jsoncons/utility/uri.hpp000066400000000000000000001705651477700171100216660ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_UTILITY_URI_HPP #define JSONCONS_UTILITY_URI_HPP #include #include #include #include #include // std::string #include #include #include #include #include #include #include #include namespace jsoncons { enum class uri_errc { success = 0, invalid_uri = 1, invalid_character_in_scheme = 2, invalid_port = 3, invalid_character_in_userinfo = 4, invalid_character_in_host = 5, invalid_character_in_path = 6, invalid_character_in_fragment = 7 }; class uri_error_category_impl : public std::error_category { public: const char* name() const noexcept override { return "jsoncons/uri"; } std::string message(int ev) const override { switch (static_cast(ev)) { case uri_errc::invalid_uri: return "Invalid URI"; case uri_errc::invalid_character_in_scheme: return "Invalid characters in scheme"; case uri_errc::invalid_port: return "'port' argument must be a number >= 0 and < 65536"; case uri_errc::invalid_character_in_userinfo: return "Invalid characters in userinfo"; case uri_errc::invalid_character_in_host: return "Invalid characters in host"; case uri_errc::invalid_character_in_path: return "Invalid characters in path"; case uri_errc::invalid_character_in_fragment: return "Invalid characters in fragment"; default: return "Unknown uri error"; } } }; inline const std::error_category& uri_error_category() { static uri_error_category_impl instance; return instance; } inline std::error_code make_error_code(uri_errc result) { return std::error_code(static_cast(result), uri_error_category()); } } // namespace jsoncons namespace std { template<> struct is_error_code_enum : public true_type { }; } // namespace std namespace jsoncons { struct uri_fragment_part_t { explicit uri_fragment_part_t() = default; }; constexpr uri_fragment_part_t uri_fragment_part{}; struct uri_encoded_part_t { explicit uri_encoded_part_t() = default; }; constexpr uri_encoded_part_t uri_encoded_part{}; class uri { using part_type = std::pair; std::string uri_string_; part_type scheme_part_; part_type userinfo_part_; part_type host_part_; part_type port_part_; part_type path_part_; part_type query_part_; part_type fragment_part_; public: uri() : uri_string_{}, scheme_part_{0,0},userinfo_part_{0,0},host_part_{0,0},port_part_{0,0},path_part_{0,0},query_part_{0,0},fragment_part_{0,0} { } uri(const uri& other) : uri_string_(other.uri_string_), scheme_part_(other.scheme_part_), userinfo_part_(other.userinfo_part_), host_part_(other.host_part_), port_part_(other.port_part_), path_part_(other.path_part_), query_part_(other.query_part_), fragment_part_(other.fragment_part_) { } uri(uri&& other) noexcept : uri_string_(std::move(other.uri_string_)), scheme_part_(other.scheme_part_), userinfo_part_(other.userinfo_part_), host_part_(other.host_part_), port_part_(other.port_part_), path_part_(other.path_part_), query_part_(other.query_part_), fragment_part_(other.fragment_part_) { } uri(const uri& other, uri_fragment_part_t, jsoncons::string_view fragment) : uri_string_(other.uri_string_), scheme_part_(other.scheme_part_), userinfo_part_(other.userinfo_part_), host_part_(other.host_part_), port_part_(other.port_part_), path_part_(other.path_part_), query_part_(other.query_part_) { uri_string_.erase(query_part_.second); if (!fragment.empty()) { uri_string_.append("#"); fragment_part_.first = uri_string_.length(); encode_illegal_characters(fragment, uri_string_); fragment_part_.second = uri_string_.length(); } else { fragment_part_.first = fragment_part_.second = uri_string_.length(); } } explicit uri(jsoncons::string_view str) { std::error_code ec; *this = parse(str, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(std::system_error(ec)); } } uri(jsoncons::string_view scheme, jsoncons::string_view userinfo, jsoncons::string_view host, jsoncons::string_view port, jsoncons::string_view path, jsoncons::string_view query = "", jsoncons::string_view fragment = "") { if (!scheme.empty()) { uri_string_.append(scheme.data(), scheme.size()); scheme_part_.second = uri_string_.length(); } if (!userinfo.empty() || !host.empty() || !port.empty()) { if (!scheme.empty()) { uri_string_.append("://"); } if (!userinfo.empty()) { userinfo_part_.first = uri_string_.length(); encode_userinfo(userinfo, uri_string_); userinfo_part_.second = uri_string_.length(); uri_string_.append("@"); } else { userinfo_part_.first = userinfo_part_.second = uri_string_.length(); } if (!host.empty()) { host_part_.first = uri_string_.length(); uri_string_.append(host.data(), host.size()); host_part_.second = uri_string_.length(); } else { JSONCONS_THROW(json_runtime_error("uri error.")); } if (!port.empty()) { if (!validate_port(port)) { JSONCONS_THROW(std::system_error(uri_errc::invalid_port)); } uri_string_.append(":"); port_part_.first = uri_string_.length(); uri_string_.append(port.data(), port.size()); port_part_.second = uri_string_.length(); } else { port_part_.first = port_part_.second = uri_string_.length(); } } else { userinfo_part_.first = userinfo_part_.second = uri_string_.length(); host_part_.first = host_part_.second = uri_string_.length(); port_part_.first = port_part_.second = uri_string_.length(); if (!scheme.empty()) { if (!path.empty() || !query.empty() || !fragment.empty()) { uri_string_.append(":"); } else { JSONCONS_THROW(json_runtime_error("uri error.")); } } } if (!path.empty()) { // if the URI is not opaque and the path is not already prefixed // with a '/', add one. path_part_.first = uri_string_.length(); if (!host.empty() && (path.front() != '/')) { uri_string_.push_back('/'); } encode_path(path, uri_string_); path_part_.second = uri_string_.length(); } else { path_part_.first = path_part_.second = uri_string_.length(); } if (!query.empty()) { uri_string_.append("?"); query_part_.first = uri_string_.length(); encode_illegal_characters(query, uri_string_); query_part_.second = uri_string_.length(); } else { query_part_.first = query_part_.second = uri_string_.length(); } if (!fragment.empty()) { uri_string_.append("#"); fragment_part_.first = uri_string_.length(); encode_illegal_characters(fragment, uri_string_); fragment_part_.second = uri_string_.length(); } else { fragment_part_.first = fragment_part_.second = uri_string_.length(); } } uri(uri_encoded_part_t, jsoncons::string_view scheme, jsoncons::string_view userinfo, jsoncons::string_view host, jsoncons::string_view port, jsoncons::string_view path, jsoncons::string_view query, jsoncons::string_view fragment) { if (!scheme.empty()) { uri_string_.append(scheme.data(), scheme.size()); scheme_part_.second = uri_string_.length(); } if (!userinfo.empty() || !host.empty() || !port.empty()) { if (!scheme.empty()) { uri_string_.append("://"); } if (!userinfo.empty()) { userinfo_part_.first = uri_string_.length(); uri_string_.append(userinfo.data(), userinfo.size()); userinfo_part_.second = uri_string_.length(); uri_string_.append("@"); } else { userinfo_part_.first = userinfo_part_.second = uri_string_.length(); } if (!host.empty()) { host_part_.first = uri_string_.length(); uri_string_.append(host.data(), host.size()); host_part_.second = uri_string_.length(); } else { JSONCONS_THROW(json_runtime_error("uri error.")); } if (!port.empty()) { uri_string_.append(":"); port_part_.first = uri_string_.length(); uri_string_.append(port.data(), port.size()); port_part_.second = uri_string_.length(); } else { port_part_.first = port_part_.second = uri_string_.length(); } } else { userinfo_part_.first = userinfo_part_.second = uri_string_.length(); host_part_.first = host_part_.second = uri_string_.length(); port_part_.first = port_part_.second = uri_string_.length(); if (!scheme.empty()) { if (!path.empty() || !query.empty() || !fragment.empty()) { uri_string_.append(":"); } else { JSONCONS_THROW(json_runtime_error("uri error.")); } } } if (!path.empty()) { // if the URI is not opaque and the path is not already prefixed // with a '/', add one. path_part_.first = uri_string_.length(); if (!host.empty() && (path.front() != '/')) { uri_string_.push_back('/'); } uri_string_.append(path.data(), path.size()); path_part_.second = uri_string_.length(); } else { path_part_.first = path_part_.second = uri_string_.length(); } if (!query.empty()) { uri_string_.append("?"); query_part_.first = uri_string_.length(); uri_string_.append(query.data(), query.size()); query_part_.second = uri_string_.length(); } else { query_part_.first = query_part_.second = uri_string_.length(); } if (!fragment.empty()) { uri_string_.append("#"); fragment_part_.first = uri_string_.length(); uri_string_.append(fragment.data(), fragment.size()); fragment_part_.second = uri_string_.length(); } else { fragment_part_.first = fragment_part_.second = uri_string_.length(); } } uri& operator=(const uri& other) { if (&other != this) { uri_string_ = other.uri_string_; scheme_part_ = other.scheme_part_; userinfo_part_ = other.userinfo_part_; host_part_ = other.host_part_; port_part_ = other.port_part_; path_part_ = other.path_part_; query_part_ = other.query_part_; fragment_part_ = other.fragment_part_; } return *this; } uri& operator=(uri&& other) noexcept { if (&other != this) { uri_string_ = std::move(other.uri_string_); scheme_part_ = other.scheme_part_; userinfo_part_ = other.userinfo_part_; host_part_ = other.host_part_; port_part_ = other.port_part_; path_part_ = other.path_part_; query_part_ = other.query_part_; fragment_part_ = other.fragment_part_; } return *this; } const std::string& string() const noexcept { return uri_string_; } bool is_absolute() const noexcept { return scheme_part_.second > scheme_part_.first; } bool is_opaque() const noexcept { return is_absolute() && !encoded_authority().empty(); } uri base() const noexcept { return uri{uri_encoded_part, scheme(), encoded_userinfo(), host(), port(), encoded_path(), jsoncons::string_view{}, jsoncons::string_view{}}; } string_view scheme() const noexcept { return string_view(uri_string_.data()+scheme_part_.first,(scheme_part_.second-scheme_part_.first)); } std::string userinfo() const { return decode_part(encoded_userinfo()); } string_view encoded_userinfo() const noexcept { return string_view(uri_string_.data()+userinfo_part_.first,(userinfo_part_.second-userinfo_part_.first)); } string_view host() const noexcept { return string_view(uri_string_.data()+host_part_.first,(host_part_.second-host_part_.first)); } string_view port() const noexcept { return string_view(uri_string_.data()+port_part_.first,(port_part_.second-port_part_.first)); } std::string authority() const { return decode_part(encoded_authority()); } string_view encoded_authority() const noexcept { return string_view(uri_string_.data()+userinfo_part_.first,(port_part_.second-userinfo_part_.first)); } std::string path() const { return decode_part(encoded_path()); } string_view encoded_path() const noexcept { return string_view(uri_string_.data()+path_part_.first,(path_part_.second-path_part_.first)); } std::string query() const { return decode_part(encoded_query()); } string_view encoded_query() const noexcept { return string_view(uri_string_.data()+query_part_.first,(query_part_.second-query_part_.first)); } std::string fragment() const { return decode_part(encoded_fragment()); } string_view encoded_fragment() const noexcept { return string_view(uri_string_.data()+fragment_part_.first,(fragment_part_.second-fragment_part_.first)); } bool has_scheme() const noexcept { return !scheme().empty(); } bool has_userinfo() const noexcept { return !encoded_userinfo().empty(); } bool has_authority() const noexcept { return !encoded_authority().empty(); } bool has_host() const noexcept { return !host().empty(); } bool has_port() const noexcept { return !port().empty(); } bool has_path() const noexcept { return !encoded_path().empty(); } bool has_query() const noexcept { return !encoded_query().empty(); } bool has_fragment() const noexcept { return !encoded_fragment().empty(); } uri resolve(string_view reference) const { return resolve(uri(reference)); } uri resolve(const uri& reference) const { // This implementation uses the psuedo-code given in // http://tools.ietf.org/html/rfc3986#section-5.2.2 if (reference.is_absolute() && !reference.is_opaque()) { return reference; } if (reference.is_opaque()) { return reference; } std::string userinfo, host, port, path, query, fragment; if (reference.has_authority()) { // g -> http://g if (reference.has_userinfo()) { userinfo = std::string(reference.encoded_userinfo()); } if (reference.has_host()) { host = std::string(reference.host()); } if (reference.has_port()) { port = std::string(reference.port()); } if (reference.has_path()) { path = remove_dot_segments(std::string(reference.encoded_path())); } if (reference.has_query()) { query = std::string(reference.encoded_query()); } } else { if (!reference.has_path()) { if (has_path()) { path = std::string(encoded_path()); } if (reference.has_query()) { query = std::string(reference.encoded_query()); } else if (has_query()) { query = std::string(encoded_query()); } } else { if (reference.encoded_path().front() == '/') { path = remove_dot_segments(std::string(reference.encoded_path())); } else { path = merge_paths(*this, reference); } if (reference.has_query()) { query = std::string(reference.encoded_query()); } } if (has_userinfo()) { userinfo = std::string(encoded_userinfo()); } if (has_host()) { host = std::string(this->host()); } if (has_port()) { port = std::string(this->port()); } } if (reference.has_fragment()) { fragment = std::string(reference.encoded_fragment()); } return uri(uri_encoded_part, std::string(scheme()), userinfo, host, port, path, query, fragment); } int compare(const uri& other) const { int result = scheme().compare(other.scheme()); if (result != 0) return result; result = encoded_userinfo().compare(other.encoded_userinfo()); if (result != 0) return result; result = host().compare(other.host()); if (result != 0) return result; result = port().compare(other.port()); if (result != 0) return result; result = encoded_path().compare(other.encoded_path()); if (result != 0) return result; result = encoded_query().compare(other.encoded_query()); if (result != 0) return result; result = encoded_fragment().compare(other.encoded_fragment()); return result; } friend bool operator==(const uri& lhs, const uri& rhs) { return lhs.compare(rhs) == 0; } friend bool operator!=(const uri& lhs, const uri& rhs) { return lhs.compare(rhs) != 0; } friend bool operator<(const uri& lhs, const uri& rhs) { return lhs.compare(rhs) < 0; } friend bool operator<=(const uri& lhs, const uri& rhs) { return lhs.compare(rhs) <= 0; } friend bool operator>(const uri& lhs, const uri& rhs) { return lhs.compare(rhs) > 0; } friend bool operator>=(const uri& lhs, const uri& rhs) { return lhs.compare(rhs) >= 0; } static std::string decode_part(const jsoncons::string_view& encoded) { std::string decoded; std::size_t length = encoded.size(); for (std::size_t i = 0; i < length;) { if (encoded[i] == '%' && (length - i) >= 3) { auto hex = encoded.substr(i + 1, 2); uint8_t n; jsoncons::detail::hex_to_integer(hex.data(), hex.size(), n); decoded.push_back((char)n); i += 3; } else { decoded.push_back(encoded[i]); ++i; } } return decoded; } static uri parse(string_view str, std::error_code& ec) { part_type scheme_part{ 0,0 }; part_type userinfo_part{0,0}; part_type host_part{0,0}; part_type port_part{0,0}; part_type path_part{0,0}; part_type query_part{0,0}; part_type fragment_part{0,0}; std::size_t start = 0; parse_state state = parse_state::start; std::size_t colon_pos = 0; std::size_t i = 0; while (i < str.size()) { char c = str[i]; switch (state) { case parse_state::start: switch (c) { case '/': state = parse_state::expect_path; break; case '#': state = parse_state::expect_fragment; start = ++i; break; default: state = parse_state::expect_scheme; break; } break; case parse_state::expect_scheme: switch (c) { case ':': if (!validate_scheme(string_view{str.data() + start, i-start})) { ec = uri_errc::invalid_character_in_scheme; return uri{}; } else { scheme_part = std::make_pair(start,i); state = parse_state::expect_first_slash; start = i; } ++i; break; case '?': path_part = std::make_pair(start, i); state = parse_state::expect_query; start = i + 1; ++i; break; case '#': userinfo_part = std::make_pair(start,start); host_part = std::make_pair(start,start); port_part = std::make_pair(start,start); path_part = std::make_pair(start,i); query_part = std::make_pair(i,i); state = parse_state::expect_fragment; start = i+1; ++i; break; default: if (++i == str.size()) // end of string, haven't found a colon, try path_part { i = 0; state = parse_state::expect_path; } break; } break; case parse_state::expect_first_slash: switch (c) { case '/': state = parse_state::expect_second_slash; ++i; break; default: start = i; state = parse_state::expect_path; ++i; break; } break; case parse_state::expect_second_slash: switch (c) { case '/': state = parse_state::expect_authority; start = i+1; ++i; break; default: ++i; break; } break; case parse_state::expect_authority: switch (c) { case '[': state = parse_state::expect_host_ipv6; start = i+1; ++i; break; default: state = parse_state::expect_userinfo; start = i; // i unchanged; break; } break; case parse_state::expect_host_ipv6: switch (c) { case ']': userinfo_part = std::make_pair(start,start); host_part = std::make_pair(start,i); port_part = std::make_pair(i,i); state = parse_state::expect_path; start = i+1; ++i; break; default: ++i; break; } break; case parse_state::expect_userinfo: switch (c) { case '@': if (!validate_userinfo(string_view{str.data() + start, i-start})) { ec = uri_errc::invalid_character_in_userinfo; return uri{}; } userinfo_part = std::make_pair(start,i); state = parse_state::expect_host; start = i+1; ++i; break; case ':': colon_pos = i; state = parse_state::expect_password; ++i; break; case '/': userinfo_part = std::make_pair(start,start); host_part = std::make_pair(start,i); port_part = std::make_pair(i,i); state = parse_state::expect_path; start = i; ++i; break; default: ++i; break; } break; case parse_state::expect_password: switch (c) { case '@': if (!validate_host(string_view{str.data() + start, i-start})) { ec = uri_errc::invalid_character_in_host; return uri{}; } userinfo_part = std::make_pair(start,i); state = parse_state::expect_host; start = i+1; ++i; break; case '/': { if (!validate_host(string_view{str.data() + start, colon_pos-start})) { ec = uri_errc::invalid_character_in_host; return uri{}; } if (!validate_port(string_view{str.data() + (colon_pos+1), i-(colon_pos+1)})) { ec = uri_errc::invalid_port; return uri{}; } userinfo_part = std::make_pair(start,start); host_part = std::make_pair(start,colon_pos); port_part = std::make_pair(colon_pos+1,i); state = parse_state::expect_path; start = i; ++i; break; } default: ++i; break; } break; case parse_state::expect_host: switch (c) { case ':': if (!validate_host(string_view{str.data() + start, i-start})) { ec = uri_errc::invalid_character_in_host; return uri{}; } host_part = std::make_pair(start,i); state = parse_state::expect_port; start = i+1; ++i; break; default: ++i; break; } break; case parse_state::expect_port: switch (c) { case '/': if (!validate_port(string_view{str.data() + start, i-start})) { ec = uri_errc::invalid_port; return uri{}; } port_part = std::make_pair(start,i); state = parse_state::expect_path; start = i; ++i; break; default: ++i; break; } break; case parse_state::expect_path: switch (c) { case '?': path_part = std::make_pair(start,i); state = parse_state::expect_query; start = i+1; ++i; break; case '#': path_part = std::make_pair(start,i); query_part = std::make_pair(i,i); state = parse_state::expect_fragment; start = i+1; ++i; break; default: { auto first = str.cbegin() + i; auto result = is_pchar(first, str.cend()); if (result.second) { i += (result.first - first); } else if (c == '/') { ++i; } else { ec = uri_errc::invalid_character_in_path; return uri{}; } break; } } break; case parse_state::expect_query: switch (c) { case '#': query_part = std::make_pair(start,i); state = parse_state::expect_fragment; start = i+1; ++i; break; default: ++i; break; } break; case parse_state::expect_fragment: ++i; break; } } switch (state) { case parse_state::expect_userinfo: userinfo_part = std::make_pair(start,start); if (!validate_host(string_view{str.data() + start, str.size()-start})) { ec = uri_errc::invalid_character_in_host; return uri{}; } host_part = std::make_pair(start,str.size()); port_part = std::make_pair(str.size(), str.size()); path_part = std::make_pair(str.size(), str.size()); query_part = std::make_pair(str.size(), str.size()); fragment_part = std::make_pair(str.size(), str.size()); break; case parse_state::expect_password: userinfo_part = std::make_pair(start,start); if (!validate_host(string_view{str.data() + start, colon_pos-start})) { ec = uri_errc::invalid_character_in_host; return uri{}; } host_part = std::make_pair(start,colon_pos); if (!validate_port(string_view{str.data() + (colon_pos+1), str.size() - (colon_pos+1)})) { ec = uri_errc::invalid_port; return uri{}; } port_part = std::make_pair(colon_pos+1, str.size()); path_part = std::make_pair(str.size(), str.size()); query_part = std::make_pair(str.size(), str.size()); fragment_part = std::make_pair(str.size(), str.size()); break; case parse_state::expect_host: if (!validate_host(string_view{str.data() + start, str.size()-start})) { ec = uri_errc::invalid_character_in_host; return uri{}; } host_part = std::make_pair(start, str.size()); port_part = std::make_pair(str.size(), str.size()); path_part = std::make_pair(str.size(), str.size()); query_part = std::make_pair(str.size(), str.size()); fragment_part = std::make_pair(str.size(), str.size()); break; case parse_state::expect_port: if (!validate_port(string_view{str.data() + start, str.size() - start})) { ec = uri_errc::invalid_port; return uri{}; } port_part = std::make_pair(start, str.size()); path_part = std::make_pair(str.size(), str.size()); query_part = std::make_pair(str.size(), str.size()); fragment_part = std::make_pair(str.size(), str.size()); break; case parse_state::expect_path: path_part = std::make_pair(start,str.size()); query_part = std::make_pair(str.size(), str.size()); fragment_part = std::make_pair(str.size(), str.size()); break; case parse_state::expect_query: query_part = std::make_pair(start,str.size()); fragment_part = std::make_pair(str.size(), str.size()); break; case parse_state::expect_fragment: fragment_part = std::make_pair(start,str.size()); if (!validate_fragment(string_view{str.data() + fragment_part.first, (fragment_part.second - fragment_part.first)})) { ec = uri_errc::invalid_character_in_fragment; return uri{}; } break; default: ec = uri_errc::invalid_uri; break; } return uri(std::string(str), scheme_part, userinfo_part, host_part, port_part, path_part, query_part, fragment_part); } private: enum class parse_state { start, expect_scheme, expect_first_slash, expect_second_slash, expect_authority, expect_host_ipv6, expect_userinfo, expect_password, expect_host, expect_port, expect_path, expect_query, expect_fragment}; uri(const std::string& uri, part_type scheme, part_type userinfo, part_type host, part_type port, part_type path, part_type query, part_type fragment) : uri_string_(uri), scheme_part_(scheme), userinfo_part_(userinfo), host_part_(host), port_part_(port), path_part_(path), query_part_(query), fragment_part_(fragment) { } /* 5.2.4. Remove Dot Segments The pseudocode also refers to a "remove_dot_segments" routine for interpreting and removing the special "." and ".." complete path segments from a referenced path. This is done after the path is extracted from a reference, whether or not the path was relative, in order to remove any invalid or extraneous dot-segments prior to forming the target URI. Although there are many ways to accomplish this removal process, we describe a simple method using two string buffers. 1. The input buffer is initialized with the now-appended path components and the output buffer is initialized to the empty string. 2. While the input buffer is not empty, loop as follows: A. If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise, B. if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise, C. if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise, D. if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise, E. move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer. 3. Finally, the output buffer is returned as the result of remove_dot_segments. */ static std::string remove_dot_segments(std::string input) { std::string output; std::size_t rel = 0; const std::size_t buflen = input.size(); while (rel < buflen) { char* data = &input[0]+rel; const std::size_t length = buflen - rel; if (length >= 3 && data[0] == '.' && data[1] == '.' && data[2] == '/') { rel += 3; } else if (length >= 2 && data[0] == '.' && data[1] == '/') { rel += 2; } else if (length >= 3 && data[0] == '/' && data[1] == '.' && data[2] == '/') { rel += 2; data[2] = '/'; } else if (length == 2 && data[0] == '/' && data[1] == '.') { ++rel; data[1] = '/'; } else if (length >= 4 && data[0] == '/' && data[1] == '.' && data[2] == '.' && data[3] == '/') { rel += 3; data[3] = '/'; auto rslash = output.rfind('/'); if (rslash != std::string::npos) { output.erase(rslash); } } else if (length >= 3 && data[0] == '/' && data[1] == '.' && data[2] == '.') { rel += 2; data[2] = '/'; auto rslash = output.rfind('/'); if (rslash != std::string::npos) { output.erase(rslash); } } else if (length == 1 && data[0] == '.') { ++rel; } else if (length == 2 && data[0] == '.' && data[1] == '.') { rel += 2; } else { const auto last = data+length; auto it = std::find(data+1, last, '/'); if (it != last) { output.append(data, it - data); rel += (it - data); } else { output.append(data, length); rel += length; } } } //std::cout << "path: " << path << ", output: " << output << "\n"; return output; } static std::string merge_paths(const uri& base, const uri& relative) { std::string result; if (!base.encoded_authority().empty() && base.encoded_path().empty()) { result = "/"; //result.append(relative.encoded_path().data(), relative.encoded_path().length()); } else { const auto& base_path = base.encoded_path(); auto last_slash = base_path.rfind('/'); result.append(std::string(base_path.substr(0,last_slash+1))); } if (!relative.encoded_path().empty()) { result.append(relative.encoded_path().begin(), relative.encoded_path().end()); } return remove_dot_segments(std::move(result)); } static bool is_alpha(char ch) { return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); } static bool is_digit(char ch) { return (ch >= '0' && ch <= '9'); } static bool is_alphanum(char ch) { return is_alpha(ch) || is_digit(ch); } static bool is_unreserved(char ch) { switch (ch) { case '_': case '-': case '!': case '.': case '~': case '\'': case '(': case ')': case '*': return true; default: return is_alphanum(ch); } } static bool is_punct(char ch) { switch (ch) { case ',': case ';': case ':': case '$': case '&': case '+': case '=': return true; default: return false; } } static bool is_reserved(char ch) { switch (ch) { case '?': case '/': case '[': case ']': case '@': return true; default: return is_punct(ch); } } static bool is_hex(char ch) { switch(ch) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': case 'a':case 'b':case 'c':case 'd':case 'e':case 'f': case 'A':case 'B':case 'C':case 'D':case 'E':case 'F': return true; default: return false; } } static bool is_pct_encoded(const char* s, std::size_t length) { return length < 3 ? false : s[0] == '%' && is_hex(s[1]) && is_hex(s[2]); } // sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "=" static bool is_sub_delim(char c) { switch (c) { case '!': return true; case '$': return true; case '&': return true; case '\'': return true; case '(': return true; case ')': return true; case '*': return true; case '+': return true; case ',': return true; case ';': return true; case '=': return true; default: return false; } } public: // Any character not in the unreserved, punct or escaped categories, and not equal // to the slash character ('/') or the commercial-at character ('@'), is quoted. static void encode_path(const jsoncons::string_view& sv, std::string& encoded) { const std::size_t length1 = sv.size() <= 2 ? 0 : sv.size() - 2; std::size_t i = 0; for (; i < length1; ++i) { char ch = sv[i]; switch (ch) { case '/': case '@': encoded.push_back(sv[i]); break; default: { bool escaped = is_pct_encoded(sv.data()+i,3); if (!is_unreserved(ch) && !is_punct(ch) && !escaped) { encoded.push_back('%'); if (uint8_t(ch) <= 15) { encoded.push_back('0'); } jsoncons::detail::integer_to_hex((uint8_t)ch, encoded); } else if (escaped) { encoded.push_back(ch); encoded.push_back(sv[++i]); encoded.push_back(sv[++i]); } else { encoded.push_back(ch); } break; } } } const std::size_t length2 = sv.size(); for (; i < length2; ++i) { char ch = sv[i]; switch (ch) { case '/': case '@': encoded.push_back(ch); break; default: { if (!is_unreserved(ch) && !is_punct(ch)) { encoded.push_back('%'); jsoncons::detail::integer_to_hex((uint8_t)ch, encoded); } else { encoded.push_back(ch); } break; } } } } // Any character not in the unreserved, punct, or escaped categories is quoted. static void encode_userinfo(const jsoncons::string_view& sv, std::string& encoded) { const std::size_t length1 = sv.size() <= 2 ? 0 : sv.size() - 2; std::size_t i = 0; for (; i < length1; ++i) { char ch = sv[i]; bool escaped = is_pct_encoded(sv.data()+i,3); if (!is_unreserved(ch) && !is_punct(ch) && !escaped) { encoded.push_back('%'); if (uint8_t(ch) <= 15) { encoded.push_back('0'); } jsoncons::detail::integer_to_hex((uint8_t)ch, encoded); } else if (escaped) { encoded.push_back(ch); encoded.push_back(sv[++i]); encoded.push_back(sv[++i]); } else { encoded.push_back(ch); } } const std::size_t length2 = sv.size(); for (; i < length2; ++i) { char ch = sv[i]; if (!is_unreserved(ch) && !is_punct(ch)) { encoded.push_back('%'); jsoncons::detail::integer_to_hex((uint8_t)ch, encoded); } else { encoded.push_back(ch); } } } // The set of all legal URI characters consists of the unreserved, reserved, escaped characters. static void encode_illegal_characters(const jsoncons::string_view& sv, std::string& encoded) { const std::size_t length1 = sv.size() <= 2 ? 0 : sv.size() - 2; std::size_t i = 0; for (; i < length1; ++i) { char ch = sv[i]; bool escaped = is_pct_encoded(sv.data()+i,3); if (!is_unreserved(ch) && !is_reserved(ch) && !escaped) { encoded.push_back('%'); if (uint8_t(ch) <= 15) { encoded.push_back('0'); } jsoncons::detail::integer_to_hex((uint8_t)ch, encoded); } else if (escaped) { encoded.push_back(ch); encoded.push_back(sv[++i]); encoded.push_back(sv[++i]); } else { encoded.push_back(ch); } } const std::size_t length2 = sv.size(); for (; i < length2; ++i) { char ch = sv[i]; if (!is_unreserved(ch) && !is_reserved(ch)) { encoded.push_back('%'); jsoncons::detail::integer_to_hex((uint8_t)ch, encoded); } else { encoded.push_back(ch); } } } // rel_segment = 1*( unreserved | escaped | ";" | "@" | "&" | "=" | "+" | "$" | "," ) static bool is_rel_segment(char c, const char* s, std::size_t length) { return is_unreserved(c) || is_pct_encoded(s,length) || c == ';' || c == '@' || c == '&' || c == '=' || c == '+' || c == '$' || c == ','; } // userinfo = *( unreserved | escaped | ";" | ":" | "&" | "=" | "+" | "$" | "," ) static bool is_userinfo(char c, const char* s, std::size_t length) { return is_unreserved(c) || is_pct_encoded(s,length) || c == ';' || c == ':' || c == '&' || c == '=' || c == '+' || c == '$' || c == ','; } static std::pair is_pct_encoded(string_view::const_iterator first, string_view::const_iterator last) { if ((last-first) < 3) { return std::pair{first+1,false}; } bool result = first[0] == '%' && is_hex(first[1]) && is_hex(first[2]); return result ? std::pair{first+3,true} : std::pair{first+1,false}; } static std::pair is_pchar(string_view::iterator first, string_view::iterator last) { JSONCONS_ASSERT(first != last); const char c = *first; if (is_unreserved(c)) { return std::pair{first+1,true}; } auto result = is_pct_encoded(first,last); if (result.second) { return result; } return std::pair{first+1,is_sub_delim(c) || c == ':' || c == '@'}; } static bool validate_fragment(string_view fragment) { if (fragment.length() == 0) { return true; } bool valid = true; auto cur = fragment.begin(); auto last = fragment.end(); while (valid && cur != last) { auto result = is_pchar(cur,last); if (!result.second && !(*cur == '?' || *cur == '/')) { valid = false; } else { cur = result.first; } } return valid; } static bool validate_userinfo(string_view userinfo) { if (userinfo.length() == 0) { return true; } bool valid = true; auto cur = userinfo.begin(); auto last = userinfo.end(); while (valid && cur != last) { auto unreserved = is_unreserved(*cur); auto pct_encoded = is_pct_encoded(cur,last); auto sub_delim = is_sub_delim(*cur); if (!unreserved && !pct_encoded.second && !sub_delim && !(*cur == ':')) { valid = false; } if (pct_encoded.second) { cur = pct_encoded.first; } else { ++cur; } } return valid; } static bool validate_port(string_view port) { uint16_t p; auto result = jsoncons::detail::to_integer(port.data(), port.length(), p); return static_cast(result); } static bool validate_host(string_view userinfo) { if (userinfo.length() == 0) { return true; } bool valid = true; auto cur = userinfo.begin(); auto last = userinfo.end(); while (valid && cur != last) { if (*cur == ' ') { valid = false; } ++cur; } return valid; } static bool validate_scheme(string_view scheme) { if (scheme.length() == 0) { return true; } bool valid = isalpha(scheme[0]); auto cur = scheme.begin(); auto last = scheme.end(); while (valid && cur != last) { char c = *cur; if (!(isalnum(c) || c == '+' || c == '.' || c == '-')) { valid = false; } ++cur; } return valid; } friend std::ostream& operator<<(std::ostream& os, const uri& a_uri) { return os << a_uri.string(); } }; } // namespace jsoncons #endif // JSONCONS_UTILITY_URI_HPP jsoncons-1.3.2/include/jsoncons/value_converter.hpp000066400000000000000000000303601477700171100225530ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_VALUE_CONVERTER_HPP #define JSONCONS_VALUE_CONVERTER_HPP #include #include #include // std::error_code #include #include #include #include // from_integer #include #include #include #include namespace jsoncons { template class value_converter { }; template class value_converter_base { public: using allocator_type = typename std::conditional::value,typename Into::allocator_type, std::allocator>::type; private: allocator_type alloc_; public: value_converter_base(const allocator_type& alloc = allocator_type()) : alloc_(alloc) { } allocator_type get_allocator() const noexcept { return alloc_; } }; // From any byte sequence, Into string template class value_converter::value && !extension_traits::is_string_or_string_view::value && extension_traits::is_string::value>::type> : value_converter_base { public: using allocator_type = typename value_converter_base::allocator_type; template typename std::enable_if::value,Into>::type convert(const From& value, semantic_tag tag, std::error_code&) { Into s(this->get_allocator()); switch (tag) { case semantic_tag::base64: encode_base64(value.begin(), value.end(), s); break; case semantic_tag::base16: encode_base16(value.begin(), value.end(), s); break; default: encode_base64url(value.begin(), value.end(), s); break; } return s; } template typename std::enable_if::value,Into>::type convert(const From& value, semantic_tag tag, std::error_code& ec) { std::string s; switch (tag) { case semantic_tag::base64: encode_base64(value.begin(), value.end(), s); break; case semantic_tag::base16: encode_base16(value.begin(), value.end(), s); break; default: encode_base64url(value.begin(), value.end(), s); break; } Into ws(this->get_allocator()); auto retval = unicode_traits::convert(s.data(), s.size(), ws); if (retval.ec != unicode_traits::conv_errc()) { ec = conv_errc::not_wide_char; } return ws; } }; // From byte string, Into byte string template class value_converter::value && !extension_traits::is_string_or_string_view::value && !extension_traits::is_string_or_string_view::value && extension_traits::is_back_insertable_byte_container::value>::type> : value_converter_base { public: using allocator_type = typename value_converter_base::allocator_type; Into convert(const From& value, semantic_tag, std::error_code&) { Into s(value.begin(),value.end(),this->get_allocator()); return s; } }; // From string or string_view, Into string, same character type template class value_converter::value && extension_traits::is_string::value && std::is_same::value>::type> : value_converter_base { public: using allocator_type = typename value_converter_base::allocator_type; Into convert(const From& value, semantic_tag, std::error_code&) { return Into(value.begin(),value.end(),this->get_allocator()); } }; // From string or string_view, Into string, different character type template class value_converter::value && extension_traits::is_string::value && !std::is_same::value>::type> : value_converter_base { public: using allocator_type = typename value_converter_base::allocator_type; Into convert(const From& value, semantic_tag, std::error_code& ec) { Into ws(this->get_allocator()); auto retval = unicode_traits::convert(value.data(), value.size(), ws); if (retval.ec != unicode_traits::conv_errc()) { ec = conv_errc::not_wide_char; } return ws; } }; // From string, Into byte_string template class value_converter::value && !extension_traits::is_string_or_string_view::value && extension_traits::is_back_insertable_byte_container::value>::type> : value_converter_base { public: using allocator_type = typename value_converter_base::allocator_type; template typename std::enable_if::value,Into>::type convert(const From& value, semantic_tag tag, std::error_code& ec) { Into bytes(this->get_allocator()); switch (tag) { case semantic_tag::base16: { auto res = decode_base16(value.begin(), value.end(), bytes); if (res.ec != conv_errc::success) { ec = conv_errc::not_byte_string; } break; } case semantic_tag::base64: { decode_base64(value.begin(), value.end(), bytes); break; } case semantic_tag::base64url: { decode_base64url(value.begin(), value.end(), bytes); break; } default: { ec = conv_errc::not_byte_string; break; } } return bytes; } template typename std::enable_if::value,Into>::type convert(const From& value, semantic_tag tag, std::error_code& ec) { Into bytes(this->get_allocator()); std::string s(this->get_allocator()); auto retval = unicode_traits::convert(value.data(), value.size(), s); if (retval.ec != unicode_traits::conv_errc()) { ec = conv_errc::not_wide_char; } switch (tag) { case semantic_tag::base16: { auto res = decode_base16(s.begin(), s.end(), bytes); if (res.ec != conv_errc::success) { ec = conv_errc::not_byte_string; } break; } case semantic_tag::base64: { decode_base64(s.begin(), s.end(), bytes); break; } case semantic_tag::base64url: { decode_base64url(s.begin(), s.end(), bytes); break; } default: { ec = conv_errc::not_byte_string; break; } } return bytes; } }; // From integer, Into string template class value_converter::value && extension_traits::is_string::value>::type> : value_converter_base { public: using allocator_type = typename value_converter_base::allocator_type; Into convert(From value, semantic_tag, std::error_code&) { Into s(this->get_allocator()); jsoncons::detail::from_integer(value, s); return s; } }; // From integer, Into string template class value_converter::value && extension_traits::is_string::value>::type> : value_converter_base { public: using allocator_type = typename value_converter_base::allocator_type; Into convert(From value, semantic_tag, std::error_code&) { Into s(this->get_allocator()); jsoncons::detail::write_double f{float_chars_format::general,0}; f(value, s); return s; } }; // From half, Into string template class value_converter::value>::type> : value_converter_base { public: using allocator_type = typename value_converter_base::allocator_type; Into convert(uint16_t value, semantic_tag, std::error_code&) { Into s(this->get_allocator()); jsoncons::detail::write_double f{float_chars_format::general,0}; double x = binary::decode_half(value); f(x, s); return s; } }; // From bool, Into string template class value_converter::value && extension_traits::is_string::value>::type> : value_converter_base { public: using allocator_type = typename value_converter_base::allocator_type; using char_type = typename Into::value_type; JSONCONS_CPP14_CONSTEXPR Into convert(From value, semantic_tag, std::error_code&) { constexpr const char_type* true_constant = JSONCONS_CSTRING_CONSTANT(char_type,"true"); constexpr const char_type* false_constant = JSONCONS_CSTRING_CONSTANT(char_type,"false"); return value ? Into(true_constant,4) : Into(false_constant,5); } }; // From null, Into string template class value_converter : value_converter_base { public: using allocator_type = typename value_converter_base::allocator_type; using char_type = typename Into::value_type; JSONCONS_CPP14_CONSTEXPR Into convert(semantic_tag, std::error_code&) { constexpr const char_type* null_constant = JSONCONS_CSTRING_CONSTANT(char_type,"null"); return Into(null_constant,4); } }; } // namespace jsoncons #endif // JSONCONS_VALUE_CONVERTER_HPP jsoncons-1.3.2/include/jsoncons_ext/000077500000000000000000000000001477700171100175155ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons_ext/bson/000077500000000000000000000000001477700171100204565ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons_ext/bson/bson.hpp000066400000000000000000000011121477700171100221230ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_BSON_BSON_HPP #define JSONCONS_EXT_BSON_BSON_HPP #include #include #include #include #include #endif // JSONCONS_EXT_BSON_BSON_HPP jsoncons-1.3.2/include/jsoncons_ext/bson/bson_cursor.hpp000066400000000000000000000160701477700171100235310ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_BSON_BSON_CURSOR_HPP #define JSONCONS_EXT_BSON_BSON_CURSOR_HPP #include #include #include // std::allocator #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace bson { template > class basic_bson_cursor : public basic_staj_cursor, private virtual ser_context { using super_type = basic_staj_cursor; public: using source_type = Source; using char_type = char; using allocator_type = Allocator; private: basic_bson_parser parser_; basic_staj_visitor cursor_visitor_; bool eof_{false}; public: using string_view_type = string_view; // Noncopyable and nonmoveable basic_bson_cursor(const basic_bson_cursor&) = delete; basic_bson_cursor(basic_bson_cursor&&) = delete; template basic_bson_cursor(Sourceable&& source, const bson_decode_options& options = bson_decode_options(), const Allocator& alloc = Allocator()) : parser_(std::forward(source), options, alloc) { parser_.cursor_mode(true); if (!done()) { next(); } } // Constructors that set parse error codes template basic_bson_cursor(Sourceable&& source, std::error_code& ec) : basic_bson_cursor(std::allocator_arg, Allocator(), std::forward(source), bson_decode_options(), ec) { } template basic_bson_cursor(Sourceable&& source, const bson_decode_options& options, std::error_code& ec) : basic_bson_cursor(std::allocator_arg, Allocator(), std::forward(source), options, ec) { } template basic_bson_cursor(std::allocator_arg_t, const Allocator& alloc, Sourceable&& source, const bson_decode_options& options, std::error_code& ec) : parser_(std::forward(source), options, alloc) { parser_.cursor_mode(true); if (!done()) { next(ec); } } ~basic_bson_cursor() = default; basic_bson_cursor& operator=(const basic_bson_cursor&) = delete; basic_bson_cursor& operator=(basic_bson_cursor&&) = delete; void reset() { parser_.reset(); cursor_visitor_.reset(); eof_ = false; if (!done()) { next(); } } template void reset(Sourceable&& source) { parser_.reset(std::forward(source)); cursor_visitor_.reset(); eof_ = false; if (!done()) { next(); } } void reset(std::error_code& ec) { parser_.reset(); cursor_visitor_.reset(); eof_ = false; if (!done()) { next(ec); } } template void reset(Sourceable&& source, std::error_code& ec) { parser_.reset(std::forward(source)); cursor_visitor_.reset(); eof_ = false; if (!done()) { next(ec); } } bool done() const override { return parser_.done(); } void array_expected(std::error_code& ec) override { if (cursor_visitor_.event().event_type() == staj_event_type::begin_object) { parser_.array_expected(cursor_visitor_, ec); } else { super_type::array_expected(ec); } } const staj_event& current() const override { return cursor_visitor_.event(); } void read_to(basic_json_visitor& visitor) override { std::error_code ec; read_to(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); } } void read_to(basic_json_visitor& visitor, std::error_code& ec) override { if (is_begin_container(current().event_type())) { parser_.cursor_mode(false); parser_.mark_level(parser_.level()); cursor_visitor_.event().send_json_event(visitor, *this, ec); if (JSONCONS_UNLIKELY(ec)) { return; } read_next(visitor, ec); parser_.cursor_mode(true); parser_.mark_level(0); if (current().event_type() == staj_event_type::begin_object) { cursor_visitor_.end_object(*this); } else { cursor_visitor_.end_array(*this); } } else { cursor_visitor_.event().send_json_event(visitor, *this, ec); } } void next() override { std::error_code ec; next(ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); } } void next(std::error_code& ec) override { read_next(ec); } const ser_context& context() const override { return *this; } bool eof() const { return eof_; } std::size_t line() const override { return parser_.line(); } std::size_t column() const override { return parser_.column(); } friend staj_filter_view operator|(basic_bson_cursor& cursor, std::function pred) { return staj_filter_view(cursor, pred); } private: void read_next(std::error_code& ec) { parser_.restart(); while (!parser_.stopped()) { parser_.parse(cursor_visitor_, ec); if (JSONCONS_UNLIKELY(ec)) {return;} } } void read_next(basic_json_visitor& visitor, std::error_code& ec) { parser_.restart(); while (!parser_.stopped()) { parser_.parse(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} } } }; using bson_stream_cursor = basic_bson_cursor; using bson_bytes_cursor = basic_bson_cursor; } // namespace bson } // namespace jsoncons #endif // JSONCONS_EXT_BSON_BSON_CURSOR_HPP jsoncons-1.3.2/include/jsoncons_ext/bson/bson_decimal128.hpp000066400000000000000000000751161477700171100240530ustar00rootroot00000000000000#ifndef JSONCONS_EXT_BSON_BSON_DECIMAL128_HPP #define JSONCONS_EXT_BSON_BSON_DECIMAL128_HPP /* * Implements decimal128_to_chars and decimal128_from_chars * * Based on the libjson functions bson_decimal128_to_string * and bson_decimal128_from_string_w_len, available at * https://github.com/mongodb/mongo-c-driver/blob/master/src/libbson/src/bson/bson-decimal128.h * and https://github.com/mongodb/mongo-c-driver/blob/master/src/libbson/src/bson/bson-decimal128.c * */ /* * Copyright 2015 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace bson { struct decimal128_to_chars_result { char* ptr; std::errc ec; }; struct decimal128_from_chars_result { const char* ptr; std::errc ec; }; /** * BSON_DECIMAL128_STRING: * * The length of a decimal128 string (with null terminator). * * 1 for the sign * 35 for digits and radix * 2 for exponent indicator and sign * 4 for exponent digits */ #define BSON_DECIMAL128_STRING 43 struct TP1 { uint64_t low; uint64_t high; constexpr TP1() : low(0), high(0) {} constexpr TP1(uint64_t hi, uint64_t lo) : low(lo), high(hi) {} }; struct TP2 { uint64_t high; uint64_t low; constexpr TP2() : high(0), low(0) {} constexpr TP2(uint64_t hi, uint64_t lo) : high(hi), low(lo) {} }; typedef std::conditional< jsoncons::endian::native == jsoncons::endian::little, TP1, TP2 >::type decimal128_t; inline bool operator==(const decimal128_t& lhs, const decimal128_t& rhs) { return lhs.high == rhs.high && lhs.low == rhs.low; } inline bool operator!=(const decimal128_t& lhs, const decimal128_t& rhs) { return !(lhs == rhs); } struct decimal128_limits { // The length of a decimal128 string (without null terminator). // // 1 for the sign // 35 for digits and radix // 2 for exponent indicator and sign // 4 for exponent digits static constexpr int buf_size = 42; static constexpr int exponent_max = 6111; static constexpr int exponent_min = -6176; static constexpr int exponent_bias = 6176; static constexpr int max_digits = 34; static constexpr decimal128_t nan() {return decimal128_t(0x7c00000000000000ull, 0);} static constexpr decimal128_t infinity() {return decimal128_t(0x7800000000000000ull, 0);} static constexpr decimal128_t neg_infinity() {return decimal128_t(0x7800000000000000ull + 0x8000000000000000ull, 0);} }; inline bool is_nan(decimal128_t dec) { return dec == decimal128_limits::nan(); } inline bool is_inf(decimal128_t dec) { return dec == decimal128_limits::infinity(); } inline bool is_neg_inf(decimal128_t dec) { return dec == decimal128_limits::neg_infinity(); } /** * bson_uint128_t: * * This struct represents a 128 bit integer. */ typedef struct { uint32_t parts[4]; /* 32-bit words stored high to low. */ } bson_uint128_t; typedef struct { uint64_t high, low; } bson_uint128_6464_t; namespace detail { /** *------------------------------------------------------------------------------ * * bson_uint128_divide1B -- * * This function divides a #bson_uint128_t by 1000000000 (1 billion) and * computes the quotient and remainder. * * The remainder will contain 9 decimal digits for conversion to string. * * @value The #bson_uint128_t operand. * @quotient A pointer to store the #bson_uint128_t quotient. * @rem A pointer to store the #uint64_t remainder. * * Returns: * The quotient at @quotient and the remainder at @rem. * * Side effects: * None. * *------------------------------------------------------------------------------ */ inline void bson_uint128_divide1B (bson_uint128_t value, /* IN */ bson_uint128_t *quotient, /* OUT */ uint32_t *rem) /* OUT */ { const uint32_t DIVISOR = 1000 * 1000 * 1000; uint64_t _rem = 0; int i = 0; if (!value.parts[0] && !value.parts[1] && !value.parts[2] && !value.parts[3]) { *quotient = value; *rem = 0; return; } for (i = 0; i <= 3; i++) { _rem <<= 32; /* Adjust remainder to match value of next dividend */ _rem += value.parts[i]; /* Add the divided to _rem */ value.parts[i] = (uint32_t) (_rem / DIVISOR); _rem %= DIVISOR; /* Store the remainder */ } *quotient = value; *rem = (uint32_t) _rem; } /** *------------------------------------------------------------------------- * * mul64x64 -- * * This function multiplies two &uint64_t into a &bson_uint128_6464_t. * * Returns: * The product of @left and @right. * * Side Effects: * None. * *------------------------------------------------------------------------- */ inline void mul_64x64 (uint64_t left, /* IN */ uint64_t right, /* IN */ bson_uint128_6464_t *product) /* OUT */ { uint64_t left_high, left_low, right_high, right_low, product_high, product_mid, product_mid2, product_low; bson_uint128_6464_t rt = {0,0}; if (!left && !right) { *product = rt; return; } left_high = left >> 32; left_low = (uint32_t) left; right_high = right >> 32; right_low = (uint32_t) right; product_high = left_high * right_high; product_mid = left_high * right_low; product_mid2 = left_low * right_high; product_low = left_low * right_low; product_high += product_mid >> 32; product_mid = (uint32_t) product_mid + product_mid2 + (product_low >> 32); product_high = product_high + (product_mid >> 32); product_low = (product_mid << 32) + (uint32_t) product_low; rt.high = product_high; rt.low = product_low; *product = rt; } /** *------------------------------------------------------------------------------ * * dec128_tolower -- * * This function converts the ASCII character @c to lowercase. It is locale * insensitive (unlike the stdlib tolower). * * Returns: * The lowercased character. */ inline char dec128_tolower (char c) { if (isupper (c)) { c += 32; } return c; } /** *------------------------------------------------------------------------------ * * dec128_istreq -- * * This function compares the null-terminated *ASCII* strings @a and @b * for case-insensitive equality. * * Returns: * true if the strings are equal, false otherwise. */ inline bool dec128_istreq (const char* a, const char* lasta, const char* b, const char* lastb) { while (!(a == lasta && b == lastb)) { // strings are different lengths if (a == lasta || b == lastb) { return false; } if (dec128_tolower (*a) != dec128_tolower (*b)) { return false; } a++; b++; } return true; } } // namespace detail /** *------------------------------------------------------------------------------ * * decimal128_to_chars -- * * This function converts a BID formatted decimal128 value to string, * accepting a &decimal128_t as @dec. The string is stored at @str. * * @dec : The BID formatted decimal to convert. * @str : The output decimal128 string. At least %BSON_DECIMAL128_STRING *characters. * * Returns: * None. * * Side effects: * None. * *------------------------------------------------------------------------------ */ inline decimal128_to_chars_result decimal128_to_chars(char* first, char* last, const decimal128_t& dec) { const std::string bson_decimal128_inf = "Infinity"; const std::string bson_decimal128_nan = "NaN"; const uint32_t combination_mask = 0x1f; /* Extract least significant 5 bits */ const uint32_t exponent_mask = 0x3fff; /* Extract least significant 14 bits */ const uint32_t combination_infinity = 30; /* Value of combination field for Inf */ const uint32_t combination_nan = 31; /* Value of combination field for NaN */ const uint32_t exponent_bias = 6176; /* decimal128 exponent bias */ char* str_out = first; /* output pointer in string */ char significand_str[35]; /* decoded significand digits */ /* Note: bits in this routine are referred to starting at 0, */ /* from the sign bit, towards the coefficient. */ uint32_t high; /* bits 0 - 31 */ uint32_t midh; /* bits 32 - 63 */ uint32_t midl; /* bits 64 - 95 */ uint32_t low; /* bits 96 - 127 */ uint32_t combination; /* bits 1 - 5 */ uint32_t biased_exponent; /* decoded biased exponent (14 bits) */ uint32_t significand_digits = 0; /* the number of significand digits */ uint32_t significand[36] = {0}; /* the base-10 digits in the significand */ uint32_t *significand_read = significand; /* read pointer into significand */ int32_t exponent; /* unbiased exponent */ int32_t scientific_exponent; /* the exponent if scientific notation is * used */ bool is_zero = false; /* true if the number is zero */ uint8_t significand_msb; /* the most signifcant significand bits (50-46) */ bson_uint128_t significand128; /* temporary storage for significand decoding */ memset (significand_str, 0, sizeof (significand_str)); if ((int64_t) dec.high < 0) { /* negative */ *(str_out++) = '-'; } low = (uint32_t) dec.low, midl = (uint32_t) (dec.low >> 32), midh = (uint32_t) dec.high, high = (uint32_t) (dec.high >> 32); /* Decode combination field and exponent */ combination = (high >> 26) & combination_mask; if (JSONCONS_UNLIKELY ((combination >> 3) == 3)) { /* Check for 'special' values */ if (combination == combination_infinity) { /* Infinity */ if (last-str_out >= static_cast(bson_decimal128_inf.size())) { std::memcpy(str_out, bson_decimal128_inf.data(), bson_decimal128_inf.size()); str_out += bson_decimal128_inf.size(); } *str_out = 0; //strcpy_s (str_out, last-str_out, bson_decimal128_inf.c_str()); return decimal128_to_chars_result{str_out, std::errc()}; } else if (combination == combination_nan) { /* NaN */ /* first, not str_out, to erase the sign */ str_out = first; if (last-str_out >= static_cast(bson_decimal128_nan.size())) { std::memcpy(str_out, bson_decimal128_nan.data(), bson_decimal128_nan.size()); str_out += bson_decimal128_nan.size(); } *str_out = 0; //strcpy_s (first, last-first, bson_decimal128_nan.c_str()); /* we don't care about the NaN payload. */ return decimal128_to_chars_result{str_out, std::errc()}; } else { biased_exponent = (high >> 15) & exponent_mask; significand_msb = 0x8 + ((high >> 14) & 0x1); } } else { significand_msb = (high >> 14) & 0x7; biased_exponent = (high >> 17) & exponent_mask; } exponent = biased_exponent - exponent_bias; /* Create string of significand digits */ /* Convert the 114-bit binary number represented by */ /* (high, midh, midl, low) to at most 34 decimal */ /* digits through modulo and division. */ significand128.parts[0] = (high & 0x3fff) + ((significand_msb & 0xf) << 14); significand128.parts[1] = midh; significand128.parts[2] = midl; significand128.parts[3] = low; if (significand128.parts[0] == 0 && significand128.parts[1] == 0 && significand128.parts[2] == 0 && significand128.parts[3] == 0) { is_zero = true; } else if (significand128.parts[0] >= (1 << 17)) { /* The significand is non-canonical or zero. * In order to preserve compatibility with the densely packed decimal * format, the maximum value for the significand of decimal128 is * 1e34 - 1. If the value is greater than 1e34 - 1, the IEEE 754 * standard dictates that the significand is interpreted as zero. */ is_zero = true; } else { for (int k = 3; k >= 0; k--) { uint32_t least_digits = 0; detail::bson_uint128_divide1B ( significand128, &significand128, &least_digits); /* We now have the 9 least significant digits (in base 2). */ /* Convert and output to string. */ if (!least_digits) { continue; } for (int j = 8; j >= 0; j--) { significand[k * 9 + j] = least_digits % 10; least_digits /= 10; } } } /* Output format options: */ /* Scientific - [-]d.dddE(+/-)dd or [-]dE(+/-)dd */ /* Regular - ddd.ddd */ if (is_zero) { significand_digits = 1; *significand_read = 0; } else { significand_digits = 36; while (!(*significand_read)) { significand_digits--; significand_read++; } } scientific_exponent = significand_digits - 1 + exponent; /* The scientific exponent checks are dictated by the string conversion * specification and are somewhat arbitrary cutoffs. * * We must check exponent > 0, because if this is the case, the number * has trailing zeros. However, we *cannot* output these trailing zeros, * because doing so would change the precision of the value, and would * change stored data if the string converted number is round tripped. */ if (scientific_exponent < -6 || exponent > 0) { /* Scientific format */ *(str_out++) = char(*(significand_read++)) + '0'; significand_digits--; if (significand_digits) { *(str_out++) = '.'; } for (std::size_t i = 0; i < significand_digits && (str_out - first) < 36; i++) { *(str_out++) = char(*(significand_read++)) + '0'; } /* Exponent */ *(str_out++) = 'E'; std::string s; if (scientific_exponent >= 0) { s.push_back('+'); } jsoncons::detail::from_integer(scientific_exponent, s); if (str_out + s.size() < last) { std::memcpy(str_out, s.data(), s.size()); } else { return decimal128_to_chars_result{str_out, std::errc::value_too_large}; } str_out += s.size(); } else { /* Regular format with no decimal place */ if (exponent >= 0) { for (std::size_t i = 0; i < significand_digits && (str_out - first) < 36; i++) { *(str_out++) = char(*(significand_read++)) + '0'; } } else { int32_t radix_position = significand_digits + exponent; if (radix_position > 0) { /* non-zero digits before radix */ for (int32_t i = 0; i < radix_position && (str_out < last); i++) { *(str_out++) = char(*(significand_read++)) + '0'; } } else { /* leading zero before radix point */ *(str_out++) = '0'; } *(str_out++) = '.'; while (radix_position++ < 0) { /* add leading zeros after radix */ *(str_out++) = '0'; } for (std::size_t i = 0; (i < significand_digits - (std::max) (radix_position - 1, 0)) && (str_out < last); i++) { *(str_out++) = char(*(significand_read++)) + '0'; } } } return decimal128_to_chars_result{str_out, std::errc()}; } /** *------------------------------------------------------------------------------ * * bson_decimal128_from_string_w_len -- * * This function converts @string in the format [+-]ddd[.]ddd[E][+-]dddd to * decimal128. Out of range values are converted to +/-Infinity. Invalid * strings are converted to NaN. @len is the length of the string, or -1 * meaning the string is null-terminated. * * If more digits are provided than the available precision allows, * round to the nearest expressable decimal128 with ties going to even will * occur. * * Note: @string must be ASCII only! * * Returns: * true on success, or false on failure. @dec will be NaN if @str was invalid * The &decimal128_t converted from @string at @dec. * * Side effects: * None. * *------------------------------------------------------------------------------ */ inline decimal128_from_chars_result decimal128_from_chars(const char* first, const char* last, decimal128_t& dec) { const string_view inf_str = "inf"; const string_view infinity_str = "infinity"; const string_view nan_str = "nan"; ptrdiff_t len = last - first; bson_uint128_6464_t significand = {0,0}; const char* str_read = first; /* Read pointer for consuming str. */ /* Parsing state tracking */ bool is_negative = false; bool saw_radix = false; bool includes_sign = false; /* True if the input first contains a sign. */ bool found_nonzero = false; std::size_t significant_digits = 0; /* Total number of significant digits * (no leading or trailing zero) */ std::size_t ndigits_read = 0; /* Total number of significand digits read */ std::size_t ndigits = 0; /* Total number of digits (no leading zeros) */ std::size_t radix_position = 0; /* The number of the digits after radix */ std::size_t first_nonzero = 0; /* The index of the first non-zero in *str* */ uint16_t digits[decimal128_limits::max_digits] = {0}; uint16_t ndigits_stored = 0; /* The number of digits in digits */ uint16_t *digits_insert = digits; /* Insertion pointer for digits */ std::size_t first_digit = 0; /* The index of the first non-zero digit */ std::size_t last_digit = 0; /* The index of the last digit */ int32_t exponent = 0; uint64_t significand_high = 0; /* The high 17 digits of the significand */ uint64_t significand_low = 0; /* The low 17 digits of the significand */ uint16_t biased_exponent = 0; /* The biased exponent */ dec.high = 0; dec.low = 0; if (*str_read == '+' || *str_read == '-') { is_negative = *(str_read++) == '-'; includes_sign = true; } /* Check for Infinity or NaN */ if (!isdigit(*str_read) && *str_read != '.') { if (detail::dec128_istreq (str_read, last, inf_str.data(), inf_str.data()+inf_str.length()) || detail::dec128_istreq (str_read, last, infinity_str.data(), infinity_str.data()+infinity_str.length())) { dec = is_negative ? decimal128_limits::neg_infinity() : decimal128_limits::infinity(); return decimal128_from_chars_result{str_read,std::errc()}; } else if (detail::dec128_istreq (str_read, last, nan_str.data(), nan_str.data()+nan_str.length())) { dec = decimal128_limits::nan(); return decimal128_from_chars_result{str_read,std::errc()}; } dec = decimal128_limits::nan(); return decimal128_from_chars_result{str_read,std::errc::invalid_argument}; } /* Read digits */ while (((isdigit (*str_read) || *str_read == '.')) && (len == -1 || str_read < first + len)) { if (*str_read == '.') { if (saw_radix) { dec = decimal128_limits::nan(); return decimal128_from_chars_result{str_read,std::errc::invalid_argument}; } saw_radix = true; str_read++; continue; } if (ndigits_stored < 34) { if (*str_read != '0' || found_nonzero) { if (!found_nonzero) { first_nonzero = ndigits_read; } found_nonzero = true; *(digits_insert++) = *(str_read) - '0'; /* Only store 34 digits */ ndigits_stored++; } } if (found_nonzero) { ndigits++; } if (saw_radix) { radix_position++; } ndigits_read++; str_read++; } if (saw_radix && !ndigits_read) { dec = decimal128_limits::nan(); return decimal128_from_chars_result{str_read,std::errc::invalid_argument}; } /* Read exponent if exists */ if (*str_read == 'e' || *str_read == 'E') { ++str_read; if (*str_read == '+') { ++str_read; } auto result = jsoncons::detail::to_integer(str_read, last - str_read, exponent); if (result.ec != jsoncons::detail::to_integer_errc()) { dec = decimal128_limits::nan(); return decimal128_from_chars_result{str_read,std::errc::invalid_argument}; } str_read = result.ptr; } if ((len == -1 || str_read < first + len) && *str_read) { dec = decimal128_limits::nan(); return decimal128_from_chars_result{str_read,std::errc::invalid_argument}; } /* Done reading input. */ /* Find first non-zero digit in digits */ first_digit = 0; if (!ndigits_stored) { /* value is zero */ first_digit = 0; last_digit = 0; digits[0] = 0; ndigits = 1; ndigits_stored = 1; significant_digits = 0; } else { last_digit = ndigits_stored - 1; significant_digits = ndigits; /* Mark trailing zeros as non-significant */ while (first[first_nonzero + significant_digits - 1 + includes_sign + saw_radix] == '0') { significant_digits--; } } /* Normalization of exponent */ /* Correct exponent based on radix position, and shift significand as needed */ /* to represent user input */ /* Overflow prevention */ if (exponent <= static_cast(radix_position) && static_cast(radix_position) - exponent > (1 << 14)) { exponent = decimal128_limits::exponent_min; } else { exponent -= static_cast(radix_position); } /* Attempt to normalize the exponent */ while (exponent > decimal128_limits::exponent_max) { /* Shift exponent to significand and decrease */ last_digit++; if (last_digit - first_digit > decimal128_limits::max_digits) { /* The exponent is too great to shift into the significand. */ if (significant_digits == 0) { /* Value is zero, we are allowed to clamp the exponent. */ exponent = decimal128_limits::exponent_max; break; } /* Overflow is not permitted, error. */ dec = decimal128_limits::nan(); return decimal128_from_chars_result{str_read,std::errc::invalid_argument}; } exponent--; } while (exponent < decimal128_limits::exponent_min || ndigits_stored < ndigits) { /* Shift last digit */ if (last_digit == 0) { /* underflow is not allowed, but zero clamping is */ if (significant_digits == 0) { exponent = decimal128_limits::exponent_min; break; } dec = decimal128_limits::nan(); return decimal128_from_chars_result{str_read,std::errc::invalid_argument}; } if (ndigits_stored < ndigits) { if (first[ndigits - 1 + includes_sign + saw_radix] - '0' != 0 && significant_digits != 0) { dec = decimal128_limits::nan(); return decimal128_from_chars_result{str_read,std::errc::invalid_argument}; } ndigits--; /* adjust to match digits not stored */ } else { if (digits[last_digit] != 0) { /* Inexact rounding is not allowed. */ dec = decimal128_limits::nan(); return decimal128_from_chars_result{str_read,std::errc::invalid_argument}; } last_digit--; /* adjust to round */ } if (exponent < decimal128_limits::exponent_max) { exponent++; } else { dec = decimal128_limits::nan(); return decimal128_from_chars_result{str_read,std::errc::invalid_argument}; } } /* Round */ /* We've normalized the exponent, but might still need to round. */ if (last_digit - first_digit + 1 < significant_digits) { uint8_t round_digit; /* There are non-zero digits after last_digit that need rounding. */ /* We round to nearest, ties to even */ round_digit = first[first_nonzero + last_digit + includes_sign + saw_radix + 1] - '0'; if (round_digit != 0) { /* Inexact (non-zero) rounding is not allowed */ dec = decimal128_limits::nan(); return decimal128_from_chars_result{str_read,std::errc::invalid_argument}; } } /* Encode significand */ significand_high = 0, /* The high 17 digits of the significand */ significand_low = 0; /* The low 17 digits of the significand */ if (significant_digits == 0) { /* read a zero */ significand_high = 0; significand_low = 0; } else if (last_digit - first_digit < 17) { std::size_t d_idx = first_digit; significand_low = digits[d_idx++]; for (; d_idx <= last_digit; d_idx++) { significand_low *= 10; significand_low += digits[d_idx]; significand_high = 0; } } else { std::size_t d_idx = first_digit; significand_high = digits[d_idx++]; for (; d_idx <= last_digit - 17; d_idx++) { significand_high *= 10; significand_high += digits[d_idx]; } significand_low = digits[d_idx++]; for (; d_idx <= last_digit; d_idx++) { significand_low *= 10; significand_low += digits[d_idx]; } } detail::mul_64x64 (significand_high, 100000000000000000ull, &significand); significand.low += significand_low; if (significand.low < significand_low) { significand.high += 1; } biased_exponent = static_cast(exponent + static_cast(decimal128_limits::exponent_bias)); /* Encode combination, exponent, and significand. */ if ((significand.high >> 49) & 1) { /* Encode '11' into bits 1 to 3 */ dec.high |= (0x3ull << 61); dec.high |= (biased_exponent & 0x3fffull) << 47; dec.high |= significand.high & 0x7fffffffffffull; } else { dec.high |= (biased_exponent & 0x3fffull) << 49; dec.high |= significand.high & 0x1ffffffffffffull; } dec.low = significand.low; /* Encode sign */ if (is_negative) { dec.high |= 0x8000000000000000ull; } return decimal128_from_chars_result{str_read,std::errc()}; } } // namespace bson } // namespace jsoncons #endif // JSONCONS_EXT_BSON_BSON_DECIMAL128_HPP jsoncons-1.3.2/include/jsoncons_ext/bson/bson_encoder.hpp000066400000000000000000000455441477700171100236430ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_BSON_BSON_ENCODER_HPP #define JSONCONS_EXT_BSON_BSON_ENCODER_HPP #include #include #include #include // std::numeric_limits #include #include #include #include // std::move #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace bson { template > class basic_bson_encoder final : public basic_json_visitor { enum class decimal_parse_state { start, integer, exp1, exp2, fraction1 }; static constexpr int64_t nanos_in_milli = 1000000; static constexpr int64_t nanos_in_second = 1000000000; static constexpr int64_t millis_in_second = 1000; public: using allocator_type = Allocator; using char_type = char; using typename basic_json_visitor::string_view_type; using sink_type = Sink; private: struct stack_item { jsoncons::bson::bson_container_type type_; std::size_t offset_{0}; std::size_t name_offset_{0}; std::size_t index_{0}; stack_item(jsoncons::bson::bson_container_type type, std::size_t offset) noexcept : type_(type), offset_(offset) { } std::size_t offset() const { return offset_; } std::size_t member_offset() const { return name_offset_; } void member_offset(std::size_t offset) { name_offset_ = offset; } std::size_t next_index() { return index_++; } bool is_object() const { return type_ == jsoncons::bson::bson_container_type::document; } }; sink_type sink_; const bson_encode_options options_; allocator_type alloc_; std::vector stack_; std::vector buffer_; int nesting_depth_{0}; public: // Noncopyable and nonmoveable basic_bson_encoder(const basic_bson_encoder&) = delete; basic_bson_encoder(basic_bson_encoder&&) = delete; explicit basic_bson_encoder(Sink&& sink, const Allocator& alloc = Allocator()) : basic_bson_encoder(std::forward(sink), bson_encode_options(), alloc) { } explicit basic_bson_encoder(Sink&& sink, const bson_encode_options& options, const Allocator& alloc = Allocator()) : sink_(std::forward(sink)), options_(options), alloc_(alloc) { } ~basic_bson_encoder() noexcept { sink_.flush(); } basic_bson_encoder& operator=(const basic_bson_encoder&) = delete; basic_bson_encoder& operator=(basic_bson_encoder&&) = delete; void reset() { stack_.clear(); buffer_.clear(); nesting_depth_ = 0; } void reset(Sink&& sink) { sink_ = std::move(sink); reset(); } private: // Implementing methods void visit_flush() override { sink_.flush(); } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag, const ser_context&, std::error_code& ec) override { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = bson_errc::max_nesting_depth_exceeded; JSONCONS_VISITOR_RETURN; } if (buffer_.size() > 0) { if (stack_.empty()) { ec = bson_errc::expected_bson_document; JSONCONS_VISITOR_RETURN; } before_value(jsoncons::bson::bson_type::document_type); } stack_.emplace_back(jsoncons::bson::bson_container_type::document, buffer_.size()); buffer_.insert(buffer_.end(), sizeof(int32_t), 0); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context&, std::error_code&) override { JSONCONS_ASSERT(!stack_.empty()); --nesting_depth_; buffer_.push_back(0x00); std::size_t length = buffer_.size() - stack_.back().offset(); binary::native_to_little(static_cast(length), buffer_.begin()+stack_.back().offset()); stack_.pop_back(); if (stack_.empty()) { for (auto c : buffer_) { sink_.push_back(c); } } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag, const ser_context&, std::error_code& ec) override { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = bson_errc::max_nesting_depth_exceeded; JSONCONS_VISITOR_RETURN; } if (buffer_.size() > 0) { if (stack_.empty()) { ec = bson_errc::expected_bson_document; JSONCONS_VISITOR_RETURN; } before_value(jsoncons::bson::bson_type::array_type); } stack_.emplace_back(jsoncons::bson::bson_container_type::array, buffer_.size()); buffer_.insert(buffer_.end(), sizeof(int32_t), 0); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context&, std::error_code&) override { JSONCONS_ASSERT(!stack_.empty()); --nesting_depth_; buffer_.push_back(0x00); std::size_t length = buffer_.size() - stack_.back().offset(); binary::native_to_little(static_cast(length), buffer_.begin()+stack_.back().offset()); stack_.pop_back(); if (stack_.empty()) { for (auto c : buffer_) { sink_.push_back(c); } } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type& name, const ser_context&, std::error_code&) override { stack_.back().member_offset(buffer_.size()); buffer_.push_back(0x00); // reserve space for code for (auto c : name) { buffer_.push_back(c); } buffer_.push_back(0x00); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag tag, const ser_context&, std::error_code& ec) override { if (stack_.empty()) { ec = bson_errc::expected_bson_document; JSONCONS_VISITOR_RETURN; } switch (tag) { case semantic_tag::undefined: before_value(jsoncons::bson::bson_type::undefined_type); break; default: before_value(jsoncons::bson::bson_type::null_type); break; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool val, semantic_tag, const ser_context&, std::error_code& ec) override { if (stack_.empty()) { ec = bson_errc::expected_bson_document; JSONCONS_VISITOR_RETURN; } before_value(jsoncons::bson::bson_type::bool_type); if (val) { buffer_.push_back(0x01); } else { buffer_.push_back(0x00); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& sv, semantic_tag tag, const ser_context&, std::error_code& ec) override { if (stack_.empty()) { ec = bson_errc::expected_bson_document; JSONCONS_VISITOR_RETURN; } switch (tag) { case semantic_tag::float128: { before_value(jsoncons::bson::bson_type::decimal128_type); decimal128_t dec; auto rc = decimal128_from_chars(sv.data(), sv.data()+sv.size(), dec); if (rc.ec != std::errc()) { ec = bson_errc::invalid_decimal128_string; JSONCONS_VISITOR_RETURN; } binary::native_to_little(dec.low,std::back_inserter(buffer_)); binary::native_to_little(dec.high,std::back_inserter(buffer_)); break; } case semantic_tag::id: { before_value(jsoncons::bson::bson_type::object_id_type); oid_t oid(sv); for (auto b : oid) { buffer_.push_back(b); } break; } case semantic_tag::regex: { before_value(jsoncons::bson::bson_type::regex_type); std::size_t first = sv.find_first_of('/'); std::size_t last = sv.find_last_of('/'); if (first == string_view::npos || last == string_view::npos || first == last) { ec = bson_errc::invalid_regex_string; JSONCONS_VISITOR_RETURN; } string_view regex = sv.substr(first+1,last-1); for (auto c : regex) { buffer_.push_back(c); } buffer_.push_back(0x00); string_view options = sv.substr(last+1); for (auto c : options) { buffer_.push_back(c); } buffer_.push_back(0x00); break; } default: switch (tag) { case semantic_tag::code: before_value(jsoncons::bson::bson_type::javascript_type); break; default: before_value(jsoncons::bson::bson_type::string_type); break; } std::size_t offset = buffer_.size(); buffer_.insert(buffer_.end(), sizeof(int32_t), 0); std::size_t string_offset = buffer_.size(); auto sink = unicode_traits::validate(sv.data(), sv.size()); if (sink.ec != unicode_traits::conv_errc()) { ec = bson_errc::invalid_utf8_text_string; JSONCONS_VISITOR_RETURN; } for (auto c : sv) { buffer_.push_back(c); } buffer_.push_back(0x00); std::size_t length = buffer_.size() - string_offset; binary::native_to_little(static_cast(length), buffer_.begin()+offset); break; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& b, semantic_tag, const ser_context&, std::error_code& ec) override { if (stack_.empty()) { ec = bson_errc::expected_bson_document; JSONCONS_VISITOR_RETURN; } before_value(jsoncons::bson::bson_type::binary_type); std::size_t offset = buffer_.size(); buffer_.insert(buffer_.end(), sizeof(int32_t), 0); std::size_t string_offset = buffer_.size(); buffer_.push_back(0x80); // default subtype for (auto c : b) { buffer_.push_back(c); } std::size_t length = buffer_.size() - string_offset - 1; binary::native_to_little(static_cast(length), buffer_.begin()+offset); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& b, uint64_t ext_tag, const ser_context&, std::error_code& ec) override { if (stack_.empty()) { ec = bson_errc::expected_bson_document; JSONCONS_VISITOR_RETURN; } before_value(jsoncons::bson::bson_type::binary_type); std::size_t offset = buffer_.size(); buffer_.insert(buffer_.end(), sizeof(int32_t), 0); std::size_t string_offset = buffer_.size(); buffer_.push_back(static_cast(ext_tag)); // default subtype for (auto c : b) { buffer_.push_back(c); } std::size_t length = buffer_.size() - string_offset - 1; binary::native_to_little(static_cast(length), buffer_.begin()+offset); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t val, semantic_tag tag, const ser_context&, std::error_code& ec) override { static constexpr int64_t min_value_div_1000 = (std::numeric_limits::min)() / 1000; static constexpr int64_t max_value_div_1000 = (std::numeric_limits::max)() / 1000; if (stack_.empty()) { ec = bson_errc::expected_bson_document; JSONCONS_VISITOR_RETURN; } switch (tag) { case semantic_tag::epoch_second: if (val < min_value_div_1000) { ec = bson_errc::datetime_too_small; JSONCONS_VISITOR_RETURN; } if (val > max_value_div_1000) { ec = bson_errc::datetime_too_large; JSONCONS_VISITOR_RETURN; } before_value(jsoncons::bson::bson_type::datetime_type); binary::native_to_little(val*millis_in_second,std::back_inserter(buffer_)); break; case semantic_tag::epoch_milli: before_value(jsoncons::bson::bson_type::datetime_type); binary::native_to_little(val,std::back_inserter(buffer_)); break; case semantic_tag::epoch_nano: before_value(jsoncons::bson::bson_type::datetime_type); if (val != 0) { val /= nanos_in_milli; } binary::native_to_little(static_cast(val),std::back_inserter(buffer_)); break; default: { if (val >= (std::numeric_limits::lowest)() && val <= (std::numeric_limits::max)()) { before_value(jsoncons::bson::bson_type::int32_type); binary::native_to_little(static_cast(val),std::back_inserter(buffer_)); } else { before_value(jsoncons::bson::bson_type::int64_type); binary::native_to_little(static_cast(val),std::back_inserter(buffer_)); } break; } } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t val, semantic_tag tag, const ser_context&, std::error_code& ec) override { static constexpr uint64_t max_value_div_1000 = (std::numeric_limits::max)() / 1000; if (stack_.empty()) { ec = bson_errc::expected_bson_document; JSONCONS_VISITOR_RETURN; } switch (tag) { case semantic_tag::epoch_second: if (val > max_value_div_1000) { ec = bson_errc::datetime_too_large; JSONCONS_VISITOR_RETURN; } before_value(jsoncons::bson::bson_type::datetime_type); binary::native_to_little(static_cast(val*millis_in_second),std::back_inserter(buffer_)); break; case semantic_tag::epoch_milli: before_value(jsoncons::bson::bson_type::datetime_type); binary::native_to_little(static_cast(val),std::back_inserter(buffer_)); break; case semantic_tag::epoch_nano: before_value(jsoncons::bson::bson_type::datetime_type); if (val != 0) { val /= nanos_in_second; } binary::native_to_little(static_cast(val),std::back_inserter(buffer_)); break; default: { if (val <= static_cast((std::numeric_limits::max)())) { before_value(jsoncons::bson::bson_type::int32_type); binary::native_to_little(static_cast(val),std::back_inserter(buffer_)); } else if (val <= static_cast((std::numeric_limits::max)())) { before_value(jsoncons::bson::bson_type::int64_type); binary::native_to_little(static_cast(val),std::back_inserter(buffer_)); } else { ec = bson_errc::number_too_large; JSONCONS_VISITOR_RETURN; } break; } } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_double(double val, semantic_tag, const ser_context&, std::error_code& ec) override { if (stack_.empty()) { ec = bson_errc::expected_bson_document; JSONCONS_VISITOR_RETURN; } before_value(jsoncons::bson::bson_type::double_type); binary::native_to_little(val,std::back_inserter(buffer_)); JSONCONS_VISITOR_RETURN; } void before_value(uint8_t code) { JSONCONS_ASSERT(!stack_.empty()); if (stack_.back().is_object()) { buffer_[stack_.back().member_offset()] = code; } else { buffer_.push_back(code); std::string name = std::to_string(stack_.back().next_index()); buffer_.insert(buffer_.end(), name.begin(), name.end()); buffer_.push_back(0x00); } } }; using bson_stream_encoder = basic_bson_encoder; using bson_bytes_encoder = basic_bson_encoder>>; } // namespace bson } // namespace jsoncons #endif // JSONCONS_EXT_BSON_BSON_ENCODER_HPP jsoncons-1.3.2/include/jsoncons_ext/bson/bson_error.hpp000066400000000000000000000062031477700171100233420ustar00rootroot00000000000000/// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_BSON_BSON_ERROR_HPP #define JSONCONS_EXT_BSON_BSON_ERROR_HPP #include #include #include namespace jsoncons { namespace bson { enum class bson_errc { success = 0, unexpected_eof = 1, source_error, invalid_utf8_text_string, max_nesting_depth_exceeded, string_length_is_non_positive, length_is_negative, number_too_large, invalid_decimal128_string, datetime_too_small, datetime_too_large, expected_bson_document, invalid_regex_string, size_mismatch, unknown_type }; class bson_error_category_impl : public std::error_category { public: const char* name() const noexcept override { return "jsoncons/bson"; } std::string message(int ev) const override { switch (static_cast(ev)) { case bson_errc::unexpected_eof: return "Unexpected end of file"; case bson_errc::source_error: return "Source error"; case bson_errc::invalid_utf8_text_string: return "Illegal UTF-8 encoding in text string"; case bson_errc::max_nesting_depth_exceeded: return "Data item nesting exceeds limit in options"; case bson_errc::string_length_is_non_positive: return "Request for the length of a string returned a non-positive result"; case bson_errc::length_is_negative: return "Request for the length of a binary returned a negative result"; case bson_errc::unknown_type: return "An unknown type was found in the stream"; case bson_errc::number_too_large: return "Number too large"; case bson_errc::invalid_decimal128_string: return "Invalid decimal128 string"; case bson_errc::datetime_too_large: return "datetime too large"; case bson_errc::datetime_too_small: return "datetime too small"; case bson_errc::expected_bson_document: return "Expected BSON document"; case bson_errc::invalid_regex_string: return "Invalid regex string"; case bson_errc::size_mismatch: return "Document or array size doesn't match bytes read"; default: return "Unknown BSON parser error"; } } }; inline const std::error_category& bson_error_category() { static bson_error_category_impl instance; return instance; } inline std::error_code make_error_code(bson_errc result) { return std::error_code(static_cast(result),bson_error_category()); } } // namespace bson } // namespace jsoncons namespace std { template<> struct is_error_code_enum : public true_type { }; } // namespace std #endif // JSONCONS_EXT_BSON_BSON_ERROR_HPP jsoncons-1.3.2/include/jsoncons_ext/bson/bson_oid.hpp000066400000000000000000000223001477700171100227600ustar00rootroot00000000000000#ifndef JSONCONS_EXT_BSON_BSON_OID_HPP #define JSONCONS_EXT_BSON_BSON_OID_HPP /* * Implements class oid_t and non member function bson_oid_to_string * * Based on the libjson functions bson_oid_to_string * and bson_oid_init_from_string_unsafe , available at * https://github.com/mongodb/mongo-c-driver/blob/master/src/libbson/src/bson/bson-oid.h * and https://github.com/mongodb/mongo-c-driver/blob/master/src/libbson/src/bson/bson-oid.c * */ /* * Copyright 2015 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include namespace jsoncons { namespace bson { class oid_t { std::array bytes_; public: using iterator = std::array::iterator; using const_iterator = std::array::const_iterator; oid_t(const std::array& bytes) : bytes_(bytes) { } oid_t(uint8_t data[12]) { std::memcpy(bytes_.data(),data,12); } oid_t(const string_view& str) { for (std::size_t i = 0; i < bytes_.size(); i++) { bytes_[i] = ((parse_hex_char (str[2 * i]) << 4) | (parse_hex_char (str[2 * i + 1]))); } } const uint8_t* data() const { return bytes_.data(); } std::size_t size() const { return bytes_.size(); } iterator begin() { return bytes_.begin(); } iterator end() { return bytes_.end(); } const_iterator begin() const { return bytes_.begin(); } const_iterator end() const { return bytes_.end(); } private: static uint8_t parse_hex_char (char hex) { switch (hex) { case '0': return 0; case '1': return 1; case '2': return 2; case '3': return 3; case '4': return 4; case '5': return 5; case '6': return 6; case '7': return 7; case '8': return 8; case '9': return 9; case 'a': case 'A': return 0xa; case 'b': case 'B': return 0xb; case 'c': case 'C': return 0xc; case 'd': case 'D': return 0xd; case 'e': case 'E': return 0xe; case 'f': case 'F': return 0xf; default: return 0; } } }; namespace detail { inline const uint16_t* get_hex_char_pairs(std::true_type) // big endian { static const uint16_t hex_char_pairs[] = { 12336, 12337, 12338, 12339, 12340, 12341, 12342, 12343, 12344, 12345, 12385, 12386, 12387, 12388, 12389, 12390, 12592, 12593, 12594, 12595, 12596, 12597, 12598, 12599, 12600, 12601, 12641, 12642, 12643, 12644, 12645, 12646, 12848, 12849, 12850, 12851, 12852, 12853, 12854, 12855, 12856, 12857, 12897, 12898, 12899, 12900, 12901, 12902, 13104, 13105, 13106, 13107, 13108, 13109, 13110, 13111, 13112, 13113, 13153, 13154, 13155, 13156, 13157, 13158, 13360, 13361, 13362, 13363, 13364, 13365, 13366, 13367, 13368, 13369, 13409, 13410, 13411, 13412, 13413, 13414, 13616, 13617, 13618, 13619, 13620, 13621, 13622, 13623, 13624, 13625, 13665, 13666, 13667, 13668, 13669, 13670, 13872, 13873, 13874, 13875, 13876, 13877, 13878, 13879, 13880, 13881, 13921, 13922, 13923, 13924, 13925, 13926, 14128, 14129, 14130, 14131, 14132, 14133, 14134, 14135, 14136, 14137, 14177, 14178, 14179, 14180, 14181, 14182, 14384, 14385, 14386, 14387, 14388, 14389, 14390, 14391, 14392, 14393, 14433, 14434, 14435, 14436, 14437, 14438, 14640, 14641, 14642, 14643, 14644, 14645, 14646, 14647, 14648, 14649, 14689, 14690, 14691, 14692, 14693, 14694, 24880, 24881, 24882, 24883, 24884, 24885, 24886, 24887, 24888, 24889, 24929, 24930, 24931, 24932, 24933, 24934, 25136, 25137, 25138, 25139, 25140, 25141, 25142, 25143, 25144, 25145, 25185, 25186, 25187, 25188, 25189, 25190, 25392, 25393, 25394, 25395, 25396, 25397, 25398, 25399, 25400, 25401, 25441, 25442, 25443, 25444, 25445, 25446, 25648, 25649, 25650, 25651, 25652, 25653, 25654, 25655, 25656, 25657, 25697, 25698, 25699, 25700, 25701, 25702, 25904, 25905, 25906, 25907, 25908, 25909, 25910, 25911, 25912, 25913, 25953, 25954, 25955, 25956, 25957, 25958, 26160, 26161, 26162, 26163, 26164, 26165, 26166, 26167, 26168, 26169, 26209, 26210, 26211, 26212, 26213, 26214}; return hex_char_pairs; } inline const uint16_t* get_hex_char_pairs(std::false_type) // little endian { static const uint16_t hex_char_pairs[] = { 12336, 12592, 12848, 13104, 13360, 13616, 13872, 14128, 14384, 14640, 24880, 25136, 25392, 25648, 25904, 26160, 12337, 12593, 12849, 13105, 13361, 13617, 13873, 14129, 14385, 14641, 24881, 25137, 25393, 25649, 25905, 26161, 12338, 12594, 12850, 13106, 13362, 13618, 13874, 14130, 14386, 14642, 24882, 25138, 25394, 25650, 25906, 26162, 12339, 12595, 12851, 13107, 13363, 13619, 13875, 14131, 14387, 14643, 24883, 25139, 25395, 25651, 25907, 26163, 12340, 12596, 12852, 13108, 13364, 13620, 13876, 14132, 14388, 14644, 24884, 25140, 25396, 25652, 25908, 26164, 12341, 12597, 12853, 13109, 13365, 13621, 13877, 14133, 14389, 14645, 24885, 25141, 25397, 25653, 25909, 26165, 12342, 12598, 12854, 13110, 13366, 13622, 13878, 14134, 14390, 14646, 24886, 25142, 25398, 25654, 25910, 26166, 12343, 12599, 12855, 13111, 13367, 13623, 13879, 14135, 14391, 14647, 24887, 25143, 25399, 25655, 25911, 26167, 12344, 12600, 12856, 13112, 13368, 13624, 13880, 14136, 14392, 14648, 24888, 25144, 25400, 25656, 25912, 26168, 12345, 12601, 12857, 13113, 13369, 13625, 13881, 14137, 14393, 14649, 24889, 25145, 25401, 25657, 25913, 26169, 12385, 12641, 12897, 13153, 13409, 13665, 13921, 14177, 14433, 14689, 24929, 25185, 25441, 25697, 25953, 26209, 12386, 12642, 12898, 13154, 13410, 13666, 13922, 14178, 14434, 14690, 24930, 25186, 25442, 25698, 25954, 26210, 12387, 12643, 12899, 13155, 13411, 13667, 13923, 14179, 14435, 14691, 24931, 25187, 25443, 25699, 25955, 26211, 12388, 12644, 12900, 13156, 13412, 13668, 13924, 14180, 14436, 14692, 24932, 25188, 25444, 25700, 25956, 26212, 12389, 12645, 12901, 13157, 13413, 13669, 13925, 14181, 14437, 14693, 24933, 25189, 25445, 25701, 25957, 26213, 12390, 12646, 12902, 13158, 13414, 13670, 13926, 14182, 14438, 14694, 24934, 25190, 25446, 25702, 25958, 26214}; return hex_char_pairs; } inline void init_hex_char_pairs(const oid_t& oid, uint16_t* data) { const uint8_t* bytes = oid.data(); const uint16_t* gHexCharPairs = get_hex_char_pairs(std::integral_constant()); data[0] = gHexCharPairs[bytes[0]]; data[1] = gHexCharPairs[bytes[1]]; data[2] = gHexCharPairs[bytes[2]]; data[3] = gHexCharPairs[bytes[3]]; data[4] = gHexCharPairs[bytes[4]]; data[5] = gHexCharPairs[bytes[5]]; data[6] = gHexCharPairs[bytes[6]]; data[7] = gHexCharPairs[bytes[7]]; data[8] = gHexCharPairs[bytes[8]]; data[9] = gHexCharPairs[bytes[9]]; data[10] = gHexCharPairs[bytes[10]]; data[11] = gHexCharPairs[bytes[11]]; } } // namespace detail template inline void to_string(const oid_t& oid, StringT& s) { s.resize(24); detail::init_hex_char_pairs(oid, reinterpret_cast(&s[0])); } } // namespace bson } // namespace jsoncons #endif // JSONCONS_EXT_BSON_BSON_OID_HPP jsoncons-1.3.2/include/jsoncons_ext/bson/bson_options.hpp000066400000000000000000000031571477700171100237110ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_BSON_BSON_OPTIONS_HPP #define JSONCONS_EXT_BSON_BSON_OPTIONS_HPP #include namespace jsoncons { namespace bson { class bson_options; class bson_options_common { friend class bson_options; int max_nesting_depth_; protected: virtual ~bson_options_common() = default; bson_options_common() : max_nesting_depth_(1024) { } bson_options_common(const bson_options_common&) = default; bson_options_common& operator=(const bson_options_common&) = default; bson_options_common(bson_options_common&&) = default; bson_options_common& operator=(bson_options_common&&) = default; public: int max_nesting_depth() const { return max_nesting_depth_; } }; class bson_decode_options : public virtual bson_options_common { friend class bson_options; public: bson_decode_options() { } }; class bson_encode_options : public virtual bson_options_common { friend class bson_options; public: bson_encode_options() { } }; class bson_options final : public bson_decode_options, public bson_encode_options { public: using bson_options_common::max_nesting_depth; bson_options& max_nesting_depth(int value) { this->max_nesting_depth_ = value; return *this; } }; } // namespace bson } // namespace jsoncons #endif // JSONCONS_EXT_BSON_BSON_OPTIONS_HPP jsoncons-1.3.2/include/jsoncons_ext/bson/bson_parser.hpp000066400000000000000000000564311477700171100235150ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_BSON_BSON_PARSER_HPP #define JSONCONS_EXT_BSON_BSON_PARSER_HPP #include #include #include #include #include #include // std::move #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace bson { enum class parse_mode {root,accept,document,array,value}; struct parse_state { parse_mode mode; std::size_t length; std::size_t pos; uint8_t type; std::size_t index{0}; parse_state(parse_mode mode_, std::size_t length_, std::size_t pos_, uint8_t type_ = 0) noexcept : mode(mode_), length(length_), pos(pos_), type(type_) { } parse_state(const parse_state&) = default; parse_state(parse_state&&) = default; parse_state& operator=(const parse_state&) = default; parse_state& operator=(parse_state&&) = default; }; template > class basic_bson_parser : public ser_context { using char_type = char; using char_traits_type = std::char_traits; using temp_allocator_type = TempAllocator; using char_allocator_type = typename std::allocator_traits:: template rebind_alloc; using byte_allocator_type = typename std::allocator_traits:: template rebind_alloc; using parse_state_allocator_type = typename std::allocator_traits:: template rebind_alloc; using string_type = std::basic_string,char_allocator_type>; bool more_{true}; bool done_{false}; bool cursor_mode_{false}; int mark_level_{0}; Source source_; bson_decode_options options_; std::vector bytes_buffer_; string_type name_buffer_; string_type text_buffer_; std::vector state_stack_; public: template basic_bson_parser(Sourceable&& source, const bson_decode_options& options = bson_decode_options(), const TempAllocator& temp_alloc = TempAllocator()) : source_(std::forward(source)), options_(options), bytes_buffer_(temp_alloc), name_buffer_(temp_alloc), text_buffer_(temp_alloc), state_stack_(temp_alloc) { state_stack_.emplace_back(parse_mode::root,0,0); } void restart() { more_ = true; } void reset() { more_ = true; done_ = false; bytes_buffer_.clear(); name_buffer_.clear(); text_buffer_.clear(); state_stack_.clear(); state_stack_.emplace_back(parse_mode::root,0,0); } template void reset(Sourceable&& source) { source_ = std::forward(source); reset(); } void cursor_mode(bool value) { cursor_mode_ = value; } int level() const { return static_cast(state_stack_.size()); } int mark_level() const { return mark_level_; } void mark_level(int value) { mark_level_ = value; } bool done() const { return done_; } bool stopped() const { return !more_; } std::size_t line() const override { return 0; } std::size_t column() const override { return source_.position(); } void array_expected(json_visitor& visitor, std::error_code& ec) { if (state_stack_.size() == 2 && state_stack_.back().mode == parse_mode::document) { state_stack_.back().mode = parse_mode::array; visitor.begin_array(semantic_tag::none, *this, ec); more_ = !cursor_mode_; } } void parse(json_visitor& visitor, std::error_code& ec) { if (JSONCONS_UNLIKELY(source_.is_error())) { ec = bson_errc::source_error; more_ = false; return; } while (!done_ && more_) { switch (state_stack_.back().mode) { case parse_mode::root: state_stack_.back().mode = parse_mode::accept; begin_document(visitor, ec); break; case parse_mode::document: { uint8_t type; std::size_t n = source_.read(&type, 1); state_stack_.back().pos += n; if (JSONCONS_UNLIKELY(n != 1)) { ec = bson_errc::unexpected_eof; more_ = false; return; } if (type != 0x00) { read_e_name(visitor,jsoncons::bson::bson_container_type::document,ec); state_stack_.back().mode = parse_mode::value; state_stack_.back().type = type; } else { end_document(visitor,ec); } break; } case parse_mode::array: { uint8_t type; std::size_t n = source_.read(&type, 1); state_stack_.back().pos += n; if (JSONCONS_UNLIKELY(n != 1)) { ec = bson_errc::unexpected_eof; more_ = false; return; } if (type != 0x00) { read_e_name(visitor,jsoncons::bson::bson_container_type::array,ec); read_value(visitor, type, ec); } else { end_array(visitor,ec); } break; } case parse_mode::value: state_stack_.back().mode = parse_mode::document; read_value(visitor,state_stack_.back().type,ec); break; case parse_mode::accept: { JSONCONS_ASSERT(state_stack_.size() == 1); state_stack_.clear(); more_ = false; done_ = true; visitor.flush(); break; } } } } private: void begin_document(json_visitor& visitor, std::error_code& ec) { if (JSONCONS_UNLIKELY(static_cast(state_stack_.size()) > options_.max_nesting_depth())) { ec = bson_errc::max_nesting_depth_exceeded; more_ = false; return; } uint8_t buf[sizeof(int32_t)]; std::size_t n = source_.read(buf, sizeof(int32_t)); if (JSONCONS_UNLIKELY(n != sizeof(int32_t))) { ec = bson_errc::unexpected_eof; more_ = false; return; } auto length = binary::little_to_native(buf, sizeof(buf)); visitor.begin_object(semantic_tag::none, *this, ec); more_ = !cursor_mode_; state_stack_.emplace_back(parse_mode::document,length,n); } void end_document(json_visitor& visitor, std::error_code& ec) { JSONCONS_ASSERT(state_stack_.size() >= 2); visitor.end_object(*this,ec); more_ = !cursor_mode_; if (level() == mark_level_) { more_ = false; } if (JSONCONS_UNLIKELY(state_stack_.back().pos != state_stack_.back().length)) { ec = bson_errc::size_mismatch; more_ = false; return; } std::size_t pos = state_stack_.back().pos; state_stack_.pop_back(); state_stack_.back().pos += pos; } void begin_array(json_visitor& visitor, std::error_code& ec) { if (JSONCONS_UNLIKELY(static_cast(state_stack_.size()) > options_.max_nesting_depth())) { ec = bson_errc::max_nesting_depth_exceeded; more_ = false; return; } uint8_t buf[sizeof(int32_t)]; std::size_t n = source_.read(buf, sizeof(int32_t)); if (JSONCONS_UNLIKELY(n != sizeof(int32_t))) { ec = bson_errc::unexpected_eof; more_ = false; return; } auto length = binary::little_to_native(buf, sizeof(buf)); visitor.begin_array(semantic_tag::none, *this, ec); more_ = !cursor_mode_; if (JSONCONS_UNLIKELY(ec)) { return; } state_stack_.emplace_back(parse_mode::array, length, n); } void end_array(json_visitor& visitor, std::error_code& ec) { JSONCONS_ASSERT(state_stack_.size() >= 2); visitor.end_array(*this, ec); more_ = !cursor_mode_; if (level() == mark_level_) { more_ = false; } if (JSONCONS_UNLIKELY(state_stack_.back().pos != state_stack_.back().length)) { ec = bson_errc::size_mismatch; more_ = false; return; } std::size_t pos = state_stack_.back().pos; state_stack_.pop_back(); state_stack_.back().pos += pos; } void read_e_name(json_visitor& visitor, jsoncons::bson::bson_container_type type, std::error_code& ec) { name_buffer_.clear(); read_cstring(name_buffer_, ec); if (JSONCONS_UNLIKELY(ec)) { return; } if (type == jsoncons::bson::bson_container_type::document) { auto result = unicode_traits::validate(name_buffer_.data(),name_buffer_.size()); if (JSONCONS_UNLIKELY(result.ec != unicode_traits::conv_errc())) { ec = bson_errc::invalid_utf8_text_string; more_ = false; return; } visitor.key(jsoncons::basic_string_view(name_buffer_.data(),name_buffer_.length()), *this, ec); more_ = !cursor_mode_; } } void read_value(json_visitor& visitor, uint8_t type, std::error_code& ec) { switch (type) { case jsoncons::bson::bson_type::double_type: { uint8_t buf[sizeof(double)]; std::size_t n = source_.read(buf, sizeof(double)); state_stack_.back().pos += n; if (JSONCONS_UNLIKELY(n != sizeof(double))) { ec = bson_errc::unexpected_eof; more_ = false; return; } double res = binary::little_to_native(buf, sizeof(buf)); visitor.double_value(res, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::bson::bson_type::symbol_type: case jsoncons::bson::bson_type::min_key_type: case jsoncons::bson::bson_type::max_key_type: case jsoncons::bson::bson_type::string_type: { text_buffer_.clear(); read_string(text_buffer_, ec); if (JSONCONS_UNLIKELY(ec)) { return; } auto result = unicode_traits::validate(text_buffer_.data(), text_buffer_.size()); if (JSONCONS_UNLIKELY(result.ec != unicode_traits::conv_errc())) { ec = bson_errc::invalid_utf8_text_string; more_ = false; return; } visitor.string_value(text_buffer_, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::bson::bson_type::javascript_type: { text_buffer_.clear(); read_string(text_buffer_, ec); if (JSONCONS_UNLIKELY(ec)) { return; } auto result = unicode_traits::validate(text_buffer_.data(), text_buffer_.size()); if (JSONCONS_UNLIKELY(result.ec != unicode_traits::conv_errc())) { ec = bson_errc::invalid_utf8_text_string; more_ = false; return; } visitor.string_value(text_buffer_, semantic_tag::code, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::bson::bson_type::regex_type: { text_buffer_.clear(); text_buffer_.push_back('/'); read_cstring(text_buffer_, ec); if (JSONCONS_UNLIKELY(ec)) { return; } text_buffer_.push_back('/'); read_cstring(text_buffer_, ec); if (JSONCONS_UNLIKELY(ec)) { return; } visitor.string_value(text_buffer_, semantic_tag::regex, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::bson::bson_type::document_type: { begin_document(visitor,ec); break; } case jsoncons::bson::bson_type::array_type: { begin_array(visitor,ec); break; } case jsoncons::bson::bson_type::undefined_type: { visitor.null_value(semantic_tag::undefined, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::bson::bson_type::null_type: { visitor.null_value(semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::bson::bson_type::bool_type: { uint8_t c; std::size_t n = source_.read(&c, 1); state_stack_.back().pos += n; if (JSONCONS_UNLIKELY(n != 1)) { ec = bson_errc::unexpected_eof; more_ = false; return; } visitor.bool_value(c != 0, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::bson::bson_type::int32_type: { uint8_t buf[sizeof(int32_t)]; std::size_t n = source_.read(buf, sizeof(int32_t)); state_stack_.back().pos += n; if (JSONCONS_UNLIKELY(n != sizeof(int32_t))) { ec = bson_errc::unexpected_eof; more_ = false; return; } auto val = binary::little_to_native(buf, sizeof(buf)); visitor.int64_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::bson::bson_type::timestamp_type: { uint8_t buf[sizeof(uint64_t)]; std::size_t n = source_.read(buf, sizeof(uint64_t)); state_stack_.back().pos += n; if (JSONCONS_UNLIKELY(n != sizeof(uint64_t))) { ec = bson_errc::unexpected_eof; more_ = false; return; } auto val = binary::little_to_native(buf, sizeof(buf)); visitor.uint64_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::bson::bson_type::int64_type: { uint8_t buf[sizeof(int64_t)]; std::size_t n = source_.read(buf, sizeof(int64_t)); state_stack_.back().pos += n; if (JSONCONS_UNLIKELY(n != sizeof(int64_t))) { ec = bson_errc::unexpected_eof; more_ = false; return; } auto val = binary::little_to_native(buf, sizeof(buf)); visitor.int64_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::bson::bson_type::datetime_type: { uint8_t buf[sizeof(int64_t)]; std::size_t n = source_.read(buf, sizeof(int64_t)); state_stack_.back().pos += n; if (JSONCONS_UNLIKELY(n != sizeof(int64_t))) { ec = bson_errc::unexpected_eof; more_ = false; return; } auto val = binary::little_to_native(buf, sizeof(buf)); visitor.int64_value(val, semantic_tag::epoch_milli, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::bson::bson_type::binary_type: { uint8_t buf[sizeof(int32_t)]; std::size_t n = source_.read(buf, sizeof(int32_t)); state_stack_.back().pos += n; if (JSONCONS_UNLIKELY(n != sizeof(int32_t))) { ec = bson_errc::unexpected_eof; more_ = false; return; } const auto len = binary::little_to_native(buf, sizeof(buf)); if (JSONCONS_UNLIKELY(len < 0)) { ec = bson_errc::length_is_negative; more_ = false; return; } uint8_t subtype; n = source_.read(&subtype, 1); state_stack_.back().pos += n; if (JSONCONS_UNLIKELY(n != 1)) { ec = bson_errc::unexpected_eof; more_ = false; return; } bytes_buffer_.clear(); n = source_reader::read(source_, bytes_buffer_, len); state_stack_.back().pos += n; if (JSONCONS_UNLIKELY(n != static_cast(len))) { ec = bson_errc::unexpected_eof; more_ = false; return; } visitor.byte_string_value(bytes_buffer_, subtype, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::bson::bson_type::decimal128_type: { uint8_t buf[sizeof(uint64_t)*2]; std::size_t n = source_.read(buf, sizeof(buf)); state_stack_.back().pos += n; if (JSONCONS_UNLIKELY(n != sizeof(buf))) { ec = bson_errc::unexpected_eof; more_ = false; return; } decimal128_t dec; dec.low = binary::little_to_native(buf, sizeof(uint64_t)); dec.high = binary::little_to_native(buf+sizeof(uint64_t), sizeof(uint64_t)); text_buffer_.clear(); text_buffer_.resize(bson::decimal128_limits::buf_size); auto r = bson::decimal128_to_chars(&text_buffer_[0], &text_buffer_[0]+text_buffer_.size(), dec); visitor.string_value(string_view(text_buffer_.data(),static_cast(r.ptr-text_buffer_.data())), semantic_tag::float128, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::bson::bson_type::object_id_type: { uint8_t buf[12]; std::size_t n = source_.read(buf, sizeof(buf)); state_stack_.back().pos += n; if (JSONCONS_UNLIKELY(n != sizeof(buf))) { ec = bson_errc::unexpected_eof; more_ = false; return; } oid_t oid(buf); to_string(oid, text_buffer_); visitor.string_value(text_buffer_, semantic_tag::id, *this, ec); more_ = !cursor_mode_; break; } default: { ec = bson_errc::unknown_type; more_ = false; return; } } } void read_cstring(string_type& buffer, std::error_code& ec) { uint8_t c = 0xff; while (true) { std::size_t n = source_.read(&c, 1); state_stack_.back().pos += n; if (JSONCONS_UNLIKELY(n != 1)) { ec = bson_errc::unexpected_eof; more_ = false; return; } if (c == 0) { break; } buffer.push_back(c); } } void read_string(string_type& buffer, std::error_code& ec) { uint8_t buf[sizeof(int32_t)]; std::size_t n = source_.read(buf, sizeof(int32_t)); state_stack_.back().pos += n; if (JSONCONS_UNLIKELY(n != sizeof(int32_t))) { ec = bson_errc::unexpected_eof; more_ = false; return; } auto len = binary::little_to_native(buf, sizeof(buf)); if (JSONCONS_UNLIKELY(len < 1)) { ec = bson_errc::string_length_is_non_positive; more_ = false; return; } std::size_t size = static_cast(len) - static_cast(1); n = source_reader::read(source_, buffer, size); state_stack_.back().pos += n; if (JSONCONS_UNLIKELY(n != size)) { ec = bson_errc::unexpected_eof; more_ = false; return; } uint8_t c; n = source_.read(&c, 1); state_stack_.back().pos += n; if (JSONCONS_UNLIKELY(n != 1)) { ec = bson_errc::unexpected_eof; more_ = false; return; } } }; } // namespace bson } // namespace jsoncons #endif // JSONCONS_EXT_BSON_BSON_PARSER_HPP jsoncons-1.3.2/include/jsoncons_ext/bson/bson_reader.hpp000066400000000000000000000045301477700171100234540ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_BSON_BSON_READER_HPP #define JSONCONS_EXT_BSON_BSON_READER_HPP #include #include #include #include // std::move #include #include #include #include #include namespace jsoncons { namespace bson { template > class basic_bson_reader { basic_bson_parser parser_; json_visitor& visitor_; public: template basic_bson_reader(Sourceable&& source, json_visitor& visitor, const TempAllocator& temp_alloc) : basic_bson_reader(std::forward(source), visitor, bson_decode_options(), temp_alloc) { } template basic_bson_reader(Sourceable&& source, json_visitor& visitor, const bson_decode_options& options = bson_decode_options(), const TempAllocator& temp_alloc=TempAllocator()) : parser_(std::forward(source), options, temp_alloc), visitor_(visitor) { } void read() { std::error_code ec; read(ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,line(),column())); } } void read(std::error_code& ec) { parser_.reset(); parser_.parse(visitor_, ec); if (JSONCONS_UNLIKELY(ec)) { return; } } std::size_t line() const { return parser_.line(); } std::size_t column() const { return parser_.column(); } }; using bson_stream_reader = basic_bson_reader; using bson_bytes_reader = basic_bson_reader; } // namespace bson } // namespace jsoncons #endif // JSONCONS_EXT_BSON_BSON_READER_HPP jsoncons-1.3.2/include/jsoncons_ext/bson/bson_type.hpp000066400000000000000000000030241477700171100231700ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_BSON_BSON_TYPE_HPP #define JSONCONS_EXT_BSON_BSON_TYPE_HPP #include namespace jsoncons { namespace bson { namespace bson_type { const uint8_t double_type = 0x01; const uint8_t string_type = 0x02; // UTF-8 string const uint8_t document_type = 0x03; const uint8_t array_type = 0x04; const uint8_t binary_type = 0x05; const uint8_t undefined_type = 0x06; // map to null const uint8_t object_id_type = 0x07; const uint8_t bool_type = 0x08; const uint8_t datetime_type = 0x09; const uint8_t null_type = 0x0a; const uint8_t regex_type = 0x0b; const uint8_t javascript_type = 0x0d; const uint8_t symbol_type = 0x0e; // deprecated, mapped to string const uint8_t javascript_with_scope_type = 0x0f; // unsupported const uint8_t int32_type = 0x10; const uint8_t timestamp_type = 0x11; // MongoDB internal Timestamp, uint64 const uint8_t int64_type = 0x12; const uint8_t decimal128_type = 0x13; const uint8_t min_key_type = 0xff; const uint8_t max_key_type = 0x7f; } enum class bson_container_type {document, array}; } // namespace bson } // namespace jsoncons #endif // JSONCONS_EXT_BSON_BSON_TYPE_HPP jsoncons-1.3.2/include/jsoncons_ext/bson/decode_bson.hpp000066400000000000000000000213011477700171100234300ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_BSON_DECODE_BSON_HPP #define JSONCONS_EXT_BSON_DECODE_BSON_HPP #include // std::basic_istream #include // std::enable_if #include #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace bson { template typename std::enable_if::value && extension_traits::is_byte_sequence::value,T>::type decode_bson(const Source& v, const bson_decode_options& options = bson_decode_options()) { jsoncons::json_decoder decoder; auto adaptor = make_json_visitor_adaptor(decoder); basic_bson_reader reader(v, adaptor, options); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value && extension_traits::is_byte_sequence::value,T>::type decode_bson(const Source& v, const bson_decode_options& options = bson_decode_options()) { basic_bson_cursor cursor(v, options); json_decoder> decoder{}; std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } template typename std::enable_if::value,T>::type decode_bson(std::istream& is, const bson_decode_options& options = bson_decode_options()) { jsoncons::json_decoder decoder; auto adaptor = make_json_visitor_adaptor(decoder); bson_stream_reader reader(is, adaptor, options); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value,T>::type decode_bson(std::istream& is, const bson_decode_options& options = bson_decode_options()) { basic_bson_cursor cursor(is, options); json_decoder> decoder{}; std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } template typename std::enable_if::value,T>::type decode_bson(InputIt first, InputIt last, const bson_decode_options& options = bson_decode_options()) { jsoncons::json_decoder decoder; auto adaptor = make_json_visitor_adaptor(decoder); basic_bson_reader> reader(binary_iterator_source(first, last), adaptor, options); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value,T>::type decode_bson(InputIt first, InputIt last, const bson_decode_options& options = bson_decode_options()) { basic_bson_cursor> cursor(binary_iterator_source(first, last), options); json_decoder> decoder{}; std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } // With leading allocator_set parameter template typename std::enable_if::value && extension_traits::is_byte_sequence::value,T>::type decode_bson(const allocator_set& alloc_set, const Source& v, const bson_decode_options& options = bson_decode_options()) { json_decoder decoder(alloc_set.get_allocator(), alloc_set.get_temp_allocator()); auto adaptor = make_json_visitor_adaptor(decoder); basic_bson_reader reader(v, adaptor, options, alloc_set.get_temp_allocator()); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value && extension_traits::is_byte_sequence::value,T>::type decode_bson(const allocator_set& alloc_set, const Source& v, const bson_decode_options& options = bson_decode_options()) { basic_bson_cursor cursor(v, options, alloc_set.get_temp_allocator()); json_decoder,TempAllocator> decoder(alloc_set.get_temp_allocator(), alloc_set.get_temp_allocator()); std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } template typename std::enable_if::value,T>::type decode_bson(const allocator_set& alloc_set, std::istream& is, const bson_decode_options& options = bson_decode_options()) { json_decoder decoder(alloc_set.get_allocator(), alloc_set.get_temp_allocator()); auto adaptor = make_json_visitor_adaptor(decoder); basic_bson_reader reader(is, adaptor, options, alloc_set.get_temp_allocator()); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value,T>::type decode_bson(const allocator_set& alloc_set, std::istream& is, const bson_decode_options& options = bson_decode_options()) { basic_bson_cursor cursor(is, options, alloc_set.get_temp_allocator()); json_decoder,TempAllocator> decoder(alloc_set.get_temp_allocator(), alloc_set.get_temp_allocator()); std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } } // namespace bson } // namespace jsoncons #endif // JSONCONS_EXT_BSON_DECODE_BSON_HPP jsoncons-1.3.2/include/jsoncons_ext/bson/encode_bson.hpp000066400000000000000000000142721477700171100234530ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_BSON_ENCODE_BSON_HPP #define JSONCONS_EXT_BSON_ENCODE_BSON_HPP #include // std::basic_ostream #include #include // std::enable_if #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace bson { template typename std::enable_if::value && extension_traits::is_back_insertable_byte_container::value,void>::type encode_bson(const T& j, ByteContainer& cont, const bson_encode_options& options = bson_encode_options()) { using char_type = typename T::char_type; basic_bson_encoder> encoder(cont, options); auto adaptor = make_json_visitor_adaptor>(encoder); j.dump(adaptor); } template typename std::enable_if::value && extension_traits::is_back_insertable_byte_container::value,void>::type encode_bson(const T& val, ByteContainer& cont, const bson_encode_options& options = bson_encode_options()) { basic_bson_encoder> encoder(cont, options); std::error_code ec; encode_traits::encode(val, encoder, json(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } template typename std::enable_if::value,void>::type encode_bson(const T& j, std::ostream& os, const bson_encode_options& options = bson_encode_options()) { using char_type = typename T::char_type; bson_stream_encoder encoder(os, options); auto adaptor = make_json_visitor_adaptor>(encoder); j.dump(adaptor); } template typename std::enable_if::value,void>::type encode_bson(const T& val, std::ostream& os, const bson_encode_options& options = bson_encode_options()) { bson_stream_encoder encoder(os, options); std::error_code ec; encode_traits::encode(val, encoder, json(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } // with temp_allocator_rag template typename std::enable_if::value && extension_traits::is_back_insertable_byte_container::value,void>::type encode_bson(const allocator_set& alloc_set, const T& j, ByteContainer& cont, const bson_encode_options& options = bson_encode_options()) { using char_type = typename T::char_type; basic_bson_encoder,TempAllocator> encoder(cont, options, alloc_set.get_temp_allocator()); auto adaptor = make_json_visitor_adaptor>(encoder); j.dump(adaptor); } template typename std::enable_if::value && extension_traits::is_back_insertable_byte_container::value,void>::type encode_bson(const allocator_set& alloc_set, const T& val, ByteContainer& cont, const bson_encode_options& options = bson_encode_options()) { basic_bson_encoder,TempAllocator> encoder(cont, options, alloc_set.get_temp_allocator()); std::error_code ec; encode_traits::encode(val, encoder, json(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } template typename std::enable_if::value,void>::type encode_bson(const allocator_set& alloc_set, const T& j, std::ostream& os, const bson_encode_options& options = bson_encode_options()) { using char_type = typename T::char_type; basic_bson_encoder encoder(os, options, alloc_set.get_temp_allocator()); auto adaptor = make_json_visitor_adaptor>(encoder); j.dump(adaptor); } template typename std::enable_if::value,void>::type encode_bson(const allocator_set& alloc_set, const T& val, std::ostream& os, const bson_encode_options& options = bson_encode_options()) { basic_bson_encoder encoder(os, options, alloc_set.get_temp_allocator()); std::error_code ec; encode_traits::encode(val, encoder, json(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } } // namespace bson } // namespace jsoncons #endif // JSONCONS_EXT_BSON_ENCODE_BSON_HPP jsoncons-1.3.2/include/jsoncons_ext/cbor/000077500000000000000000000000001477700171100204425ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons_ext/cbor/cbor.hpp000066400000000000000000000011141477700171100220750ustar00rootroot00000000000000// Copyright 2017-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_CBOR_CBOR_HPP #define JSONCONS_EXT_CBOR_CBOR_HPP #include #include #include #include #include #endif // JSONCONS_EXT_CBOR_CBOR_HPP jsoncons-1.3.2/include/jsoncons_ext/cbor/cbor_cursor.hpp000066400000000000000000000204011477700171100234720ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_CBOR_CBOR_CURSOR_HPP #define JSONCONS_EXT_CBOR_CBOR_CURSOR_HPP #include #include #include #include // std::allocator #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace cbor { template > class basic_cbor_cursor : public basic_staj_cursor, private virtual ser_context { public: using source_type = Source; using char_type = char; using allocator_type = Allocator; private: basic_cbor_parser parser_; basic_staj_visitor cursor_visitor_; basic_item_event_visitor_to_json_visitor cursor_handler_adaptor_; bool eof_{false}; public: using string_view_type = string_view; // Noncopyable and nonmoveable basic_cbor_cursor(const basic_cbor_cursor&) = delete; basic_cbor_cursor(basic_cbor_cursor&&) = delete; template basic_cbor_cursor(Sourceable&& source, const cbor_decode_options& options = cbor_decode_options(), const Allocator& alloc = Allocator()) : parser_(std::forward(source), options, alloc), cursor_handler_adaptor_(cursor_visitor_, alloc) { parser_.cursor_mode(true); if (!done()) { next(); } } // Constructors that set parse error codes template basic_cbor_cursor(Sourceable&& source, std::error_code& ec) : basic_cbor_cursor(std::allocator_arg, Allocator(), std::forward(source), cbor_decode_options(), ec) { } template basic_cbor_cursor(Sourceable&& source, const cbor_decode_options& options, std::error_code& ec) : basic_cbor_cursor(std::allocator_arg, Allocator(), std::forward(source), options, ec) { } template basic_cbor_cursor(std::allocator_arg_t, const Allocator& alloc, Sourceable&& source, const cbor_decode_options& options, std::error_code& ec) : parser_(std::forward(source), options, alloc), cursor_handler_adaptor_(cursor_visitor_, alloc), eof_(false) { parser_.cursor_mode(true); if (!done()) { next(ec); } } ~basic_cbor_cursor() = default; basic_cbor_cursor& operator=(const basic_cbor_cursor&) = delete; basic_cbor_cursor& operator=(basic_cbor_cursor&&) = delete; void reset() { parser_.reset(); cursor_visitor_.reset(); cursor_handler_adaptor_.reset(); eof_ = false; if (!done()) { next(); } } template void reset(Sourceable&& source) { parser_.reset(std::forward(source)); cursor_visitor_.reset(); cursor_handler_adaptor_.reset(); eof_ = false; if (!done()) { next(); } } void reset(std::error_code& ec) { parser_.reset(); cursor_visitor_.reset(); cursor_handler_adaptor_.reset(); eof_ = false; if (!done()) { next(ec); } } template void reset(Sourceable&& source, std::error_code& ec) { parser_.reset(std::forward(source)); cursor_visitor_.reset(); cursor_handler_adaptor_.reset(); eof_ = false; if (!done()) { next(ec); } } bool done() const override { return parser_.done(); } uint64_t raw_tag() const { return parser_.raw_tag(); } bool is_typed_array() const { return cursor_visitor_.is_typed_array(); } const staj_event& current() const override { return cursor_visitor_.event(); } void read_to(basic_json_visitor& visitor) override { std::error_code ec; read_to(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); } } void read_to(basic_json_visitor& visitor, std::error_code& ec) override { if (is_typed_array()) { cursor_visitor_.dump(visitor, *this, ec); } else if (is_begin_container(current().event_type())) { parser_.cursor_mode(false); parser_.mark_level(parser_.level()); cursor_visitor_.event().send_json_event(visitor, *this, ec); if (JSONCONS_UNLIKELY(ec)) { return; } read_next(visitor, ec); parser_.cursor_mode(true); parser_.mark_level(0); if (current().event_type() == staj_event_type::begin_object) { cursor_visitor_.end_object(*this); } else { cursor_visitor_.end_array(*this); } } else { cursor_visitor_.event().send_json_event(visitor, *this, ec); } } void next() override { std::error_code ec; next(ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); } } void next(std::error_code& ec) override { read_next(ec); } const ser_context& context() const override { return *this; } bool eof() const { return eof_; } std::size_t line() const override { return parser_.line(); } std::size_t column() const override { return parser_.column(); } friend staj_filter_view operator|(basic_cbor_cursor& cursor, std::function pred) { return staj_filter_view(cursor, pred); } private: void read_next(std::error_code& ec) { if (cursor_visitor_.in_available()) { cursor_visitor_.send_available(ec); } else { parser_.restart(); while (!parser_.stopped()) { parser_.parse(cursor_handler_adaptor_, ec); if (JSONCONS_UNLIKELY(ec)) {return;} } } } void read_next(basic_json_visitor& visitor, std::error_code& ec) { { struct resource_wrapper { basic_item_event_visitor_to_json_visitor& adaptor; basic_json_visitor& original; resource_wrapper(basic_item_event_visitor_to_json_visitor& adaptor, basic_json_visitor& visitor) : adaptor(adaptor), original(adaptor.destination()) { adaptor.destination(visitor); } ~resource_wrapper() { adaptor.destination(original); } } wrapper(cursor_handler_adaptor_, visitor); parser_.restart(); while (!parser_.stopped()) { parser_.parse(cursor_handler_adaptor_, ec); if (JSONCONS_UNLIKELY(ec)) { return; } } } } }; using cbor_stream_cursor = basic_cbor_cursor; using cbor_bytes_cursor = basic_cbor_cursor; } // namespace cbor } // namespace jsoncons #endif jsoncons-1.3.2/include/jsoncons_ext/cbor/cbor_detail.hpp000066400000000000000000000047621477700171100234330ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_CBOR_CBOR_DETAIL_HPP #define JSONCONS_EXT_CBOR_CBOR_DETAIL_HPP #include #include #include #include // 0x00..0x17 (0..23) #define JSONCONS_EXT_CBOR_0x00_0x17 \ 0x00:case 0x01:case 0x02:case 0x03:case 0x04:case 0x05:case 0x06:case 0x07:case 0x08:case 0x09:case 0x0a:case 0x0b:case 0x0c:case 0x0d:case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12:case 0x13:case 0x14:case 0x15:case 0x16:case 0x17 #define JSONCONS_EXT_CBOR_ARRAY_TAGS \ 0x40:case 0x41:case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:case 0x47:case 0x48:case 0x49:case 0x4a:case 0x4b:case 0x4c:case 0x4d:case 0x4e:case 0x4f:case 0x50:case 0x51:case 0x52:case 0x53:case 0x54:case 0x55:case 0x56:case 0x57 namespace jsoncons { namespace cbor { namespace detail { //const uint8_t cbor_array_tags_010_mask = 0b11100000; //const uint8_t cbor_array_tags_f_mask = 0b00010000; //const uint8_t cbor_array_tags_s_mask = 0b00001000; //const uint8_t cbor_array_tags_e_mask = 0b00000100; //const uint8_t cbor_array_tags_ll_mask = 0b00000011; const uint8_t cbor_array_tags_010_mask = 0xE0; const uint8_t cbor_array_tags_f_mask = 0x10; const uint8_t cbor_array_tags_s_mask = 0x08; const uint8_t cbor_array_tags_e_mask = 0x04; const uint8_t cbor_array_tags_ll_mask = 0x03; const uint8_t cbor_array_tags_010_shift = 5; const uint8_t cbor_array_tags_f_shift = 4; const uint8_t cbor_array_tags_s_shift = 3; const uint8_t cbor_array_tags_e_shift = 2; const uint8_t cbor_array_tags_ll_shift = 0; enum class cbor_major_type : uint8_t { unsigned_integer = 0x00, negative_integer = 0x01, byte_string = 0x02, text_string = 0x03, array = 0x04, map = 0x05, semantic_tag = 0x06, simple = 0x7 }; namespace additional_info { const uint8_t indefinite_length = 0x1f; } inline size_t min_length_for_stringref(uint64_t index) { std::size_t n; if (index <= 23) { n = 3; } else if (index <= 255) { n = 4; } else if (index <= 65535) { n = 5; } else if (index <= 4294967295) { n = 7; } else { n = 11; } return n; } } // namespace detail } // namespace cbor } // namespace jsoncons #endif jsoncons-1.3.2/include/jsoncons_ext/cbor/cbor_encoder.hpp000066400000000000000000001744661477700171100236210ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_CBOR_CBOR_ENCODER_HPP #define JSONCONS_EXT_CBOR_CBOR_ENCODER_HPP #include #include #include #include // std::numeric_limits #include #include #include #include #include #include // std::move #include #include #include #include #include // jsoncons::ser_error #include #include #include #include #include #include #include #include namespace jsoncons { namespace cbor { enum class cbor_container_type {object, indefinite_length_object, array, indefinite_length_array}; template > class basic_cbor_encoder final : public basic_json_visitor { using super_type = basic_json_visitor; enum class decimal_parse_state { start, integer, exp1, exp2, fraction1 }; enum class hexfloat_parse_state { start, expect_0, expect_x, integer, exp1, exp2, fraction1 }; static constexpr int64_t nanos_in_second = 1000000000; static constexpr int64_t millis_in_second = 1000; public: using allocator_type = Allocator; using sink_type = Sink; using typename super_type::char_type; using typename super_type::string_view_type; private: using char_allocator_type = typename std::allocator_traits:: template rebind_alloc; using byte_allocator_type = typename std::allocator_traits:: template rebind_alloc; using string_type = std::basic_string,char_allocator_type>; using byte_string_type = basic_byte_string; struct stack_item { cbor_container_type type_; std::size_t length_{0}; std::size_t index_{0}; stack_item(cbor_container_type type, std::size_t length = 0) noexcept : type_(type), length_(length) { } ~stack_item() = default; std::size_t length() const { return length_; } std::size_t count() const { return is_object() ? index_/2 : index_; } bool is_object() const { return type_ == cbor_container_type::object || type_ == cbor_container_type::indefinite_length_object; } bool is_indefinite_length() const { return type_ == cbor_container_type::indefinite_length_array || type_ == cbor_container_type::indefinite_length_object; } }; using string_size_allocator_type = typename std::allocator_traits:: template rebind_alloc>; using byte_string_size_allocator_type = typename std::allocator_traits:: template rebind_alloc>; using stack_item_allocator_type = typename std::allocator_traits:: template rebind_alloc; Sink sink_; const cbor_encode_options options_; allocator_type alloc_; std::vector stack_; std::map,string_size_allocator_type> stringref_map_; std::map,byte_string_size_allocator_type> bytestringref_map_; std::size_t next_stringref_ = 0; int nesting_depth_{0}; public: // Noncopyable and nonmoveable basic_cbor_encoder(const basic_cbor_encoder&) = delete; basic_cbor_encoder(basic_cbor_encoder&&) = delete; explicit basic_cbor_encoder(Sink&& sink, const Allocator& alloc = Allocator()) : basic_cbor_encoder(std::forward(sink), cbor_encode_options(), alloc) { } basic_cbor_encoder(Sink&& sink, const cbor_encode_options& options, const Allocator& alloc = Allocator()) : sink_(std::forward(sink)), options_(options), alloc_(alloc), stack_(alloc), stringref_map_(alloc), bytestringref_map_(alloc) { if (options.pack_strings()) { write_tag(256); } } ~basic_cbor_encoder() noexcept { JSONCONS_TRY { sink_.flush(); } JSONCONS_CATCH(...) { } } basic_cbor_encoder& operator=(const basic_cbor_encoder&) = delete; basic_cbor_encoder& operator=(basic_cbor_encoder&&) = delete; void reset() { stack_.clear(); stringref_map_.clear(); bytestringref_map_.clear(); next_stringref_ = 0; nesting_depth_ = 0; } void reset(Sink&& sink) { sink_ = std::move(sink); reset(); } void begin_object_with_tag(uint64_t raw_tag) { write_tag(raw_tag); begin_object(); } void begin_object_with_tag(std::size_t length, uint64_t raw_tag) { write_tag(raw_tag); begin_object(length); } void begin_array_with_tag(uint64_t raw_tag) { write_tag(raw_tag); begin_array(); } void begin_array_with_tag(std::size_t length, uint64_t raw_tag) { write_tag(raw_tag); begin_array(length); } void null_value_with_tag(uint64_t raw_tag) { write_tag(raw_tag); sink_.push_back(0xf6); end_value(); } void bool_value_with_tag(bool value, uint64_t raw_tag) { write_tag(raw_tag); if (value) { sink_.push_back(0xf5); } else { sink_.push_back(0xf4); } end_value(); } void string_value_with_tag(const string_view_type& value, uint64_t raw_tag) { write_tag(raw_tag); write_string(value); end_value(); } template void byte_string_value_with_tag(const ByteStringLike& value, uint64_t raw_tag, typename std::enable_if::value,int>::type = 0) { write_tag(raw_tag); write_byte_string(byte_string_view(reinterpret_cast(value.data()),value.size())); end_value(); } void double_value_with_tag(double value, uint64_t raw_tag) { write_tag(raw_tag); double_value(value); } void uint64_value_with_tag(uint64_t value, uint64_t raw_tag) { write_tag(raw_tag); write_uint64_value(value); end_value(); } void int64_value_with_tag(int64_t value, uint64_t raw_tag) { write_tag(raw_tag); write_int64_value(value); end_value(); } private: // Implementing methods void visit_flush() override { sink_.flush(); } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag, const ser_context&, std::error_code& ec) override { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = cbor_errc::max_nesting_depth_exceeded; JSONCONS_VISITOR_RETURN; } stack_.emplace_back(cbor_container_type::indefinite_length_object); sink_.push_back(0xbf); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(std::size_t length, semantic_tag, const ser_context&, std::error_code& ec) override { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = cbor_errc::max_nesting_depth_exceeded; JSONCONS_VISITOR_RETURN; } stack_.emplace_back(cbor_container_type::object, length); if (length <= 0x17) { binary::native_to_big(static_cast(0xa0 + length), std::back_inserter(sink_)); } else if (length <= 0xff) { binary::native_to_big(static_cast(0xb8), std::back_inserter(sink_)); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } else if (length <= 0xffff) { binary::native_to_big(static_cast(0xb9), std::back_inserter(sink_)); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } else if (length <= 0xffffffff) { binary::native_to_big(static_cast(0xba), std::back_inserter(sink_)); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } else if (uint64_t(length) <= (std::numeric_limits::max)()) { binary::native_to_big(static_cast(0xbb), std::back_inserter(sink_)); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context&, std::error_code& ec) override { JSONCONS_ASSERT(!stack_.empty()); --nesting_depth_; if (stack_.back().is_indefinite_length()) { sink_.push_back(0xff); } else { if (stack_.back().count() < stack_.back().length()) { ec = cbor_errc::too_few_items; JSONCONS_VISITOR_RETURN; } if (stack_.back().count() > stack_.back().length()) { ec = cbor_errc::too_many_items; JSONCONS_VISITOR_RETURN; } } stack_.pop_back(); end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag, const ser_context&, std::error_code& ec) override { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = cbor_errc::max_nesting_depth_exceeded; JSONCONS_VISITOR_RETURN; } stack_.emplace_back(cbor_container_type::indefinite_length_array); sink_.push_back(0x9f); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(std::size_t length, semantic_tag, const ser_context&, std::error_code& ec) override { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = cbor_errc::max_nesting_depth_exceeded; JSONCONS_VISITOR_RETURN; } stack_.emplace_back(cbor_container_type::array, length); if (length <= 0x17) { binary::native_to_big(static_cast(0x80 + length), std::back_inserter(sink_)); } else if (length <= 0xff) { binary::native_to_big(static_cast(0x98), std::back_inserter(sink_)); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } else if (length <= 0xffff) { binary::native_to_big(static_cast(0x99), std::back_inserter(sink_)); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } else if (length <= 0xffffffff) { binary::native_to_big(static_cast(0x9a), std::back_inserter(sink_)); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } else if (uint64_t(length) <= (std::numeric_limits::max)()) { binary::native_to_big(static_cast(0x9b), std::back_inserter(sink_)); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context&, std::error_code& ec) override { JSONCONS_ASSERT(!stack_.empty()); --nesting_depth_; if (stack_.back().is_indefinite_length()) { sink_.push_back(0xff); } else { if (stack_.back().count() < stack_.back().length()) { ec = cbor_errc::too_few_items; JSONCONS_VISITOR_RETURN; } if (stack_.back().count() > stack_.back().length()) { ec = cbor_errc::too_many_items; JSONCONS_VISITOR_RETURN; } } stack_.pop_back(); end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type& name, const ser_context& context, std::error_code& ec) override { visit_string(name, semantic_tag::none, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag tag, const ser_context&, std::error_code&) override { if (tag == semantic_tag::undefined) { sink_.push_back(0xf7); } else { sink_.push_back(0xf6); } end_value(); JSONCONS_VISITOR_RETURN; } void write_string(const string_view& sv) { auto sink = unicode_traits::validate(sv.data(), sv.size()); if (sink.ec != unicode_traits::conv_errc()) { JSONCONS_THROW(ser_error(cbor_errc::invalid_utf8_text_string)); } if (options_.pack_strings() && sv.size() >= jsoncons::cbor::detail::min_length_for_stringref(next_stringref_)) { string_type s(sv.data(), sv.size(), alloc_); auto it = stringref_map_.find(s); if (it == stringref_map_.end()) { stringref_map_.emplace(std::make_pair(std::move(s), next_stringref_++)); write_utf8_string(sv); } else { write_tag(25); write_uint64_value((*it).second); } } else { write_utf8_string(sv); } } void write_utf8_string(const string_view& sv) { const size_t length = sv.size(); if (length <= 0x17) { // fixstr stores a byte array whose length is upto 31 bytes binary::native_to_big(static_cast(0x60 + length), std::back_inserter(sink_)); } else if (length <= 0xff) { binary::native_to_big(static_cast(0x78), std::back_inserter(sink_)); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } else if (length <= 0xffff) { binary::native_to_big(static_cast(0x79), std::back_inserter(sink_)); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } else if (length <= 0xffffffff) { binary::native_to_big(static_cast(0x7a), std::back_inserter(sink_)); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } else if (uint64_t(length) <= (std::numeric_limits::max)()) { binary::native_to_big(static_cast(0x7b), std::back_inserter(sink_)); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } for (auto c : sv) { sink_.push_back(c); } } void write_bignum(bigint& n) { bool is_neg = n < 0; if (is_neg) { n = - n -1; } int signum; std::vector data; n.write_bytes_be(signum, data); std::size_t length = data.size(); if (is_neg) { write_tag(3); } else { write_tag(2); } if (length <= 0x17) { // fixstr stores a byte array whose length is upto 31 bytes binary::native_to_big(static_cast(0x40 + length), std::back_inserter(sink_)); } else if (length <= 0xff) { binary::native_to_big(static_cast(0x58), std::back_inserter(sink_)); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } else if (length <= 0xffff) { binary::native_to_big(static_cast(0x59), std::back_inserter(sink_)); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } else if (length <= 0xffffffff) { binary::native_to_big(static_cast(0x5a), std::back_inserter(sink_)); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } else if (uint64_t(length) <= (std::numeric_limits::max)()) { binary::native_to_big(static_cast(0x5b), std::back_inserter(sink_)); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } for (auto c : data) { sink_.push_back(c); } } void write_decimal_value(const string_view_type& sv, const ser_context& context, std::error_code& ec) { decimal_parse_state state = decimal_parse_state::start; std::basic_string s; std::basic_string exponent; int64_t scale = 0; for (auto c : sv) { switch (state) { case decimal_parse_state::start: { switch (c) { case '-': case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': s.push_back(c); state = decimal_parse_state::integer; break; default: { ec = cbor_errc::invalid_decimal_fraction; return; } } break; } case decimal_parse_state::integer: { switch (c) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': s.push_back(c); break; case 'e': case 'E': state = decimal_parse_state::exp1; break; case '.': state = decimal_parse_state::fraction1; break; default: { ec = cbor_errc::invalid_decimal_fraction; return; } } break; } case decimal_parse_state::exp1: { switch (c) { case '+': state = decimal_parse_state::exp2; break; case '-': case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': exponent.push_back(c); state = decimal_parse_state::exp2; break; default: { ec = cbor_errc::invalid_decimal_fraction; return; } } break; } case decimal_parse_state::exp2: { switch (c) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': exponent.push_back(c); break; default: { ec = cbor_errc::invalid_decimal_fraction; return; } } break; } case decimal_parse_state::fraction1: { switch (c) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': s.push_back(c); --scale; break; default: { ec = cbor_errc::invalid_decimal_fraction; return; } } break; } } } write_tag(4); visit_begin_array((std::size_t)2, semantic_tag::none, context, ec); if (JSONCONS_UNLIKELY(ec)) {return;} if (exponent.length() > 0) { int64_t val{}; auto r = jsoncons::detail::to_integer(exponent.data(), exponent.length(), val); if (!r) { ec = r.error_code(); return; } scale += val; } visit_int64(scale, semantic_tag::none, context, ec); if (JSONCONS_UNLIKELY(ec)) {return;} int64_t val{ 0 }; auto r = jsoncons::detail::to_integer(s.data(),s.length(), val); if (r) { visit_int64(val, semantic_tag::none, context, ec); if (JSONCONS_UNLIKELY(ec)) {return;} } else if (r.error_code() == jsoncons::detail::to_integer_errc::overflow) { bigint n = bigint::from_string(s.data(), s.length()); write_bignum(n); end_value(); } else { ec = r.error_code(); return; } visit_end_array(context, ec); } void write_hexfloat_value(const string_view_type& sv, const ser_context& context, std::error_code& ec) { hexfloat_parse_state state = hexfloat_parse_state::start; std::basic_string s; std::basic_string exponent; int64_t scale = 0; for (auto c : sv) { switch (state) { case hexfloat_parse_state::start: { switch (c) { case '-': s.push_back(c); state = hexfloat_parse_state::expect_0; break; case '0': state = hexfloat_parse_state::expect_x; break; default: { ec = cbor_errc::invalid_bigfloat; return; } } break; } case hexfloat_parse_state::expect_0: { switch (c) { case '0': state = hexfloat_parse_state::expect_x; break; default: { ec = cbor_errc::invalid_bigfloat; return; } } break; } case hexfloat_parse_state::expect_x: { switch (c) { case 'x': case 'X': state = hexfloat_parse_state::integer; break; default: { ec = cbor_errc::invalid_bigfloat; return; } } break; } case hexfloat_parse_state::integer: { switch (c) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'A':case 'B':case 'C':case 'D':case 'E':case 'F': s.push_back(c); break; case 'p': case 'P': state = hexfloat_parse_state::exp1; break; case '.': state = hexfloat_parse_state::fraction1; break; default: { ec = cbor_errc::invalid_bigfloat; return; } } break; } case hexfloat_parse_state::exp1: { switch (c) { case '+': state = hexfloat_parse_state::exp2; break; case '-': case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'A':case 'B':case 'C':case 'D':case 'E':case 'F': exponent.push_back(c); state = hexfloat_parse_state::exp2; break; default: { ec = cbor_errc::invalid_bigfloat; return; } } break; } case hexfloat_parse_state::exp2: { switch (c) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'A':case 'B':case 'C':case 'D':case 'E':case 'F': exponent.push_back(c); break; default: { ec = cbor_errc::invalid_bigfloat; return; } } break; } case hexfloat_parse_state::fraction1: { switch (c) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'A':case 'B':case 'C':case 'D':case 'E':case 'F': s.push_back(c); scale -= 4; break; default: { ec = cbor_errc::invalid_bigfloat; return; } } break; } } } write_tag(5); visit_begin_array((std::size_t)2, semantic_tag::none, context, ec); if (JSONCONS_UNLIKELY(ec)) return; if (exponent.length() > 0) { int64_t val{ 0 }; auto r = jsoncons::detail::hex_to_integer(exponent.data(), exponent.length(), val); if (!r) { ec = r.error_code(); return; } scale += val; } visit_int64(scale, semantic_tag::none, context, ec); if (JSONCONS_UNLIKELY(ec)) return; int64_t val{ 0 }; auto r = jsoncons::detail::hex_to_integer(s.data(),s.length(), val); if (r) { visit_int64(val, semantic_tag::none, context, ec); if (JSONCONS_UNLIKELY(ec)) return; } else if (r.error_code() == jsoncons::detail::to_integer_errc::overflow) { bigint n = bigint::from_string_radix(s.data(), s.length(), 16); write_bignum(n); end_value(); } else { ec = r.error_code(); return; } visit_end_array(context, ec); } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& sv, semantic_tag tag, const ser_context& context, std::error_code& ec) override { switch (tag) { case semantic_tag::bigint: { bigint n = bigint::from_string(sv.data(), sv.length()); write_bignum(n); end_value(); break; } case semantic_tag::bigdec: { write_decimal_value(sv, context, ec); break; } case semantic_tag::bigfloat: { write_hexfloat_value(sv, context, ec); break; } case semantic_tag::datetime: { write_tag(0); write_string(sv); end_value(); break; } case semantic_tag::uri: { write_tag(32); write_string(sv); end_value(); break; } case semantic_tag::base64url: { write_tag(33); write_string(sv); end_value(); break; } case semantic_tag::base64: { write_tag(34); write_string(sv); end_value(); break; } default: { write_string(sv); end_value(); break; } } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& b, semantic_tag tag, const ser_context&, std::error_code&) override { byte_string_chars_format encoding_hint; switch (tag) { case semantic_tag::base16: encoding_hint = byte_string_chars_format::base16; break; case semantic_tag::base64: encoding_hint = byte_string_chars_format::base64; break; case semantic_tag::base64url: encoding_hint = byte_string_chars_format::base64url; break; default: encoding_hint = byte_string_chars_format::none; break; } switch (encoding_hint) { case byte_string_chars_format::base64url: write_tag(21); break; case byte_string_chars_format::base64: write_tag(22); break; case byte_string_chars_format::base16: write_tag(23); break; default: break; } if (options_.pack_strings() && b.size() >= jsoncons::cbor::detail::min_length_for_stringref(next_stringref_)) { byte_string_type bs(b.data(), b.size(), alloc_); auto it = bytestringref_map_.find(bs); if (it == bytestringref_map_.end()) { bytestringref_map_.emplace(std::make_pair(bs, next_stringref_++)); write_byte_string(bs); } else { write_tag(25); write_uint64_value((*it).second); } } else { write_byte_string(b); } end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& b, uint64_t ext_tag, const ser_context&, std::error_code&) override { if (options_.pack_strings() && b.size() >= jsoncons::cbor::detail::min_length_for_stringref(next_stringref_)) { byte_string_type bs(b.data(), b.size(), alloc_); auto it = bytestringref_map_.find(bs); if (it == bytestringref_map_.end()) { bytestringref_map_.emplace(std::make_pair(bs, next_stringref_++)); write_tag(ext_tag); write_byte_string(bs); } else { write_tag(25); write_uint64_value((*it).second); } } else { write_tag(ext_tag); write_byte_string(b); } end_value(); JSONCONS_VISITOR_RETURN; } void write_byte_string(const byte_string_view& b) { if (b.size() <= 0x17) { // fixstr stores a byte array whose length is upto 31 bytes binary::native_to_big(static_cast(0x40 + b.size()), std::back_inserter(sink_)); } else if (b.size() <= 0xff) { binary::native_to_big(static_cast(0x58), std::back_inserter(sink_)); binary::native_to_big(static_cast(b.size()), std::back_inserter(sink_)); } else if (b.size() <= 0xffff) { binary::native_to_big(static_cast(0x59), std::back_inserter(sink_)); binary::native_to_big(static_cast(b.size()), std::back_inserter(sink_)); } else if (b.size() <= 0xffffffff) { binary::native_to_big(static_cast(0x5a), std::back_inserter(sink_)); binary::native_to_big(static_cast(b.size()), std::back_inserter(sink_)); } else // if (b.size() <= 0xffffffffffffffff) { binary::native_to_big(static_cast(0x5b), std::back_inserter(sink_)); binary::native_to_big(static_cast(b.size()), std::back_inserter(sink_)); } for (auto c : b) { sink_.push_back(c); } } JSONCONS_VISITOR_RETURN_TYPE visit_double(double val, semantic_tag tag, const ser_context&, std::error_code&) override { switch (tag) { case semantic_tag::epoch_second: write_tag(1); break; case semantic_tag::epoch_milli: write_tag(1); if (val != 0) { val /= millis_in_second; } break; case semantic_tag::epoch_nano: write_tag(1); if (val != 0) { val /= nanos_in_second; } break; default: break; } float valf = (float)val; if ((double)valf == val) { binary::native_to_big(static_cast(0xfa), std::back_inserter(sink_)); binary::native_to_big(valf, std::back_inserter(sink_)); } else { binary::native_to_big(static_cast(0xfb), std::back_inserter(sink_)); binary::native_to_big(val, std::back_inserter(sink_)); } // write double end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { switch (tag) { case semantic_tag::epoch_milli: case semantic_tag::epoch_nano: visit_double(static_cast(value), tag, context, ec); break; case semantic_tag::epoch_second: write_tag(1); break; default: break; } write_int64_value(value); end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code& ec) override { switch (tag) { case semantic_tag::epoch_milli: case semantic_tag::epoch_nano: visit_double(static_cast(value), tag, context, ec); break; case semantic_tag::epoch_second: write_tag(1); break; default: break; } write_uint64_value(value); end_value(); JSONCONS_VISITOR_RETURN; } void write_tag(uint64_t value) { if (value <= 0x17) { sink_.push_back(0xc0 | static_cast(value)); } else if (value <=(std::numeric_limits::max)()) { sink_.push_back(0xd8); sink_.push_back(static_cast(value)); } else if (value <=(std::numeric_limits::max)()) { sink_.push_back(0xd9); binary::native_to_big(static_cast(value), std::back_inserter(sink_)); } else if (value <=(std::numeric_limits::max)()) { sink_.push_back(0xda); binary::native_to_big(static_cast(value), std::back_inserter(sink_)); } else { sink_.push_back(0xdb); binary::native_to_big(static_cast(value), std::back_inserter(sink_)); } } void write_uint64_value(uint64_t value) { if (value <= 0x17) { sink_.push_back(static_cast(value)); } else if (value <=(std::numeric_limits::max)()) { sink_.push_back(static_cast(0x18)); sink_.push_back(static_cast(value)); } else if (value <=(std::numeric_limits::max)()) { sink_.push_back(static_cast(0x19)); binary::native_to_big(static_cast(value), std::back_inserter(sink_)); } else if (value <=(std::numeric_limits::max)()) { sink_.push_back(static_cast(0x1a)); binary::native_to_big(static_cast(value), std::back_inserter(sink_)); } else if (value <=(std::numeric_limits::max)()) { sink_.push_back(static_cast(0x1b)); binary::native_to_big(static_cast(value), std::back_inserter(sink_)); } } void write_int64_value(int64_t value) { if (value >= 0) { if (value <= 0x17) { binary::native_to_big(static_cast(value), std::back_inserter(sink_)); } else if (value <= (std::numeric_limits::max)()) { binary::native_to_big(static_cast(0x18), std::back_inserter(sink_)); binary::native_to_big(static_cast(value), std::back_inserter(sink_)); } else if (value <= (std::numeric_limits::max)()) { binary::native_to_big(static_cast(0x19), std::back_inserter(sink_)); binary::native_to_big(static_cast(value), std::back_inserter(sink_)); } else if (value <= (std::numeric_limits::max)()) { binary::native_to_big(static_cast(0x1a), std::back_inserter(sink_)); binary::native_to_big(static_cast(value), std::back_inserter(sink_)); } else if (value <= (std::numeric_limits::max)()) { binary::native_to_big(static_cast(0x1b), std::back_inserter(sink_)); binary::native_to_big(static_cast(value), std::back_inserter(sink_)); } } else { const auto posnum = -1 - value; if (value >= -24) { binary::native_to_big(static_cast(0x20 + posnum), std::back_inserter(sink_)); } else if (posnum <= (std::numeric_limits::max)()) { binary::native_to_big(static_cast(0x38), std::back_inserter(sink_)); binary::native_to_big(static_cast(posnum), std::back_inserter(sink_)); } else if (posnum <= (std::numeric_limits::max)()) { binary::native_to_big(static_cast(0x39), std::back_inserter(sink_)); binary::native_to_big(static_cast(posnum), std::back_inserter(sink_)); } else if (posnum <= (std::numeric_limits::max)()) { binary::native_to_big(static_cast(0x3a), std::back_inserter(sink_)); binary::native_to_big(static_cast(posnum), std::back_inserter(sink_)); } else if (posnum <= (std::numeric_limits::max)()) { binary::native_to_big(static_cast(0x3b), std::back_inserter(sink_)); binary::native_to_big(static_cast(posnum), std::back_inserter(sink_)); } } } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool value, semantic_tag, const ser_context&, std::error_code&) override { if (value) { sink_.push_back(0xf5); } else { sink_.push_back(0xf4); } end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& v, semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (options_.use_typed_arrays()) { switch (tag) { case semantic_tag::clamped: write_tag(0x44); break; default: write_tag(0x40); break; } write_byte_string(byte_string_view(v)); JSONCONS_VISITOR_RETURN; } else { this->begin_array(v.size(), semantic_tag::none, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto p = v.begin(); p != v.end(); ++p) { this->uint64_value(*p, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } this->end_array(context, ec); JSONCONS_VISITOR_RETURN; } } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (options_.use_typed_arrays()) { write_typed_array_tag(std::integral_constant(), uint16_t(), tag); std::vector v(data.size()*sizeof(uint16_t)); std::memcpy(v.data(),data.data(),data.size()*sizeof(uint16_t)); write_byte_string(byte_string_view(v)); JSONCONS_VISITOR_RETURN; } else { this->begin_array(data.size(), semantic_tag::none, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto p = data.begin(); p != data.end(); ++p) { this->uint64_value(*p, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } this->end_array(context, ec); JSONCONS_VISITOR_RETURN; } } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (options_.use_typed_arrays()) { write_typed_array_tag(std::integral_constant(), uint32_t(), tag); std::vector v(data.size()*sizeof(uint32_t)); std::memcpy(v.data(), data.data(), data.size()*sizeof(uint32_t)); write_byte_string(byte_string_view(v)); JSONCONS_VISITOR_RETURN; } else { this->begin_array(data.size(), semantic_tag::none, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto p = data.begin(); p != data.end(); ++p) { this->uint64_value(*p, semantic_tag::none, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } this->end_array(context, ec); JSONCONS_VISITOR_RETURN; } } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (options_.use_typed_arrays()) { write_typed_array_tag(std::integral_constant(), uint64_t(), tag); std::vector v(data.size()*sizeof(uint64_t)); std::memcpy(v.data(), data.data(), data.size()*sizeof(uint64_t)); write_byte_string(byte_string_view(v)); JSONCONS_VISITOR_RETURN; } else { this->begin_array(data.size(), semantic_tag::none, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto p = data.begin(); p != data.end(); ++p) { this->uint64_value(*p,semantic_tag::none,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } this->end_array(context, ec); JSONCONS_VISITOR_RETURN; } } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag, const ser_context& context, std::error_code& ec) override { if (options_.use_typed_arrays()) { write_tag(0x48); std::vector v(data.size()*sizeof(int8_t)); std::memcpy(v.data(), data.data(), data.size()*sizeof(int8_t)); write_byte_string(byte_string_view(v)); JSONCONS_VISITOR_RETURN; } else { this->begin_array(data.size(), semantic_tag::none,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto p = data.begin(); p != data.end(); ++p) { this->int64_value(*p,semantic_tag::none,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } this->end_array(context, ec); JSONCONS_VISITOR_RETURN; } } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (options_.use_typed_arrays()) { write_typed_array_tag(std::integral_constant(), int16_t(), tag); std::vector v(data.size()*sizeof(int16_t)); std::memcpy(v.data(), data.data(), data.size()*sizeof(int16_t)); write_byte_string(byte_string_view(v)); JSONCONS_VISITOR_RETURN; } else { this->begin_array(data.size(), semantic_tag::none,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto p = data.begin(); p != data.end(); ++p) { this->int64_value(*p,semantic_tag::none,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } this->end_array(context, ec); JSONCONS_VISITOR_RETURN; } } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (options_.use_typed_arrays()) { write_typed_array_tag(std::integral_constant(), int32_t(), tag); std::vector v(data.size()*sizeof(int32_t)); std::memcpy(v.data(), data.data(), data.size()*sizeof(int32_t)); write_byte_string(byte_string_view(v)); JSONCONS_VISITOR_RETURN; } else { this->begin_array(data.size(), semantic_tag::none,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto p = data.begin(); p != data.end(); ++p) { this->int64_value(*p,semantic_tag::none,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } this->end_array(context, ec); JSONCONS_VISITOR_RETURN; } } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (options_.use_typed_arrays()) { write_typed_array_tag(std::integral_constant(), int64_t(), tag); std::vector v(data.size()*sizeof(int64_t)); std::memcpy(v.data(), data.data(), data.size()*sizeof(int64_t)); write_byte_string(byte_string_view(v)); JSONCONS_VISITOR_RETURN; } else { this->begin_array(data.size(), semantic_tag::none,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto p = data.begin(); p != data.end(); ++p) { this->int64_value(*p,semantic_tag::none,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } this->end_array(context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} JSONCONS_VISITOR_RETURN; } } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(half_arg_t, const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (options_.use_typed_arrays()) { write_typed_array_tag(std::integral_constant(), half_arg, tag); std::vector v(data.size()*sizeof(uint16_t)); std::memcpy(v.data(),data.data(),data.size()*sizeof(uint16_t)); write_byte_string(byte_string_view(v)); JSONCONS_VISITOR_RETURN; } else { this->begin_array(data.size(), semantic_tag::none, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto p = data.begin(); p != data.end(); ++p) { this->half_value(*p, tag, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } this->end_array(context, ec); JSONCONS_VISITOR_RETURN; } } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (options_.use_typed_arrays()) { write_typed_array_tag(std::integral_constant(), float(), tag); std::vector v(data.size()*sizeof(float)); std::memcpy(v.data(), data.data(), data.size()*sizeof(float)); write_byte_string(byte_string_view(v)); JSONCONS_VISITOR_RETURN; } else { this->begin_array(data.size(), semantic_tag::none,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (const auto* p = data.begin(); p != data.end(); ++p) { this->double_value(*p,semantic_tag::none,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } this->end_array(context, ec); JSONCONS_VISITOR_RETURN; } } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { if (options_.use_typed_arrays()) { write_typed_array_tag(std::integral_constant(), double(), tag); std::vector v(data.size()*sizeof(double)); std::memcpy(v.data(), data.data(), data.size()*sizeof(double)); write_byte_string(byte_string_view(v)); JSONCONS_VISITOR_RETURN; } this->begin_array(data.size(), semantic_tag::none,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto p = data.begin(); p != data.end(); ++p) { this->double_value(*p,semantic_tag::none,context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } this->end_array(context, ec); JSONCONS_VISITOR_RETURN; } /* JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const jsoncons::span&, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } */ JSONCONS_VISITOR_RETURN_TYPE visit_begin_multi_dim(const jsoncons::span& shape, semantic_tag tag, const ser_context& context, std::error_code& ec) override { switch (tag) { case semantic_tag::multi_dim_column_major: write_tag(1040); break; default: write_tag(40); break; } visit_begin_array(2, semantic_tag::none, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} visit_begin_array(shape.size(), semantic_tag::none, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} for (auto it = shape.begin(); it != shape.end(); ++it) { visit_uint64(*it, semantic_tag::none, context, ec); if (JSONCONS_UNLIKELY(ec)) {JSONCONS_VISITOR_RETURN;} } visit_end_array(context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_multi_dim(const ser_context& context, std::error_code& ec) override { visit_end_array(context, ec); JSONCONS_VISITOR_RETURN; } void write_typed_array_tag(std::true_type, uint16_t, semantic_tag) { write_tag(0x41); // big endian } void write_typed_array_tag(std::false_type, uint16_t, semantic_tag) { write_tag(0x45); } void write_typed_array_tag(std::true_type, uint32_t, semantic_tag) { write_tag(0x42); // big endian } void write_typed_array_tag(std::false_type, uint32_t, semantic_tag) { write_tag(0x46); // little endian } void write_typed_array_tag(std::true_type, uint64_t, semantic_tag) { write_tag(0x43); // big endian } void write_typed_array_tag(std::false_type, uint64_t, semantic_tag) { write_tag(0x47); // little endian } void write_typed_array_tag(std::true_type, int16_t, semantic_tag) { write_tag(0x49); // big endian } void write_typed_array_tag(std::false_type, int16_t, semantic_tag) { write_tag(0x4d); // little endian } void write_typed_array_tag(std::true_type, int32_t, semantic_tag) { write_tag(0x4a); // big endian } void write_typed_array_tag(std::false_type, int32_t, semantic_tag) { write_tag(0x4e); // little endian } void write_typed_array_tag(std::true_type, int64_t, semantic_tag) { write_tag(0x4b); // big endian } void write_typed_array_tag(std::false_type, int64_t, semantic_tag) { write_tag(0x4f); // little endian } void write_typed_array_tag(std::true_type, half_arg_t, semantic_tag) { write_tag(0x50); } void write_typed_array_tag(std::false_type, half_arg_t, semantic_tag) { write_tag(0x54); } void write_typed_array_tag(std::true_type, float, semantic_tag) { write_tag(0x51); // big endian } void write_typed_array_tag(std::false_type, float, semantic_tag) { write_tag(0x55); // little endian } void write_typed_array_tag(std::true_type, double, semantic_tag) { write_tag(0x52); // big endian } void write_typed_array_tag(std::false_type, double, semantic_tag) { write_tag(0x56); // little endian } void end_value() { if (!stack_.empty()) { ++stack_.back().index_; } } }; using cbor_stream_encoder = basic_cbor_encoder; using cbor_bytes_encoder = basic_cbor_encoder>>; } // namespace cbor } // namespace jsoncons #endif jsoncons-1.3.2/include/jsoncons_ext/cbor/cbor_error.hpp000066400000000000000000000056431477700171100233210ustar00rootroot00000000000000/// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_CBOR_CBOR_ERROR_HPP #define JSONCONS_EXT_CBOR_CBOR_ERROR_HPP #include #include #include #include namespace jsoncons { namespace cbor { enum class cbor_errc { success = 0, unexpected_eof, source_error, invalid_decimal_fraction, invalid_bigfloat, invalid_utf8_text_string, too_many_items, too_few_items, number_too_large, stringref_too_large, max_nesting_depth_exceeded, unknown_type, illegal_chunked_string }; class cbor_error_category_impl : public std::error_category { public: const char* name() const noexcept override { return "jsoncons/cbor"; } std::string message(int ev) const override { switch (static_cast(ev)) { case cbor_errc::unexpected_eof: return "Unexpected end of file"; case cbor_errc::source_error: return "Source error"; case cbor_errc::invalid_decimal_fraction: return "Invalid decimal fraction"; case cbor_errc::invalid_bigfloat: return "Invalid bigfloat"; case cbor_errc::invalid_utf8_text_string: return "Illegal UTF-8 encoding in text string"; case cbor_errc::too_many_items: return "Too many items were added to a CBOR map or array of known length"; case cbor_errc::too_few_items: return "Too few items were added to a CBOR map or array of known length"; case cbor_errc::number_too_large: return "Number exceeds implementation limits"; case cbor_errc::stringref_too_large: return "stringref exceeds stringref map size"; case cbor_errc::max_nesting_depth_exceeded: return "Data item nesting exceeds limit in options"; case cbor_errc::unknown_type: return "An unknown type was found in the stream"; case cbor_errc::illegal_chunked_string: return "An illegal type was found while parsing an indefinite length string"; default: return "Unknown CBOR parser error"; } } }; inline const std::error_category& cbor_error_category() { static cbor_error_category_impl instance; return instance; } inline std::error_code make_error_code(cbor_errc e) { return std::error_code(static_cast(e),cbor_error_category()); } } // namespace cbor } // namespace jsoncons namespace std { template<> struct is_error_code_enum : public true_type { }; } // namespace std #endif jsoncons-1.3.2/include/jsoncons_ext/cbor/cbor_event_reader.hpp000066400000000000000000000174471477700171100246400ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_CBOR_EVENT_READER_HPP #define JSONCONS_EXT_CBOR_EVENT_READER_HPP #include #include #include #include // std::allocator #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace cbor { template > class cbor_event_reader : public basic_staj_event_reader, private virtual ser_context { public: using source_type = Source; using char_type = char; using allocator_type = Allocator; private: basic_cbor_parser parser_; basic_item_event_receiver cursor_visitor_; bool eof_{false}; public: using string_view_type = string_view; // Noncopyable and nonmoveable cbor_event_reader(const cbor_event_reader&) = delete; cbor_event_reader(cbor_event_reader&&) = delete; template cbor_event_reader(Sourceable&& source, const cbor_decode_options& options = cbor_decode_options(), const Allocator& alloc = Allocator()) : parser_(std::forward(source), options, alloc) { parser_.cursor_mode(true); if (!done()) { next(); } } // Constructors that set parse error codes template cbor_event_reader(Sourceable&& source, std::error_code& ec) : cbor_event_reader(std::allocator_arg, Allocator(), std::forward(source), cbor_decode_options(), ec) { } template cbor_event_reader(Sourceable&& source, const cbor_decode_options& options, std::error_code& ec) : cbor_event_reader(std::allocator_arg, Allocator(), std::forward(source), options, ec) { } template cbor_event_reader(std::allocator_arg_t, const Allocator& alloc, Sourceable&& source, const cbor_decode_options& options, std::error_code& ec) : parser_(std::forward(source), options, alloc), eof_(false) { parser_.cursor_mode(true); if (!done()) { next(ec); } } ~cbor_event_reader() = default; cbor_event_reader& operator=(const cbor_event_reader&) = delete; cbor_event_reader& operator=(cbor_event_reader&&) = delete; void reset() { parser_.reset(); cursor_visitor_.reset(); eof_ = false; if (!done()) { next(); } } template void reset(Sourceable&& source) { parser_.reset(std::forward(source)); cursor_visitor_.reset(); eof_ = false; if (!done()) { next(); } } void reset(std::error_code& ec) { parser_.reset(); cursor_visitor_.reset(); eof_ = false; if (!done()) { next(ec); } } template void reset(Sourceable&& source, std::error_code& ec) { parser_.reset(std::forward(source)); cursor_visitor_.reset(); eof_ = false; if (!done()) { next(ec); } } bool done() const override { return parser_.done(); } bool is_typed_array() const { return cursor_visitor_.is_typed_array(); } const basic_staj_event& current() const override { return cursor_visitor_.event(); } void read_to(basic_item_event_visitor& visitor) override { std::error_code ec; read_to(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); } } void read_to(basic_item_event_visitor& visitor, std::error_code& ec) override { if (is_typed_array()) { cursor_visitor_.dump(visitor, *this, ec); } else if (is_begin_container(current().event_type())) { parser_.cursor_mode(false); parser_.mark_level(parser_.level()); cursor_visitor_.dump(visitor, *this, ec); if (JSONCONS_UNLIKELY(ec)) { return; } read_next(visitor, ec); parser_.cursor_mode(true); parser_.mark_level(0); if (current().event_type() == staj_event_type::begin_object) { cursor_visitor_.end_object(*this); } else { cursor_visitor_.end_array(*this); } } else { cursor_visitor_.dump(visitor, *this, ec); } } void next() override { std::error_code ec; next(ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); } } void next(std::error_code& ec) override { read_next(ec); } const ser_context& context() const override { return *this; } bool eof() const { return eof_; } std::size_t line() const override { return parser_.line(); } std::size_t column() const override { return parser_.column(); } friend staj2_filter_view operator|(cbor_event_reader& cursor, std::function pred) { return staj2_filter_view(cursor, pred); } private: void read_next(std::error_code& ec) { if (cursor_visitor_.in_available()) { cursor_visitor_.send_available(ec); } else { parser_.restart(); while (!parser_.stopped()) { parser_.parse(cursor_visitor_, ec); if (JSONCONS_UNLIKELY(ec)) {return;} } } } void read_next(basic_item_event_visitor& visitor, std::error_code& ec) { parser_.restart(); while (!parser_.stopped()) { parser_.parse(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { return; } } } }; } // namespace cbor } // namespace jsoncons #endif jsoncons-1.3.2/include/jsoncons_ext/cbor/cbor_options.hpp000066400000000000000000000043331477700171100236560ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_CBOR_CBOR_OPTIONS_HPP #define JSONCONS_EXT_CBOR_CBOR_OPTIONS_HPP #include #include namespace jsoncons { namespace cbor { class cbor_options; class cbor_options_common { friend class cbor_options; int max_nesting_depth_; protected: virtual ~cbor_options_common() = default; cbor_options_common() : max_nesting_depth_(1024) { } cbor_options_common(const cbor_options_common&) = default; cbor_options_common& operator=(const cbor_options_common&) = default; cbor_options_common(cbor_options_common&&) = default; cbor_options_common& operator=(cbor_options_common&&) = default; public: int max_nesting_depth() const { return max_nesting_depth_; } }; class cbor_decode_options : public virtual cbor_options_common { friend class cbor_options; public: cbor_decode_options() { } }; class cbor_encode_options : public virtual cbor_options_common { friend class cbor_options; bool use_stringref_; bool use_typed_arrays_; public: cbor_encode_options() : use_stringref_(false), use_typed_arrays_(false) { } bool pack_strings() const { return use_stringref_; } bool use_typed_arrays() const { return use_typed_arrays_; } }; class cbor_options final : public cbor_decode_options, public cbor_encode_options { public: using cbor_options_common::max_nesting_depth; using cbor_encode_options::pack_strings; using cbor_encode_options::use_typed_arrays; cbor_options& max_nesting_depth(int value) { this->max_nesting_depth_ = value; return *this; } cbor_options& pack_strings(bool value) { this->use_stringref_ = value; return *this; } cbor_options& use_typed_arrays(bool value) { this->use_typed_arrays_ = value; return *this; } }; } // namespace cbor } // namespace jsoncons #endif jsoncons-1.3.2/include/jsoncons_ext/cbor/cbor_parser.hpp000066400000000000000000002127541477700171100234670ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_CBOR_CBOR_PARSER_HPP #define JSONCONS_EXT_CBOR_CBOR_PARSER_HPP #include // std::bitset #include #include #include #include #include #include // std::move #include #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace cbor { enum class parse_mode {root,accept,array,indefinite_array,map_key,map_value,indefinite_map_key,indefinite_map_value,multi_dim}; struct parse_state { parse_mode mode; std::size_t length; bool pop_stringref_map_stack; std::size_t index{0}; parse_state(parse_mode mode, std::size_t length, bool pop_stringref_map_stack = false) noexcept : mode(mode), length(length), pop_stringref_map_stack(pop_stringref_map_stack) { } parse_state(const parse_state&) = default; parse_state(parse_state&&) = default; parse_state& operator=(const parse_state&) = default; parse_state& operator=(parse_state&&) = default; ~parse_state() = default; }; template > class basic_cbor_parser : public ser_context { using char_type = char; using char_traits_type = std::char_traits; using allocator_type = Allocator; using char_allocator_type = typename std::allocator_traits:: template rebind_alloc; using byte_allocator_type = typename std::allocator_traits:: template rebind_alloc; using tag_allocator_type = typename std::allocator_traits:: template rebind_alloc; using parse_state_allocator_type = typename std::allocator_traits:: template rebind_alloc; using string_type = std::basic_string; using byte_string_type = std::vector; struct mapped_string { using allocator_type = Allocator; jsoncons::cbor::detail::cbor_major_type type; string_type str; byte_string_type bytes; mapped_string(const string_type& str, const allocator_type& alloc = allocator_type()) : type(jsoncons::cbor::detail::cbor_major_type::text_string), str(str.c_str(), str.size(), alloc), bytes(alloc) { } mapped_string(string_type&& str, const allocator_type& alloc = allocator_type()) : type(jsoncons::cbor::detail::cbor_major_type::text_string), str(std::move(str), alloc), bytes(alloc) { } mapped_string(const byte_string_type& bytes, const allocator_type& alloc = allocator_type()) : type(jsoncons::cbor::detail::cbor_major_type::byte_string), str(alloc), bytes(bytes,alloc) { } mapped_string(byte_string_type&& bytes, const allocator_type& alloc = allocator_type()) : type(jsoncons::cbor::detail::cbor_major_type::byte_string), str(alloc), bytes(std::move(bytes),alloc) { } mapped_string(const mapped_string&) = default; mapped_string(mapped_string&&) = default; mapped_string& operator=(const mapped_string&) = default; mapped_string& operator=(mapped_string&&) = default; mapped_string(const mapped_string& other, const allocator_type& alloc) : type(other.type), str(other.str,alloc), bytes(other.bytes,alloc) { } mapped_string(mapped_string&& other, const allocator_type& alloc) noexcept : type(other.type), str(std::move(other.str), alloc), bytes(std::move(other.bytes), alloc) { } ~mapped_string() = default; }; using mapped_string_allocator_type = typename std::allocator_traits:: template rebind_alloc; using stringref_map = std::vector; using stringref_map_allocator_type = typename std::allocator_traits:: template rebind_alloc; enum {stringref_tag, // 25 stringref_namespace_tag, // 256 item_tag, num_of_tags}; bool more_{true}; bool done_{false}; bool cursor_mode_{false}; int mark_level_{0}; uint64_t raw_tag_{0}; int nesting_depth_{0}; std::bitset other_tags_; allocator_type alloc_; Source source_; cbor_decode_options options_; string_type text_buffer_; byte_string_type bytes_buffer_; std::vector state_stack_; byte_string_type typed_array_; std::vector shape_; std::vector stringref_map_stack_; struct read_byte_string_from_buffer { byte_string_view bytes; read_byte_string_from_buffer(const byte_string_view& b) : bytes(b) { } template void operator()(Container& c, std::error_code&) { c.clear(); c.reserve(bytes.size()); for (auto b : bytes) { c.push_back(b); } } }; struct read_byte_string_from_source { basic_cbor_parser* source; read_byte_string_from_source(basic_cbor_parser* source) : source(source) { } template void operator()(Container& cont, std::error_code& ec) { source->read_byte_string(cont,ec); } }; public: template basic_cbor_parser(Sourceable&& source, const cbor_decode_options& options = cbor_decode_options(), const Allocator& alloc = Allocator()) : alloc_(alloc), source_(std::forward(source)), options_(options), text_buffer_(alloc), bytes_buffer_(alloc), state_stack_(alloc), typed_array_(alloc), stringref_map_stack_(alloc) { state_stack_.emplace_back(parse_mode::root,0); } basic_cbor_parser(const basic_cbor_parser&) = delete; basic_cbor_parser(basic_cbor_parser&&) = delete; basic_cbor_parser& operator=(const basic_cbor_parser&) = delete; basic_cbor_parser& operator=(basic_cbor_parser&&) = delete; ~basic_cbor_parser() = default; void restart() { more_ = true; } void reset() { more_ = true; done_ = false; text_buffer_.clear(); bytes_buffer_.clear(); raw_tag_ = 0; state_stack_.clear(); state_stack_.emplace_back(parse_mode::root,0); typed_array_.clear(); stringref_map_stack_.clear(); nesting_depth_ = 0; } template void reset(Sourceable&& source) { source_ = std::forward(source); reset(); } void cursor_mode(bool value) { cursor_mode_ = value; } int level() const { return static_cast(state_stack_.size()); } int mark_level() const { return mark_level_; } void mark_level(int value) { mark_level_ = value; } bool done() const { return done_; } bool stopped() const { return !more_; } std::size_t line() const override { return 0; } std::size_t column() const override { return source_.position(); } uint64_t raw_tag() const { return raw_tag_; } void parse(item_event_visitor& visitor, std::error_code& ec) { while (!done_ && more_) { switch (state_stack_.back().mode) { case parse_mode::multi_dim: { if (state_stack_.back().index == 0) { ++state_stack_.back().index; read_item(visitor, ec); } else { produce_end_multi_dim(visitor, ec); } break; } case parse_mode::array: { if (state_stack_.back().index < state_stack_.back().length) { ++state_stack_.back().index; read_item(visitor, ec); } else { end_array(visitor, ec); } break; } case parse_mode::indefinite_array: { auto c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = cbor_errc::unexpected_eof; more_ = false; return; } if (c.value == 0xff) { source_.ignore(1); end_array(visitor, ec); } else { read_item(visitor, ec); } break; } case parse_mode::map_key: { if (state_stack_.back().index < state_stack_.back().length) { ++state_stack_.back().index; state_stack_.back().mode = parse_mode::map_value; read_item(visitor, ec); } else { end_object(visitor, ec); } break; } case parse_mode::map_value: { state_stack_.back().mode = parse_mode::map_key; read_item(visitor, ec); break; } case parse_mode::indefinite_map_key: { auto c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = cbor_errc::unexpected_eof; more_ = false; return; } if (c.value == 0xff) { source_.ignore(1); end_object(visitor, ec); } else { state_stack_.back().mode = parse_mode::indefinite_map_value; read_item(visitor, ec); } break; } case parse_mode::indefinite_map_value: { state_stack_.back().mode = parse_mode::indefinite_map_key; read_item(visitor, ec); break; } case parse_mode::root: { state_stack_.back().mode = parse_mode::accept; read_item(visitor, ec); break; } case parse_mode::accept: { JSONCONS_ASSERT(state_stack_.size() == 1); state_stack_.clear(); more_ = false; done_ = true; visitor.flush(); break; } } } } private: void read_item(item_event_visitor& visitor, std::error_code& ec) { read_tags(ec); if (JSONCONS_UNLIKELY(ec)) { return; } auto c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = cbor_errc::unexpected_eof; more_ = false; return; } jsoncons::cbor::detail::cbor_major_type major_type = get_major_type(c.value); uint8_t info = get_additional_information_value(c.value); switch (major_type) { case jsoncons::cbor::detail::cbor_major_type::unsigned_integer: { uint64_t val = get_uint64_value(ec); if (JSONCONS_UNLIKELY(ec)) { return; } if (!stringref_map_stack_.empty() && other_tags_[stringref_tag]) { other_tags_[stringref_tag] = false; if (val >= stringref_map_stack_.back().size()) { ec = cbor_errc::stringref_too_large; more_ = false; return; } auto index = static_cast(val); if (index != val) { ec = cbor_errc::number_too_large; more_ = false; return; } auto& str = stringref_map_stack_.back().at(index); switch (str.type) { case jsoncons::cbor::detail::cbor_major_type::text_string: { handle_string(visitor, jsoncons::basic_string_view(str.str.data(),str.str.length()),ec); if (JSONCONS_UNLIKELY(ec)) { return; } break; } case jsoncons::cbor::detail::cbor_major_type::byte_string: { read_byte_string_from_buffer read(byte_string_view(str.bytes)); write_byte_string(read, visitor, ec); if (JSONCONS_UNLIKELY(ec)) { return; } break; } default: JSONCONS_UNREACHABLE(); break; } } else { semantic_tag tag = semantic_tag::none; if (other_tags_[item_tag]) { if (raw_tag_ == 1) { tag = semantic_tag::epoch_second; } other_tags_[item_tag] = false; } visitor.uint64_value(val, tag, *this, ec); more_ = !cursor_mode_; } break; } case jsoncons::cbor::detail::cbor_major_type::negative_integer: { int64_t val = get_int64_value(ec); if (JSONCONS_UNLIKELY(ec)) { return; } semantic_tag tag = semantic_tag::none; if (other_tags_[item_tag]) { if (raw_tag_ == 1) { tag = semantic_tag::epoch_second; } other_tags_[item_tag] = false; } visitor.int64_value(val, tag, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::cbor::detail::cbor_major_type::byte_string: { read_byte_string_from_source read(this); write_byte_string(read, visitor, ec); if (JSONCONS_UNLIKELY(ec)) { return; } break; } case jsoncons::cbor::detail::cbor_major_type::text_string: { text_buffer_.clear(); read_text_string(text_buffer_, ec); if (JSONCONS_UNLIKELY(ec)) { return; } auto result = unicode_traits::validate(text_buffer_.data(),text_buffer_.size()); if (result.ec != unicode_traits::conv_errc()) { ec = cbor_errc::invalid_utf8_text_string; more_ = false; return; } handle_string(visitor, jsoncons::basic_string_view(text_buffer_.data(),text_buffer_.length()),ec); if (JSONCONS_UNLIKELY(ec)) { return; } break; } case jsoncons::cbor::detail::cbor_major_type::semantic_tag: { JSONCONS_UNREACHABLE(); break; } case jsoncons::cbor::detail::cbor_major_type::simple: { switch (info) { case 0x14: visitor.bool_value(false, semantic_tag::none, *this, ec); more_ = !cursor_mode_; source_.ignore(1); break; case 0x15: visitor.bool_value(true, semantic_tag::none, *this, ec); more_ = !cursor_mode_; source_.ignore(1); break; case 0x16: visitor.null_value(semantic_tag::none, *this, ec); more_ = !cursor_mode_; source_.ignore(1); break; case 0x17: visitor.null_value(semantic_tag::undefined, *this, ec); more_ = !cursor_mode_; source_.ignore(1); break; case 0x19: // Half-Precision Float (two-byte IEEE 754) { uint64_t val = get_uint64_value(ec); if (JSONCONS_UNLIKELY(ec)) { return; } visitor.half_value(static_cast(val), semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case 0x1a: // Single-Precision Float (four-byte IEEE 754) case 0x1b: // Double-Precision Float (eight-byte IEEE 754) { double val = get_double(ec); if (JSONCONS_UNLIKELY(ec)) { return; } semantic_tag tag = semantic_tag::none; if (other_tags_[item_tag]) { if (raw_tag_ == 1) { tag = semantic_tag::epoch_second; } other_tags_[item_tag] = false; } visitor.double_value(val, tag, *this, ec); more_ = !cursor_mode_; break; } default: { ec = cbor_errc::unknown_type; more_ = false; return; } } break; } case jsoncons::cbor::detail::cbor_major_type::array: { if (other_tags_[item_tag]) { switch (raw_tag_) { case 0x04: text_buffer_.clear(); read_decimal_fraction(text_buffer_, ec); if (JSONCONS_UNLIKELY(ec)) { return; } visitor.string_value(text_buffer_, semantic_tag::bigdec, *this, ec); more_ = !cursor_mode_; break; case 0x05: text_buffer_.clear(); read_bigfloat(text_buffer_, ec); if (JSONCONS_UNLIKELY(ec)) { return; } visitor.string_value(text_buffer_, semantic_tag::bigfloat, *this, ec); more_ = !cursor_mode_; break; case 40: // row major storage produce_begin_multi_dim(visitor, semantic_tag::multi_dim_row_major, ec); break; case 1040: // column major storage produce_begin_multi_dim(visitor, semantic_tag::multi_dim_column_major, ec); break; default: begin_array(visitor, info, ec); break; } other_tags_[item_tag] = false; } else { begin_array(visitor, info, ec); } break; } case jsoncons::cbor::detail::cbor_major_type::map: { begin_object(visitor, info, ec); break; } default: break; } other_tags_[item_tag] = false; } void begin_array(item_event_visitor& visitor, uint8_t info, std::error_code& ec) { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = cbor_errc::max_nesting_depth_exceeded; more_ = false; return; } semantic_tag tag = semantic_tag::none; bool pop_stringref_map_stack = false; if (other_tags_[stringref_namespace_tag]) { stringref_map_stack_.emplace_back(); other_tags_[stringref_namespace_tag] = false; pop_stringref_map_stack = true; } switch (info) { case jsoncons::cbor::detail::additional_info::indefinite_length: { state_stack_.emplace_back(parse_mode::indefinite_array,0,pop_stringref_map_stack); visitor.begin_array(tag, *this, ec); more_ = !cursor_mode_; source_.ignore(1); break; } default: // definite length { std::size_t len = get_size(ec); if (JSONCONS_UNLIKELY(ec)) { return; } state_stack_.emplace_back(parse_mode::array,len,pop_stringref_map_stack); visitor.begin_array(len, tag, *this, ec); more_ = !cursor_mode_; break; } } } void end_array(item_event_visitor& visitor, std::error_code& ec) { --nesting_depth_; visitor.end_array(*this, ec); more_ = !cursor_mode_; if (level() == mark_level_) { more_ = false; } if (state_stack_.back().pop_stringref_map_stack) { stringref_map_stack_.pop_back(); } state_stack_.pop_back(); } void begin_object(item_event_visitor& visitor, uint8_t info, std::error_code& ec) { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = cbor_errc::max_nesting_depth_exceeded; more_ = false; return; } bool pop_stringref_map_stack = false; if (other_tags_[stringref_namespace_tag]) { stringref_map_stack_.emplace_back(); other_tags_[stringref_namespace_tag] = false; pop_stringref_map_stack = true; } switch (info) { case jsoncons::cbor::detail::additional_info::indefinite_length: { state_stack_.emplace_back(parse_mode::indefinite_map_key,0,pop_stringref_map_stack); visitor.begin_object(semantic_tag::none, *this, ec); more_ = !cursor_mode_; source_.ignore(1); break; } default: // definite_length { std::size_t len = get_size(ec); if (JSONCONS_UNLIKELY(ec)) { return; } state_stack_.emplace_back(parse_mode::map_key,len,pop_stringref_map_stack); visitor.begin_object(len, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } } } void end_object(item_event_visitor& visitor, std::error_code& ec) { --nesting_depth_; visitor.end_object(*this, ec); if (level() == mark_level_) { more_ = false; } more_ = !cursor_mode_; if (state_stack_.back().pop_stringref_map_stack) { stringref_map_stack_.pop_back(); } state_stack_.pop_back(); } void read_text_string(string_type& str, std::error_code& ec) { auto c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = cbor_errc::unexpected_eof; more_ = false; return; } jsoncons::cbor::detail::cbor_major_type major_type = get_major_type(c.value); uint8_t info = get_additional_information_value(c.value); JSONCONS_ASSERT(major_type == jsoncons::cbor::detail::cbor_major_type::text_string); auto func = [&str](Source& source, std::size_t length, std::error_code& ec) -> bool { if (source_reader::read(source, str, length) != length) { ec = cbor_errc::unexpected_eof; return false; } return true; }; iterate_string_chunks(func, major_type, ec); if (!stringref_map_stack_.empty() && info != jsoncons::cbor::detail::additional_info::indefinite_length && str.length() >= jsoncons::cbor::detail::min_length_for_stringref(stringref_map_stack_.back().size())) { stringref_map_stack_.back().emplace_back(mapped_string(str,alloc_)); } } std::size_t get_size(std::error_code& ec) { uint64_t u = get_uint64_value(ec); if (JSONCONS_UNLIKELY(ec)) { return 0; } std::size_t len = static_cast(u); if (len != u) { ec = cbor_errc::number_too_large; more_ = false; } return len; } void read_byte_string(byte_string_type& v, std::error_code& ec) { v.clear(); auto c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = cbor_errc::unexpected_eof; return; } jsoncons::cbor::detail::cbor_major_type major_type = get_major_type(c.value); uint8_t info = get_additional_information_value(c.value); JSONCONS_ASSERT(major_type == jsoncons::cbor::detail::cbor_major_type::byte_string); switch(info) { case jsoncons::cbor::detail::additional_info::indefinite_length: { auto func = [&v](Source& source, std::size_t length, std::error_code& ec) -> bool { if (source_reader::read(source, v, length) != length) { ec = cbor_errc::unexpected_eof; return false; } return true; }; iterate_string_chunks(func, major_type, ec); break; } default: { std::size_t length = get_size(ec); if (JSONCONS_UNLIKELY(ec)) { return; } if (source_reader::read(source_, v, length) != length) { ec = cbor_errc::unexpected_eof; return; } if (!stringref_map_stack_.empty() && v.size() >= jsoncons::cbor::detail::min_length_for_stringref(stringref_map_stack_.back().size())) { stringref_map_stack_.back().emplace_back(mapped_string(v, alloc_)); } break; } } } template void iterate_string_chunks(Function& func, jsoncons::cbor::detail::cbor_major_type type, std::error_code& ec) { int nesting_level = 0; bool done = false; while (!done) { auto c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = cbor_errc::unexpected_eof; more_ = false; return; } if (nesting_level > 0 && c.value == 0xff) { --nesting_level; if (nesting_level == 0) { done = true; } source_.ignore(1); continue; } jsoncons::cbor::detail::cbor_major_type major_type = get_major_type(c.value); if (major_type != type) { ec = cbor_errc::illegal_chunked_string; more_ = false; return; } uint8_t info = get_additional_information_value(c.value); switch (info) { case jsoncons::cbor::detail::additional_info::indefinite_length: { ++nesting_level; source_.ignore(1); break; } default: // definite length { std::size_t length = get_size(ec); if (JSONCONS_UNLIKELY(ec)) { return; } more_ = func(source_, length, ec); if (JSONCONS_UNLIKELY(ec)) { return; } if (nesting_level == 0) { done = true; } break; } } } } uint64_t get_uint64_value(std::error_code& ec) { uint64_t val = 0; uint8_t initial_b; if (source_.read(&initial_b, 1) == 0) { ec = cbor_errc::unexpected_eof; more_ = false; return 0; } uint8_t info = get_additional_information_value(initial_b); switch (info) { case JSONCONS_EXT_CBOR_0x00_0x17: // Integer 0x00..0x17 (0..23) { val = info; break; } case 0x18: // Unsigned integer (one-byte uint8_t follows) { uint8_t b; if (source_.read(&b, 1) == 0) { ec = cbor_errc::unexpected_eof; more_ = false; return val; } val = b; break; } case 0x19: // Unsigned integer (two-byte uint16_t follows) { uint8_t buf[sizeof(uint16_t)]; source_.read(buf, sizeof(uint16_t)); val = binary::big_to_native(buf, sizeof(buf)); break; } case 0x1a: // Unsigned integer (four-byte uint32_t follows) { uint8_t buf[sizeof(uint32_t)]; source_.read(buf, sizeof(uint32_t)); val = binary::big_to_native(buf, sizeof(buf)); break; } case 0x1b: // Unsigned integer (eight-byte uint64_t follows) { uint8_t buf[sizeof(uint64_t)]; source_.read(buf, sizeof(uint64_t)); val = binary::big_to_native(buf, sizeof(buf)); break; } default: break; } return val; } int64_t get_int64_value(std::error_code& ec) { int64_t val = 0; auto ch = source_.peek(); if (ch.eof) { ec = cbor_errc::unexpected_eof; more_ = false; return val; } jsoncons::cbor::detail::cbor_major_type major_type = get_major_type(ch.value); uint8_t info = get_additional_information_value(ch.value); switch (major_type) { case jsoncons::cbor::detail::cbor_major_type::negative_integer: source_.ignore(1); switch (info) { case JSONCONS_EXT_CBOR_0x00_0x17: // 0x00..0x17 (0..23) { val = static_cast(- 1 - info); break; } case 0x18: // Negative integer (one-byte uint8_t follows) { uint8_t b; if (source_.read(&b, 1) == 0) { ec = cbor_errc::unexpected_eof; more_ = false; return val; } val = static_cast(-1) - static_cast(b); break; } case 0x19: // Negative integer -1-n (two-byte uint16_t follows) { uint8_t buf[sizeof(uint16_t)]; if (source_.read(buf, sizeof(uint16_t)) != sizeof(uint16_t)) { ec = cbor_errc::unexpected_eof; more_ = false; return val; } auto x = binary::big_to_native(buf, sizeof(buf)); val = static_cast(-1)- x; break; } case 0x1a: // Negative integer -1-n (four-byte uint32_t follows) { uint8_t buf[sizeof(uint32_t)]; if (source_.read(buf, sizeof(uint32_t)) != sizeof(uint32_t)) { ec = cbor_errc::unexpected_eof; more_ = false; return val; } auto x = binary::big_to_native(buf, sizeof(buf)); val = static_cast(-1)- x; break; } case 0x1b: // Negative integer -1-n (eight-byte uint64_t follows) { uint8_t buf[sizeof(uint64_t)]; if (source_.read(buf, sizeof(uint64_t)) != sizeof(uint64_t)) { ec = cbor_errc::unexpected_eof; more_ = false; return val; } auto x = binary::big_to_native(buf, sizeof(buf)); val = static_cast(-1)- static_cast(x); break; } } break; case jsoncons::cbor::detail::cbor_major_type::unsigned_integer: { uint64_t x = get_uint64_value(ec); if (JSONCONS_UNLIKELY(ec)) { return 0; } if (x <= static_cast((std::numeric_limits::max)())) { val = x; } else { // error; } break; } break; default: break; } return val; } double get_double(std::error_code& ec) { double val = 0; uint8_t b; if (source_.read(&b, 1) == 0) { ec = cbor_errc::unexpected_eof; more_ = false; return 0; } uint8_t info = get_additional_information_value(b); switch (info) { case 0x1a: // Single-Precision Float (four-byte IEEE 754) { uint8_t buf[sizeof(float)]; if (source_.read(buf, sizeof(float)) !=sizeof(float)) { ec = cbor_errc::unexpected_eof; more_ = false; return 0; } val = binary::big_to_native(buf, sizeof(buf)); break; } case 0x1b: // Double-Precision Float (eight-byte IEEE 754) { uint8_t buf[sizeof(double)]; if (source_.read(buf, sizeof(double)) != sizeof(double)) { ec = cbor_errc::unexpected_eof; more_ = false; return 0; } val = binary::big_to_native(buf, sizeof(buf)); break; } default: break; } return val; } void read_decimal_fraction(string_type& result, std::error_code& ec) { std::size_t size = get_size(ec); if (JSONCONS_UNLIKELY(ec)) { return; } if (size != 2) { ec = cbor_errc::invalid_decimal_fraction; more_ = false; return; } auto c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = cbor_errc::unexpected_eof; more_ = false; return; } int64_t exponent = 0; switch (get_major_type(c.value)) { case jsoncons::cbor::detail::cbor_major_type::unsigned_integer: { exponent = get_uint64_value(ec); if (JSONCONS_UNLIKELY(ec)) { return; } break; } case jsoncons::cbor::detail::cbor_major_type::negative_integer: { exponent = get_int64_value(ec); if (JSONCONS_UNLIKELY(ec)) { return; } break; } default: { ec = cbor_errc::invalid_decimal_fraction; more_ = false; return; } } string_type str(alloc_); c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = cbor_errc::unexpected_eof; more_ = false; return; } switch (get_major_type(c.value)) { case jsoncons::cbor::detail::cbor_major_type::unsigned_integer: { uint64_t val = get_uint64_value(ec); if (JSONCONS_UNLIKELY(ec)) { return; } jsoncons::detail::from_integer(val, str); break; } case jsoncons::cbor::detail::cbor_major_type::negative_integer: { int64_t val = get_int64_value(ec); if (JSONCONS_UNLIKELY(ec)) { return; } jsoncons::detail::from_integer(val, str); break; } case jsoncons::cbor::detail::cbor_major_type::semantic_tag: { uint8_t b; if (source_.read(&b, 1) == 0) { ec = cbor_errc::unexpected_eof; more_ = false; return; } uint8_t tag = get_additional_information_value(b); c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = cbor_errc::unexpected_eof; more_ = false; return; } if (get_major_type(c.value) == jsoncons::cbor::detail::cbor_major_type::byte_string) { bytes_buffer_.clear(); read_byte_string(bytes_buffer_, ec); if (JSONCONS_UNLIKELY(ec)) { more_ = false; return; } if (tag == 2) { bigint n = bigint::from_bytes_be(1, bytes_buffer_.data(), bytes_buffer_.size()); n.write_string(str); } else if (tag == 3) { bigint n = bigint::from_bytes_be(1, bytes_buffer_.data(), bytes_buffer_.size()); n = -1 - n; n.write_string(str); } } break; } default: { ec = cbor_errc::invalid_decimal_fraction; more_ = false; return; } } if (str.size() >= static_cast((std::numeric_limits::max)()) || exponent >= (std::numeric_limits::max)() || exponent <= (std::numeric_limits::min)()) { ec = cbor_errc::invalid_decimal_fraction; more_ = false; return; } else if (str.size() > 0) { if (str[0] == '-') { result.push_back('-'); jsoncons::detail::prettify_string(str.c_str()+1, str.size()-1, (int)exponent, -4, 17, result); } else { jsoncons::detail::prettify_string(str.c_str(), str.size(), (int)exponent, -4, 17, result); } } else { ec = cbor_errc::invalid_decimal_fraction; more_ = false; return; } } void read_bigfloat(string_type& str, std::error_code& ec) { std::size_t size = get_size(ec); if (JSONCONS_UNLIKELY(ec)) { return; } if (size != 2) { ec = cbor_errc::invalid_bigfloat; more_ = false; return; } auto c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = cbor_errc::unexpected_eof; more_ = false; return; } int64_t exponent = 0; switch (get_major_type(c.value)) { case jsoncons::cbor::detail::cbor_major_type::unsigned_integer: { exponent = get_uint64_value(ec); if (JSONCONS_UNLIKELY(ec)) { return; } break; } case jsoncons::cbor::detail::cbor_major_type::negative_integer: { exponent = get_int64_value(ec); if (JSONCONS_UNLIKELY(ec)) { return; } break; } default: { ec = cbor_errc::invalid_bigfloat; more_ = false; return; } } c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = cbor_errc::unexpected_eof; more_ = false; return; } switch (get_major_type(c.value)) { case jsoncons::cbor::detail::cbor_major_type::unsigned_integer: { uint64_t val = get_uint64_value(ec); if (JSONCONS_UNLIKELY(ec)) { return; } str.push_back('0'); str.push_back('x'); jsoncons::detail::integer_to_hex(val, str); break; } case jsoncons::cbor::detail::cbor_major_type::negative_integer: { int64_t val = get_int64_value(ec); if (JSONCONS_UNLIKELY(ec)) { return; } str.push_back('-'); str.push_back('0'); str.push_back('x'); jsoncons::detail::integer_to_hex(static_cast(-val), str); break; } case jsoncons::cbor::detail::cbor_major_type::semantic_tag: { uint8_t b; if (source_.read(&b, 1) == 0) { ec = cbor_errc::unexpected_eof; more_ = false; return; } uint8_t tag = get_additional_information_value(b); c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = cbor_errc::unexpected_eof; more_ = false; return; } if (get_major_type(c.value) == jsoncons::cbor::detail::cbor_major_type::byte_string) { bytes_buffer_.clear(); read_byte_string(bytes_buffer_, ec); if (JSONCONS_UNLIKELY(ec)) { more_ = false; return; } if (tag == 2) { str.push_back('0'); str.push_back('x'); bigint n = bigint::from_bytes_be(1, bytes_buffer_.data(), bytes_buffer_.size()); n.write_string_hex(str); } else if (tag == 3) { str.push_back('-'); str.push_back('0'); bigint n = bigint::from_bytes_be(1, bytes_buffer_.data(), bytes_buffer_.size()); n = -1 - n; n.write_string_hex(str); str[2] = 'x'; // overwrite minus } } break; } default: { ec = cbor_errc::invalid_bigfloat; more_ = false; return; } } str.push_back('p'); if (exponent >=0) { jsoncons::detail::integer_to_hex(static_cast(exponent), str); } else { str.push_back('-'); jsoncons::detail::integer_to_hex(static_cast(-exponent), str); } } static jsoncons::cbor::detail::cbor_major_type get_major_type(uint8_t type) { static constexpr uint8_t major_type_shift = 0x05; uint8_t value = type >> major_type_shift; return static_cast(value); } static uint8_t get_additional_information_value(uint8_t type) { static constexpr uint8_t additional_information_mask = (1U << 5) - 1; uint8_t value = type & additional_information_mask; return value; } void read_tags(std::error_code& ec) { auto c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = cbor_errc::unexpected_eof; more_ = false; return; } jsoncons::cbor::detail::cbor_major_type major_type = get_major_type(c.value); while (major_type == jsoncons::cbor::detail::cbor_major_type::semantic_tag) { uint64_t val = get_uint64_value(ec); if (JSONCONS_UNLIKELY(ec)) { return; } switch(val) { case 25: // stringref other_tags_[stringref_tag] = true; break; case 256: // stringref-namespace other_tags_[stringref_namespace_tag] = true; break; default: other_tags_[item_tag] = true; raw_tag_ = val; break; } c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = cbor_errc::unexpected_eof; more_ = false; return; } major_type = get_major_type(c.value); } } void handle_string(item_event_visitor& visitor, const jsoncons::basic_string_view& v, std::error_code& ec) { semantic_tag tag = semantic_tag::none; if (other_tags_[item_tag]) { switch (raw_tag_) { case 0: tag = semantic_tag::datetime; break; case 32: tag = semantic_tag::uri; break; case 33: tag = semantic_tag::base64url; break; case 34: tag = semantic_tag::base64; break; default: break; } other_tags_[item_tag] = false; } visitor.string_value(v, tag, *this, ec); more_ = !cursor_mode_; } static jsoncons::endian get_typed_array_endianness(const uint8_t tag) { return ((tag & detail::cbor_array_tags_e_mask) >> detail::cbor_array_tags_e_shift) == 0 ? jsoncons::endian::big : jsoncons::endian::little; } static std::size_t get_typed_array_bytes_per_element(const uint8_t tag) { const uint8_t f = (tag & detail::cbor_array_tags_f_mask) >> detail::cbor_array_tags_f_shift; const uint8_t ll = (tag & detail::cbor_array_tags_ll_mask) >> detail::cbor_array_tags_ll_shift; return std::size_t(1) << (f + ll); } template void write_byte_string(Read read, item_event_visitor& visitor, std::error_code& ec) { if (other_tags_[item_tag]) { switch (raw_tag_) { case 0x2: { bytes_buffer_.clear(); read(bytes_buffer_,ec); if (JSONCONS_UNLIKELY(ec)) { more_ = false; return; } bigint n = bigint::from_bytes_be(1, bytes_buffer_.data(), bytes_buffer_.size()); text_buffer_.clear(); n.write_string(text_buffer_); visitor.string_value(text_buffer_, semantic_tag::bigint, *this, ec); more_ = !cursor_mode_; break; } case 0x3: { bytes_buffer_.clear(); read(bytes_buffer_,ec); if (JSONCONS_UNLIKELY(ec)) { more_ = false; return; } bigint n = bigint::from_bytes_be(1, bytes_buffer_.data(), bytes_buffer_.size()); n = -1 - n; text_buffer_.clear(); n.write_string(text_buffer_); visitor.string_value(text_buffer_, semantic_tag::bigint, *this, ec); more_ = !cursor_mode_; break; } case 0x15: { read(bytes_buffer_,ec); if (JSONCONS_UNLIKELY(ec)) { more_ = false; return; } visitor.byte_string_value(bytes_buffer_, semantic_tag::base64url, *this, ec); more_ = !cursor_mode_; break; } case 0x16: { read(bytes_buffer_,ec); if (JSONCONS_UNLIKELY(ec)) { more_ = false; return; } visitor.byte_string_value(bytes_buffer_, semantic_tag::base64, *this, ec); more_ = !cursor_mode_; break; } case 0x17: { read(bytes_buffer_,ec); if (JSONCONS_UNLIKELY(ec)) { more_ = false; return; } visitor.byte_string_value(bytes_buffer_, semantic_tag::base16, *this, ec); more_ = !cursor_mode_; break; } case 0x40: { typed_array_.clear(); read(typed_array_,ec); if (JSONCONS_UNLIKELY(ec)) { more_ = false; return; } uint8_t* data = reinterpret_cast(typed_array_.data()); std::size_t size = typed_array_.size(); visitor.typed_array(jsoncons::span(data,size), semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case 0x44: { typed_array_.clear(); read(typed_array_,ec); if (JSONCONS_UNLIKELY(ec)) { more_ = false; return; } uint8_t* data = reinterpret_cast(typed_array_.data()); std::size_t size = typed_array_.size(); visitor.typed_array(jsoncons::span(data,size), semantic_tag::clamped, *this, ec); more_ = !cursor_mode_; break; } case 0x41: case 0x45: { typed_array_.clear(); read(typed_array_,ec); if (JSONCONS_UNLIKELY(ec)) { more_ = false; return; } const uint8_t tag = (uint8_t)raw_tag_; jsoncons::endian e = get_typed_array_endianness(tag); const size_t bytes_per_elem = get_typed_array_bytes_per_element(tag); uint16_t* data = reinterpret_cast(typed_array_.data()); std::size_t size = typed_array_.size()/bytes_per_elem; if (e != jsoncons::endian::native) { for (std::size_t i = 0; i < size; ++i) { data[i] = binary::byte_swap(data[i]); } } visitor.typed_array(jsoncons::span(data,size), semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case 0x42: case 0x46: { typed_array_.clear(); read(typed_array_,ec); if (JSONCONS_UNLIKELY(ec)) { more_ = false; return; } const uint8_t tag = (uint8_t)raw_tag_; jsoncons::endian e = get_typed_array_endianness(tag); const size_t bytes_per_elem = get_typed_array_bytes_per_element(tag); uint32_t* data = reinterpret_cast(typed_array_.data()); std::size_t size = typed_array_.size()/bytes_per_elem; if (e != jsoncons::endian::native) { for (std::size_t i = 0; i < size; ++i) { data[i] = binary::byte_swap(data[i]); } } visitor.typed_array(jsoncons::span(data,size), semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case 0x43: case 0x47: { typed_array_.clear(); read(typed_array_,ec); if (JSONCONS_UNLIKELY(ec)) { more_ = false; return; } const uint8_t tag = (uint8_t)raw_tag_; jsoncons::endian e = get_typed_array_endianness(tag); const size_t bytes_per_elem = get_typed_array_bytes_per_element(tag); uint64_t* data = reinterpret_cast(typed_array_.data()); std::size_t size = typed_array_.size()/bytes_per_elem; if (e != jsoncons::endian::native) { for (std::size_t i = 0; i < size; ++i) { data[i] = binary::byte_swap(data[i]); } } visitor.typed_array(jsoncons::span(data,size), semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case 0x48: { typed_array_.clear(); read(typed_array_,ec); if (JSONCONS_UNLIKELY(ec)) { more_ = false; return; } int8_t* data = reinterpret_cast(typed_array_.data()); std::size_t size = typed_array_.size(); visitor.typed_array(jsoncons::span(data,size), semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case 0x49: case 0x4d: { typed_array_.clear(); read(typed_array_,ec); if (JSONCONS_UNLIKELY(ec)) { more_ = false; return; } const uint8_t tag = (uint8_t)raw_tag_; jsoncons::endian e = get_typed_array_endianness(tag); const size_t bytes_per_elem = get_typed_array_bytes_per_element(tag); int16_t* data = reinterpret_cast(typed_array_.data()); std::size_t size = typed_array_.size()/bytes_per_elem; if (e != jsoncons::endian::native) { for (std::size_t i = 0; i < size; ++i) { data[i] = binary::byte_swap(data[i]); } } visitor.typed_array(jsoncons::span(data,size), semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case 0x4a: case 0x4e: { typed_array_.clear(); read(typed_array_,ec); if (JSONCONS_UNLIKELY(ec)) { more_ = false; return; } const uint8_t tag = (uint8_t)raw_tag_; jsoncons::endian e = get_typed_array_endianness(tag); const size_t bytes_per_elem = get_typed_array_bytes_per_element(tag); int32_t* data = reinterpret_cast(typed_array_.data()); std::size_t size = typed_array_.size()/bytes_per_elem; if (e != jsoncons::endian::native) { for (std::size_t i = 0; i < size; ++i) { data[i] = binary::byte_swap(data[i]); } } visitor.typed_array(jsoncons::span(data,size), semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case 0x4b: case 0x4f: { typed_array_.clear(); read(typed_array_,ec); if (JSONCONS_UNLIKELY(ec)) { more_ = false; return; } const uint8_t tag = (uint8_t)raw_tag_; jsoncons::endian e = get_typed_array_endianness(tag); const size_t bytes_per_elem = get_typed_array_bytes_per_element(tag); int64_t* data = reinterpret_cast(typed_array_.data()); std::size_t size = typed_array_.size()/bytes_per_elem; if (e != jsoncons::endian::native) { for (std::size_t i = 0; i < size; ++i) { data[i] = binary::byte_swap(data[i]); } } visitor.typed_array(jsoncons::span(data,size), semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case 0x50: case 0x54: { typed_array_.clear(); read(typed_array_,ec); if (JSONCONS_UNLIKELY(ec)) { more_ = false; return; } const uint8_t tag = (uint8_t)raw_tag_; jsoncons::endian e = get_typed_array_endianness(tag); const size_t bytes_per_elem = get_typed_array_bytes_per_element(tag); uint16_t* data = reinterpret_cast(typed_array_.data()); std::size_t size = typed_array_.size()/bytes_per_elem; if (e != jsoncons::endian::native) { for (std::size_t i = 0; i < size; ++i) { data[i] = binary::byte_swap(data[i]); } } visitor.typed_array(half_arg, jsoncons::span(data,size), semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case 0x51: case 0x55: { typed_array_.clear(); read(typed_array_,ec); if (JSONCONS_UNLIKELY(ec)) { more_ = false; return; } const uint8_t tag = (uint8_t)raw_tag_; jsoncons::endian e = get_typed_array_endianness(tag); const size_t bytes_per_elem = get_typed_array_bytes_per_element(tag); float* data = reinterpret_cast(typed_array_.data()); std::size_t size = typed_array_.size()/bytes_per_elem; if (e != jsoncons::endian::native) { for (std::size_t i = 0; i < size; ++i) { data[i] = binary::byte_swap(data[i]); } } visitor.typed_array(jsoncons::span(data,size), semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case 0x52: case 0x56: { typed_array_.clear(); read(typed_array_,ec); if (JSONCONS_UNLIKELY(ec)) { more_ = false; return; } const uint8_t tag = (uint8_t)raw_tag_; jsoncons::endian e = get_typed_array_endianness(tag); const size_t bytes_per_elem = get_typed_array_bytes_per_element(tag); double* data = reinterpret_cast(typed_array_.data()); std::size_t size = typed_array_.size()/bytes_per_elem; if (e != jsoncons::endian::native) { for (std::size_t i = 0; i < size; ++i) { data[i] = binary::byte_swap(data[i]); } } visitor.typed_array(jsoncons::span(data,size), semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } default: { read(bytes_buffer_,ec); if (JSONCONS_UNLIKELY(ec)) { more_ = false; return; } visitor.byte_string_value(bytes_buffer_, raw_tag_, *this, ec); more_ = !cursor_mode_; break; } } other_tags_[item_tag] = false; } else { read(bytes_buffer_,ec); if (JSONCONS_UNLIKELY(ec)) { return; } visitor.byte_string_value(bytes_buffer_, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } } void produce_begin_multi_dim(item_event_visitor& visitor, semantic_tag tag, std::error_code& ec) { uint8_t b; if (source_.read(&b, 1) == 0) { ec = cbor_errc::unexpected_eof; more_ = false; return; } jsoncons::cbor::detail::cbor_major_type major_type = get_major_type(b); JSONCONS_ASSERT(major_type == jsoncons::cbor::detail::cbor_major_type::array); uint8_t info = get_additional_information_value(b); read_shape(info, ec); if (JSONCONS_UNLIKELY(ec)) { return; } state_stack_.emplace_back(parse_mode::multi_dim, 0); visitor.begin_multi_dim(shape_, tag, *this, ec); more_ = !cursor_mode_; } void produce_end_multi_dim(item_event_visitor& visitor, std::error_code& ec) { visitor.end_multi_dim(*this, ec); more_ = !cursor_mode_; state_stack_.pop_back(); } void read_shape(uint8_t info, std::error_code& ec) { shape_.clear(); switch (info) { case jsoncons::cbor::detail::additional_info::indefinite_length: { while (true) { auto c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = cbor_errc::unexpected_eof; more_ = false; return; } if (c.value == 0xff) { source_.ignore(1); } else { std::size_t dim = get_size(ec); if (JSONCONS_UNLIKELY(ec)) { return; } shape_.push_back(dim); } } break; } default: { std::size_t size = get_size(ec); if (JSONCONS_UNLIKELY(ec)) { return; } for (std::size_t i = 0; more_ && i < size; ++i) { std::size_t dim = get_size(ec); if (JSONCONS_UNLIKELY(ec)) { return; } shape_.push_back(dim); } break; } } } }; } // namespace cbor } // namespace jsoncons #endif jsoncons-1.3.2/include/jsoncons_ext/cbor/cbor_reader.hpp000066400000000000000000000064531477700171100234320ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_CBOR_CBOR_EVENT_READER_HPP #define JSONCONS_EXT_CBOR_CBOR_EVENT_READER_HPP #include #include #include #include // std::move #include #include #include #include #include #include #include namespace jsoncons { namespace cbor { template > class basic_cbor_reader { using char_type = char; basic_cbor_parser parser_; basic_item_event_visitor_to_json_visitor adaptor_; item_event_visitor& visitor_; public: template basic_cbor_reader(Sourceable&& source, json_visitor& visitor, const Allocator& alloc) : basic_cbor_reader(std::forward(source), visitor, cbor_decode_options(), alloc) { } template basic_cbor_reader(Sourceable&& source, json_visitor& visitor, const cbor_decode_options& options = cbor_decode_options(), const Allocator& alloc=Allocator()) : parser_(std::forward(source), options, alloc), adaptor_(visitor, alloc), visitor_(adaptor_) { } template basic_cbor_reader(Sourceable&& source, item_event_visitor& visitor, const Allocator& alloc) : basic_cbor_reader(std::forward(source), visitor, cbor_decode_options(), alloc) { } template basic_cbor_reader(Sourceable&& source, item_event_visitor& visitor, const cbor_decode_options& options = cbor_decode_options(), const Allocator& alloc=Allocator()) : parser_(std::forward(source), options, alloc), visitor_(visitor) { } void read() { std::error_code ec; read(ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,line(),column())); } } void read(std::error_code& ec) { parser_.reset(); parser_.parse(visitor_, ec); if (JSONCONS_UNLIKELY(ec)) { return; } } std::size_t line() const { return parser_.line(); } std::size_t column() const { return parser_.column(); } }; using cbor_stream_reader = basic_cbor_reader; using cbor_bytes_reader = basic_cbor_reader; } // namespace cbor_reader } // namespace jsoncons #endif // JSONCONS_EXT_CBOR_CBOR_EVENT_READER_HPP jsoncons-1.3.2/include/jsoncons_ext/cbor/decode_cbor.hpp000066400000000000000000000211331477700171100234030ustar00rootroot00000000000000// Copyright 2017-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_CBOR_DECODE_CBOR_HPP #define JSONCONS_EXT_CBOR_DECODE_CBOR_HPP #include // std::basic_istream #include // std::enable_if #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace cbor { template typename std::enable_if::value && extension_traits::is_byte_sequence::value,T>::type decode_cbor(const Source& v, const cbor_decode_options& options = cbor_decode_options()) { jsoncons::json_decoder decoder; auto adaptor = make_json_visitor_adaptor(decoder); basic_cbor_reader reader(v, adaptor, options); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value && extension_traits::is_byte_sequence::value,T>::type decode_cbor(const Source& v, const cbor_decode_options& options = cbor_decode_options()) { basic_cbor_cursor cursor(v, options); json_decoder> decoder{}; std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } template typename std::enable_if::value,T>::type decode_cbor(std::istream& is, const cbor_decode_options& options = cbor_decode_options()) { jsoncons::json_decoder decoder; auto adaptor = make_json_visitor_adaptor(decoder); cbor_stream_reader reader(is, adaptor, options); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value,T>::type decode_cbor(std::istream& is, const cbor_decode_options& options = cbor_decode_options()) { basic_cbor_cursor cursor(is, options); json_decoder> decoder{}; std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } template typename std::enable_if::value,T>::type decode_cbor(InputIt first, InputIt last, const cbor_decode_options& options = cbor_decode_options()) { jsoncons::json_decoder decoder; auto adaptor = make_json_visitor_adaptor(decoder); basic_cbor_reader> reader(binary_iterator_source(first, last), adaptor, options); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value,T>::type decode_cbor(InputIt first, InputIt last, const cbor_decode_options& options = cbor_decode_options()) { basic_cbor_cursor> cursor(binary_iterator_source(first, last), options); json_decoder> decoder{}; std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } // With leading allocator_set parameter template typename std::enable_if::value && extension_traits::is_byte_sequence::value,T>::type decode_cbor(const allocator_set& alloc_set, const Source& v, const cbor_decode_options& options = cbor_decode_options()) { json_decoder decoder(alloc_set.get_allocator(), alloc_set.get_temp_allocator()); auto adaptor = make_json_visitor_adaptor(decoder); basic_cbor_reader reader(v, adaptor, options, alloc_set.get_temp_allocator()); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value && extension_traits::is_byte_sequence::value,T>::type decode_cbor(const allocator_set& alloc_set, const Source& v, const cbor_decode_options& options = cbor_decode_options()) { basic_cbor_cursor cursor(v, options, alloc_set.get_temp_allocator()); json_decoder,TempAllocator> decoder(alloc_set.get_temp_allocator(), alloc_set.get_temp_allocator()); std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } template typename std::enable_if::value,T>::type decode_cbor(const allocator_set& alloc_set, std::istream& is, const cbor_decode_options& options = cbor_decode_options()) { json_decoder decoder(alloc_set.get_allocator(), alloc_set.get_temp_allocator()); auto adaptor = make_json_visitor_adaptor(decoder); basic_cbor_reader reader(is, adaptor, options, alloc_set.get_temp_allocator()); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value,T>::type decode_cbor(const allocator_set& alloc_set, std::istream& is, const cbor_decode_options& options = cbor_decode_options()) { basic_cbor_cursor cursor(is, options, alloc_set.get_temp_allocator()); json_decoder,TempAllocator> decoder(alloc_set.get_temp_allocator(), alloc_set.get_temp_allocator()); std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } } // namespace cbor } // namespace jsoncons #endif jsoncons-1.3.2/include/jsoncons_ext/cbor/encode_cbor.hpp000066400000000000000000000137471477700171100234310ustar00rootroot00000000000000// Copyright 2017-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_CBOR_ENCODE_CBOR_HPP #define JSONCONS_EXT_CBOR_ENCODE_CBOR_HPP #include // std::basic_ostream #include // std::enable_if #include #include #include #include #include #include namespace jsoncons { namespace cbor { // to bytes template typename std::enable_if::value && extension_traits::is_back_insertable_byte_container::value,void>::type encode_cbor(const T& j, ByteContainer& cont, const cbor_encode_options& options = cbor_encode_options()) { using char_type = typename T::char_type; basic_cbor_encoder> encoder(cont, options); auto adaptor = make_json_visitor_adaptor>(encoder); j.dump(adaptor); } template typename std::enable_if::value && extension_traits::is_back_insertable_byte_container::value,void>::type encode_cbor(const T& val, ByteContainer& cont, const cbor_encode_options& options = cbor_encode_options()) { basic_cbor_encoder> encoder(cont, options); std::error_code ec; encode_traits::encode(val, encoder, json(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } // stream template typename std::enable_if::value,void>::type encode_cbor(const T& j, std::ostream& os, const cbor_encode_options& options = cbor_encode_options()) { using char_type = typename T::char_type; cbor_stream_encoder encoder(os, options); auto adaptor = make_json_visitor_adaptor>(encoder); j.dump(adaptor); } template typename std::enable_if::value,void>::type encode_cbor(const T& val, std::ostream& os, const cbor_encode_options& options = cbor_encode_options()) { cbor_stream_encoder encoder(os, options); std::error_code ec; encode_traits::encode(val, encoder, json(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } // temp_allocator_arg // to bytes template typename std::enable_if::value && extension_traits::is_back_insertable_byte_container::value,void>::type encode_cbor(const allocator_set& alloc_set, const T& j, ByteContainer& cont, const cbor_encode_options& options = cbor_encode_options()) { using char_type = typename T::char_type; basic_cbor_encoder,TempAllocator> encoder(cont, options, alloc_set.get_temp_allocator()); auto adaptor = make_json_visitor_adaptor>(encoder); j.dump(adaptor); } template typename std::enable_if::value && extension_traits::is_back_insertable_byte_container::value,void>::type encode_cbor(const allocator_set& alloc_set, const T& val, ByteContainer& cont, const cbor_encode_options& options = cbor_encode_options()) { basic_cbor_encoder,TempAllocator> encoder(cont, options, alloc_set.get_temp_allocator()); std::error_code ec; encode_traits::encode(val, encoder, json(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } // stream template typename std::enable_if::value,void>::type encode_cbor(const allocator_set& alloc_set, const T& j, std::ostream& os, const cbor_encode_options& options = cbor_encode_options()) { using char_type = typename T::char_type; basic_cbor_encoder encoder(os, options, alloc_set.get_temp_allocator()); auto adaptor = make_json_visitor_adaptor>(encoder); j.dump(adaptor); } template typename std::enable_if::value,void>::type encode_cbor(const allocator_set& alloc_set, const T& val, std::ostream& os, const cbor_encode_options& options = cbor_encode_options()) { basic_cbor_encoder encoder(os, options, alloc_set.get_temp_allocator()); std::error_code ec; encode_traits::encode(val, encoder, json(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } } // namespace cbor } // namespace jsoncons #endif jsoncons-1.3.2/include/jsoncons_ext/csv/000077500000000000000000000000001477700171100203105ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons_ext/csv/csv.hpp000066400000000000000000000011471477700171100216170ustar00rootroot00000000000000/// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_CSV_CSV_HPP #define JSONCONS_EXT_CSV_CSV_HPP #include #include #include #include #include #include #endif // JSONCONS_EXT_CSV_CSV_HPP jsoncons-1.3.2/include/jsoncons_ext/csv/csv_cursor.hpp000066400000000000000000000264631477700171100232240ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_CSV_CSV_CURSOR_HPP #define JSONCONS_EXT_CSV_CSV_CURSOR_HPP #include #include #include #include // std::allocator #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace csv { template ,typename Allocator=std::allocator> class basic_csv_cursor : public basic_staj_cursor, private virtual ser_context { public: using source_type = Source; using char_type = CharT; using allocator_type = Allocator; private: static constexpr size_t default_max_buffer_size = 16384; using char_allocator_type = typename std::allocator_traits:: template rebind_alloc; text_source_adaptor source_; basic_csv_parser parser_; basic_staj_visitor cursor_visitor_; public: using string_view_type = jsoncons::basic_string_view; // Noncopyable and nonmoveable basic_csv_cursor(const basic_csv_cursor&) = delete; basic_csv_cursor(basic_csv_cursor&&) = delete; // Constructors that throw parse exceptions template basic_csv_cursor(Sourceable&& source, const basic_csv_decode_options& options = basic_csv_decode_options(), std::function err_handler = default_csv_parsing(), const Allocator& alloc = Allocator(), typename std::enable_if,Sourceable>::value>::type* = 0) : source_(std::forward(source)), parser_(options,err_handler,alloc) { parser_.cursor_mode(true); if (!done()) { next(); } } template basic_csv_cursor(Sourceable&& source, const basic_csv_decode_options& options = basic_csv_decode_options(), std::function err_handler = default_csv_parsing(), const Allocator& alloc = Allocator(), typename std::enable_if,Sourceable>::value>::type* = 0) : source_(), parser_(options,err_handler,alloc) { parser_.cursor_mode(true); jsoncons::basic_string_view sv(std::forward(source)); initialize_with_string_view(sv); } // Constructors that set parse error codes template basic_csv_cursor(Sourceable&& source, std::error_code& ec) : basic_csv_cursor(std::allocator_arg, Allocator(), std::forward(source), basic_csv_decode_options(), default_csv_parsing(), ec) { } template basic_csv_cursor(Sourceable&& source, const basic_csv_decode_options& options, std::error_code& ec) : basic_csv_cursor(std::allocator_arg, Allocator(), std::forward(source), options, default_csv_parsing(), ec) { } template basic_csv_cursor(Sourceable&& source, const basic_csv_decode_options& options, std::function err_handler, std::error_code& ec) : basic_csv_cursor(std::allocator_arg, Allocator(), std::forward(source), options, err_handler, ec) { } template basic_csv_cursor(std::allocator_arg_t, const Allocator& alloc, Sourceable&& source, const basic_csv_decode_options& options, std::function err_handler, std::error_code& ec, typename std::enable_if,Sourceable>::value>::type* = 0) : source_(std::forward(source)), parser_(options,err_handler,alloc) { parser_.cursor_mode(true); if (!done()) { next(ec); } } template basic_csv_cursor(std::allocator_arg_t, const Allocator& alloc, Sourceable&& source, const basic_csv_decode_options& options, std::function err_handler, std::error_code& ec, typename std::enable_if,Sourceable>::value>::type* = 0) : source_(), parser_(options,err_handler,alloc) { parser_.cursor_mode(true); jsoncons::basic_string_view sv(std::forward(source)); initialize_with_string_view(sv, ec); } ~basic_csv_cursor() = default; basic_csv_cursor& operator=(const basic_csv_cursor&) = delete; basic_csv_cursor& operator=(basic_csv_cursor&&) = delete; template typename std::enable_if,Sourceable>::value>::type reset(Sourceable&& source) { source_ = std::forward(source); parser_.reinitialize(); cursor_visitor_.reset(); if (!done()) { next(); } } template typename std::enable_if,Sourceable>::value>::type reset(Sourceable&& source) { source_ = {}; parser_.reinitialize(); cursor_visitor_.reset(); initialize_with_string_view(std::forward(source)); } template typename std::enable_if,Sourceable>::value>::type reset(Sourceable&& source, std::error_code& ec) { source_ = std::forward(source); parser_.reinitialize(); cursor_visitor_.reset(); if (!done()) { next(ec); } } template typename std::enable_if,Sourceable>::value>::type reset(Sourceable&& source, std::error_code& ec) { source_ = {}; parser_.reinitialize(); initialize_with_string_view(std::forward(source), ec); } bool done() const override { return parser_.done(); } const basic_staj_event& current() const override { return cursor_visitor_.event(); } void read_to(basic_json_visitor& visitor) override { std::error_code ec; read_to(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); } } void read_to(basic_json_visitor& visitor, std::error_code& ec) override { if (is_begin_container(current().event_type())) { parser_.cursor_mode(false); parser_.mark_level(parser_.level()); cursor_visitor_.event().send_json_event(visitor, *this, ec); if (JSONCONS_UNLIKELY(ec)) { return; } read_next(visitor, ec); parser_.cursor_mode(true); parser_.mark_level(0); if (current().event_type() == staj_event_type::begin_object) { cursor_visitor_.end_object(*this); } else { cursor_visitor_.end_array(*this); } } else { cursor_visitor_.event().send_json_event(visitor, *this, ec); } } void next() override { std::error_code ec; next(ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); } } void next(std::error_code& ec) override { read_next(ec); } const ser_context& context() const override { return *this; } bool eof() const { return parser_.source_exhausted() && source_.eof(); } std::size_t line() const override { return parser_.line(); } std::size_t column() const override { return parser_.column(); } friend basic_staj_filter_view operator|(basic_csv_cursor& cursor, std::function&, const ser_context&)> pred) { return basic_staj_filter_view(cursor, pred); } private: void initialize_with_string_view(string_view_type sv) { auto r = unicode_traits::detect_json_encoding(sv.data(), sv.size()); if (!(r.encoding == unicode_traits::encoding_kind::utf8 || r.encoding == unicode_traits::encoding_kind::undetected)) { JSONCONS_THROW(ser_error(json_errc::illegal_unicode_character,parser_.line(),parser_.column())); } std::size_t offset = (r.ptr - sv.data()); parser_.update(sv.data()+offset,sv.size()-offset); if (!done()) { next(); } } void initialize_with_string_view(string_view_type sv, std::error_code& ec) { auto r = unicode_traits::detect_encoding_from_bom(sv.data(), sv.size()); if (!(r.encoding == unicode_traits::encoding_kind::utf8 || r.encoding == unicode_traits::encoding_kind::undetected)) { ec = json_errc::illegal_unicode_character; return; } std::size_t offset = (r.ptr - sv.data()); parser_.update(sv.data()+offset,sv.size()-offset); if (!done()) { next(ec); } } void read_next(std::error_code& ec) { read_next(cursor_visitor_, ec); } void read_next(basic_json_visitor& visitor, std::error_code& ec) { parser_.restart(); while (!parser_.stopped()) { if (parser_.source_exhausted()) { auto s = source_.read_buffer(ec); if (JSONCONS_UNLIKELY(ec)) {return;} if (s.size() > 0) { parser_.update(s.data(),s.size()); } } parser_.parse_some(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} } } }; using csv_stream_cursor = basic_csv_cursor>; using csv_string_cursor = basic_csv_cursor>; using wcsv_stream_cursor = basic_csv_cursor>; using wcsv_string_cursor = basic_csv_cursor>; } // namespace csv } // namespace jsoncons #endif // JSONCONS_EXT_CSV_CSV_CURSOR_HPP jsoncons-1.3.2/include/jsoncons_ext/csv/csv_encoder.hpp000066400000000000000000001477741477700171100233370ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_CSV_CSV_ENCODER_HPP #define JSONCONS_EXT_CSV_CSV_ENCODER_HPP #include // std::array #include // std::numeric_limits #include // std::allocator #include #include #include // std::unordered_map #include // std::move #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace csv { template ,typename Allocator=std::allocator> class basic_csv_encoder final : public basic_json_visitor { public: using char_type = CharT; using typename basic_json_visitor::string_view_type; using sink_type = Sink; using allocator_type = Allocator; using char_allocator_type = typename std::allocator_traits:: template rebind_alloc; using string_type = std::basic_string, char_allocator_type>; using string_allocator_type = typename std::allocator_traits:: template rebind_alloc; using string_string_allocator_type = typename std::allocator_traits:: template rebind_alloc>; using string_vector_allocator_type = typename std::allocator_traits:: template rebind_alloc>>; using column_type = std::vector; using column_path_column_map_type = std::unordered_map,std::equal_to,string_vector_allocator_type>; private: static jsoncons::basic_string_view null_constant() { static jsoncons::basic_string_view k = JSONCONS_STRING_VIEW_CONSTANT(CharT,"null"); return k; } static jsoncons::basic_string_view true_constant() { static jsoncons::basic_string_view k = JSONCONS_STRING_VIEW_CONSTANT(CharT,"true"); return k; } static jsoncons::basic_string_view false_constant() { static jsoncons::basic_string_view k = JSONCONS_STRING_VIEW_CONSTANT(CharT,"false"); return k; } enum class stack_item_kind { flat_row_mapping, row_mapping, flat_object, flat_row, stream_flat_row, unmapped, object, row, column_mapping, column, multivalued_field, stream_multivalued_field, column_multivalued_field }; struct stack_item { stack_item_kind item_kind_; std::size_t count_{0}; string_type column_path_; stack_item(stack_item_kind item_kind) noexcept : item_kind_(item_kind) { } stack_item_kind item_kind() const { return item_kind_; } }; using stack_item_allocator_type = typename std::allocator_traits:: template rebind_alloc; static const stack_item& parent(const std::vector& stack) { JSONCONS_ASSERT(stack.size() >= 2); return stack[stack.size() - 2]; } Sink sink_; bool flat_; std::size_t max_nesting_depth_; bool has_column_mapping_; bool has_column_names_; char_type field_delimiter_; char_type subfield_delimiter_; string_type line_delimiter_; quote_style_kind quote_style_; char_type quote_char_; char_type quote_escape_char_; bool enable_nan_to_num_; string_type nan_to_num_; bool enable_nan_to_str_; string_type nan_to_str_; bool enable_inf_to_num_; string_type inf_to_num_; bool enable_inf_to_str_; string_type inf_to_str_; bool enable_neginf_to_num_; string_type neginf_to_num_; bool enable_neginf_to_str_; string_type neginf_to_str_; allocator_type alloc_; std::vector stack_; jsoncons::detail::write_double fp_; std::vector column_names_; std::vector column_paths_; std::unordered_map,std::equal_to,string_string_allocator_type> column_path_name_map_; std::unordered_map,std::equal_to,string_string_allocator_type> column_path_value_map_; column_path_column_map_type column_path_column_map_; std::size_t column_index_{0}; string_type value_buffer_; typename column_path_column_map_type::iterator column_it_; // Noncopyable and nonmoveable basic_csv_encoder(const basic_csv_encoder&) = delete; basic_csv_encoder& operator=(const basic_csv_encoder&) = delete; public: basic_csv_encoder(Sink&& sink, const Allocator& alloc = Allocator()) : basic_csv_encoder(std::forward(sink), basic_csv_encode_options(), alloc) { } basic_csv_encoder(Sink&& sink, const basic_csv_encode_options& options, const Allocator& alloc = Allocator()) : sink_(std::forward(sink)), flat_(options.flat()), max_nesting_depth_(options.max_nesting_depth()), has_column_mapping_(!options.column_mapping().empty()), has_column_names_(!options.column_names().empty()), field_delimiter_(options.field_delimiter()), subfield_delimiter_(options.subfield_delimiter()), line_delimiter_(options.line_delimiter()), quote_style_(options.quote_style()), quote_char_(options.quote_char()), quote_escape_char_(options.quote_escape_char()), enable_nan_to_num_(options.enable_nan_to_num()), nan_to_num_(options.nan_to_num()), enable_nan_to_str_(options.enable_nan_to_str()), nan_to_str_(options.nan_to_str()), enable_inf_to_num_(options.enable_inf_to_num()), inf_to_num_(options.inf_to_num()), enable_inf_to_str_(options.enable_inf_to_str()), inf_to_str_(options.inf_to_str()), enable_neginf_to_num_(options.enable_neginf_to_num()), neginf_to_num_(options.neginf_to_num()), enable_neginf_to_str_(options.enable_neginf_to_str()), neginf_to_str_(options.neginf_to_str()), alloc_(alloc), stack_(alloc), fp_(options.float_format(), options.precision()), column_names_(alloc), column_paths_(alloc), column_path_name_map_(alloc), column_path_value_map_(alloc), column_path_column_map_(alloc), value_buffer_(alloc), column_it_(column_path_column_map_.end()) { if (has_column_mapping_) { for (const auto& item : options.column_mapping()) { column_paths_.emplace_back(item.first); column_path_name_map_.emplace(item.first, item.second); column_path_value_map_.emplace(item.first, string_type{alloc_}); } } if (has_column_names_) { jsoncons::csv::detail::parse_column_names(options.column_names(), column_names_); } } ~basic_csv_encoder() noexcept { JSONCONS_TRY { sink_.flush(); } JSONCONS_CATCH(...) { } } void reset() { stack_.clear(); if (!has_column_mapping_) { column_paths_.clear(); column_path_value_map_.clear(); } column_index_ = 0; } void reset(Sink&& sink) { sink_ = std::move(sink); reset(); } private: void escape_string(const CharT* s, std::size_t length, CharT quote_char, CharT quote_escape_char, string_type& sink) { const CharT* begin = s; const CharT* end = s + length; for (const CharT* it = begin; it != end; ++it) { CharT c = *it; if (c == quote_char) { sink.push_back(quote_escape_char); sink.push_back(quote_char); } else { sink.push_back(c); } } } void visit_flush() override { sink_.flush(); } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag, const ser_context&, std::error_code& ec) override { if (stack_.empty()) { stack_.emplace_back(stack_item_kind::column_mapping); if (has_column_names_) { for (const auto& item : column_names_) { string_type str{alloc_}; str.push_back('/'); str.append(jsonpointer::escape(item, alloc_)); column_paths_.emplace_back(str); column_path_value_map_.emplace(str, string_type{alloc_}); column_path_name_map_.emplace(std::move(str), item); } has_column_mapping_ = true; } JSONCONS_VISITOR_RETURN; } if (JSONCONS_UNLIKELY(stack_.size() >= max_nesting_depth_)) { ec = csv_errc::max_nesting_depth_exceeded; JSONCONS_VISITOR_RETURN; } // legacy if (has_column_names_ && stack_.back().count_ == 0) { if (stack_.back().item_kind_ == stack_item_kind::flat_row_mapping || stack_.back().item_kind_ == stack_item_kind::row_mapping) { for (const auto& item : column_names_) { string_type str{alloc_}; str.push_back('/'); str.append(jsonpointer::escape(item, alloc_)); column_paths_.emplace_back(str); column_path_value_map_.emplace(str, string_type{alloc_}); column_path_name_map_.emplace(std::move(str), item); } has_column_mapping_ = true; } } switch (stack_.back().item_kind_) { case stack_item_kind::flat_row_mapping: stack_.emplace_back(stack_item_kind::flat_object); break; case stack_item_kind::row_mapping: stack_.emplace_back(stack_item_kind::object); break; case stack_item_kind::object: stack_.emplace_back(stack_item_kind::object); break; case stack_item_kind::flat_object: if (subfield_delimiter_ == char_type()) { stack_.emplace_back(stack_item_kind::unmapped); } else { stack_.back().column_path_ = parent(stack_).column_path_; value_buffer_.clear(); stack_.emplace_back(stack_item_kind::multivalued_field); } break; case stack_item_kind::column_multivalued_field: break; case stack_item_kind::unmapped: stack_.emplace_back(stack_item_kind::unmapped); break; default: // error //std::cout << "visit_begin_object " << (int)stack_.back().item_kind_ << "\n"; ec = csv_errc::source_error; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context&, std::error_code& ec) override { JSONCONS_ASSERT(!stack_.empty()); switch (stack_.back().item_kind_) { case stack_item_kind::flat_object: case stack_item_kind::object: if (parent(stack_).item_kind_ == stack_item_kind::row_mapping || parent(stack_).item_kind_ == stack_item_kind::flat_row_mapping) { if (stack_[0].count_ == 0) { bool first = true; for (std::size_t i = 0; i < column_paths_.size(); ++i) { auto it = column_path_name_map_.find(column_paths_[i]); if (it != column_path_name_map_.end()) { if (!first) { sink_.push_back(field_delimiter_); } else { first = false; } sink_.append(it->second.data(), it->second.length()); } } sink_.append(line_delimiter_.data(), line_delimiter_.length()); } for (std::size_t i = 0; i < column_paths_.size(); ++i) { if (i > 0) { sink_.push_back(field_delimiter_); } auto it = column_path_value_map_.find(column_paths_[i]); if (it != column_path_value_map_.end()) { sink_.append(it->second.data(), it->second.length()); it->second.clear(); } } sink_.append(line_delimiter_.data(), line_delimiter_.length()); } break; case stack_item_kind::column_mapping: { // Write header { bool first = true; for (std::size_t i = 0; i < column_paths_.size(); ++i) { auto it = column_path_name_map_.find(column_paths_[i]); if (it != column_path_name_map_.end()) { if (!first) { sink_.push_back(field_delimiter_); } sink_.append(it->second.data(), it->second.length()); first = false; } } sink_.append(line_delimiter_.data(), line_delimiter_.length()); } std::vector> columns; for (const auto& item : column_paths_) { auto it = column_path_column_map_.find(item); if (it != column_path_column_map_.end()) { columns.emplace_back((*it).second.cbegin(), (*it).second.cend()); } } if (!columns.empty()) { const std::size_t no_cols = columns.size(); bool done = false; while (!done) { std::size_t missing_cols = 0; std::size_t new_missing_cols = 0; bool first = true; for (std::size_t i = 0; i < no_cols; ++i) { auto& item = columns[i]; if (item.first == item.second) { ++missing_cols; ++new_missing_cols; if (missing_cols == no_cols) { done = true; } else if (i == (no_cols-1)) { while (new_missing_cols > 0) { sink_.push_back(field_delimiter_); --new_missing_cols; } } } else { while (new_missing_cols > 0) { sink_.push_back(field_delimiter_); --new_missing_cols; } if (!first) { sink_.push_back(field_delimiter_); } else { first = false; } sink_.append((*(item.first)).data(), (*(item.first)).size()); ++item.first; } } if (!done) { sink_.append(line_delimiter_.data(), line_delimiter_.length()); } } } break; } case stack_item_kind::column_multivalued_field: break; case stack_item_kind::unmapped: break; default: //std::cout << "visit_end_object " << (int)stack_.back().item_kind_ << "\n"; ec = csv_errc::source_error; JSONCONS_VISITOR_RETURN; } stack_.pop_back(); if (!stack_.empty()) { ++stack_.back().count_; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag, const ser_context&, std::error_code& ec) override { if (stack_.empty()) { if (flat_) { stack_.emplace_back(stack_item_kind::flat_row_mapping); } else { stack_.emplace_back(stack_item_kind::row_mapping); } JSONCONS_VISITOR_RETURN; } if (JSONCONS_UNLIKELY(stack_.size() >= max_nesting_depth_)) { ec = csv_errc::max_nesting_depth_exceeded; JSONCONS_VISITOR_RETURN; } // legacy if (has_column_names_ && stack_.back().count_ == 0) { if (stack_.back().item_kind_ == stack_item_kind::flat_row_mapping || stack_.back().item_kind_ == stack_item_kind::row_mapping) { std::size_t index = 0; for (const auto& item : column_names_) { string_type str{alloc_}; str.push_back('/'); jsoncons::detail::from_integer(index, str); column_paths_.emplace_back(str); column_path_value_map_.emplace(str, string_type{alloc_}); column_path_name_map_.emplace(std::move(str), item); ++index; } has_column_mapping_ = true; } } switch (stack_.back().item_kind_) { case stack_item_kind::flat_row_mapping: if (has_column_mapping_) { stack_.emplace_back(stack_item_kind::flat_row); } else { stack_.emplace_back(stack_item_kind::stream_flat_row); } break; case stack_item_kind::row_mapping: stack_.emplace_back(stack_item_kind::row); break; case stack_item_kind::object: stack_.emplace_back(stack_item_kind::object); break; case stack_item_kind::row: stack_.emplace_back(stack_item_kind::row); break; case stack_item_kind::flat_row: if (subfield_delimiter_ == char_type()) { stack_.emplace_back(stack_item_kind::unmapped); } else { append_array_path_component(); value_buffer_.clear(); stack_.emplace_back(stack_item_kind::multivalued_field); } break; case stack_item_kind::stream_flat_row: if (subfield_delimiter_ == char_type()) { stack_.emplace_back(stack_item_kind::unmapped); } else { value_buffer_.clear(); stack_.emplace_back(stack_item_kind::stream_multivalued_field); } break; case stack_item_kind::flat_object: if (subfield_delimiter_ == char_type()) { stack_.emplace_back(stack_item_kind::unmapped); } else { if (stack_[0].count_ == 0) { if (!has_column_mapping_) { string_type str = stack_.back().column_path_; column_paths_.emplace_back(str); column_path_value_map_.emplace(std::move(str), string_type{alloc_}); } } value_buffer_.clear(); stack_.emplace_back(stack_item_kind::multivalued_field); } break; case stack_item_kind::multivalued_field: case stack_item_kind::stream_multivalued_field: stack_.emplace_back(stack_item_kind::unmapped); break; case stack_item_kind::column_mapping: stack_.emplace_back(stack_item_kind::column); break; case stack_item_kind::column: { value_buffer_.clear(); stack_.emplace_back(stack_item_kind::column_multivalued_field); break; } case stack_item_kind::column_multivalued_field: stack_.emplace_back(stack_item_kind::unmapped); break; case stack_item_kind::unmapped: stack_.emplace_back(stack_item_kind::unmapped); break; default: // error //std::cout << "visit_begin_array " << (int)stack_.back().item_kind_ << "\n"; ec = csv_errc::source_error; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context&, std::error_code& ec) override { JSONCONS_ASSERT(!stack_.empty()); switch (stack_.back().item_kind_) { case stack_item_kind::row_mapping: case stack_item_kind::flat_row_mapping: break; case stack_item_kind::flat_row: if (parent(stack_).item_kind_ == stack_item_kind::flat_row_mapping) { if (stack_[0].count_ == 0 && !column_path_name_map_.empty()) { std::size_t col = 0; for (std::size_t i = 0; i < column_paths_.size(); ++i) { auto it = column_path_name_map_.find(column_paths_[i]); if (it != column_path_name_map_.end()) { if (col > 0) { sink_.push_back(field_delimiter_); } sink_.append(it->second.data(), it->second.length()); ++col; } } sink_.append(line_delimiter_.data(), line_delimiter_.length()); } for (std::size_t i = 0; i < column_paths_.size(); ++i) { if (i > 0) { sink_.push_back(field_delimiter_); } auto it = column_path_value_map_.find(column_paths_[i]); if (it != column_path_value_map_.end()) { sink_.append(it->second.data(), it->second.length()); it->second.clear(); } } sink_.append(line_delimiter_.data(), line_delimiter_.length()); } break; case stack_item_kind::stream_flat_row: if (parent(stack_).item_kind_ == stack_item_kind::flat_row_mapping) { sink_.append(line_delimiter_.data(), line_delimiter_.length()); } break; case stack_item_kind::multivalued_field: { auto it = column_path_value_map_.find(parent(stack_).column_path_); if (it != column_path_value_map_.end()) { it->second = value_buffer_; } break; } case stack_item_kind::stream_multivalued_field: { if (parent(stack_).count_ > 0) { sink_.push_back(field_delimiter_); } sink_.append(value_buffer_.data(), value_buffer_.size()); break; } case stack_item_kind::row: if (parent(stack_).item_kind_ == stack_item_kind::row_mapping) { if (stack_[0].count_ == 0) { std::size_t col = 0; for (std::size_t i = 0; i < column_paths_.size(); ++i) { auto it = column_path_name_map_.find(column_paths_[i]); if (it != column_path_name_map_.end()) { if (col > 0) { sink_.push_back(field_delimiter_); } sink_.append(it->second.data(), it->second.length()); ++col; } } sink_.append(line_delimiter_.data(), line_delimiter_.length()); } for (std::size_t i = 0; i < column_paths_.size(); ++i) { if (i > 0) { sink_.push_back(field_delimiter_); } auto it = column_path_value_map_.find(column_paths_[i]); if (it != column_path_value_map_.end()) { sink_.append(it->second.data(), it->second.length()); it->second.clear(); } } sink_.append(line_delimiter_.data(), line_delimiter_.length()); } break; case stack_item_kind::column: ++column_index_; break; case stack_item_kind::column_multivalued_field: column_it_->second.emplace_back(value_buffer_.data(),value_buffer_.length()); break; case stack_item_kind::unmapped: break; default: //std::cout << "visit_end_array " << (int)stack_.back().item_kind_ << "\n"; ec = csv_errc::source_error; JSONCONS_VISITOR_RETURN; } stack_.pop_back(); if (!stack_.empty()) { ++stack_.back().count_; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type& name, const ser_context&, std::error_code&) override { JSONCONS_ASSERT(!stack_.empty()); switch (stack_.back().item_kind_) { case stack_item_kind::flat_object: { stack_.back().column_path_ = parent(stack_).column_path_; stack_.back().column_path_.push_back('/'); stack_.back().column_path_.append(jsonpointer::escape(name, alloc_)); if (!has_column_mapping_) { column_path_name_map_.emplace(stack_.back().column_path_, name); } break; } case stack_item_kind::object: { stack_.back().column_path_ = parent(stack_).column_path_; stack_.back().column_path_.push_back('/'); stack_.back().column_path_.append(jsonpointer::escape(name, alloc_)); if (!has_column_mapping_) { column_path_name_map_.emplace(stack_.back().column_path_, stack_.back().column_path_); } break; } case stack_item_kind::column_mapping: { stack_.back().column_path_.clear(); stack_.back().column_path_.push_back('/'); stack_.back().column_path_.append(std::string(name)); if (!has_column_mapping_) { string_type str = stack_.back().column_path_; column_paths_.emplace_back(str); column_path_name_map_.emplace(std::move(str), name); } column_it_ = column_path_column_map_.emplace(stack_.back().column_path_, column_type{alloc_}).first; break; } default: break; } JSONCONS_VISITOR_RETURN; } void append_array_path_component() { stack_.back().column_path_ = parent(stack_).column_path_; stack_.back().column_path_.push_back('/'); jsoncons::detail::from_integer(stack_.back().count_, stack_.back().column_path_); if (stack_[0].count_ == 0) { if (!has_column_mapping_) { string_type str = stack_.back().column_path_; if (stack_.back().item_kind_ == stack_item_kind::row) { column_path_name_map_.emplace(str, stack_.back().column_path_); } column_paths_.emplace_back(str); column_path_value_map_.emplace(std::move(str), string_type{alloc_}); } } } JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_ASSERT(!stack_.empty()); switch (stack_.back().item_kind_) { case stack_item_kind::flat_object: case stack_item_kind::object: { if (stack_[0].count_ == 0) { if (!has_column_mapping_) { string_type str = stack_.back().column_path_; column_paths_.emplace_back(str); column_path_value_map_.emplace(std::move(str), string_type{alloc_}); } } auto it = column_path_value_map_.find(stack_.back().column_path_); if (it != column_path_value_map_.end()) { write_null_value(it->second); } break; } case stack_item_kind::flat_row: case stack_item_kind::row: { append_array_path_component(); auto it = column_path_value_map_.find(stack_.back().column_path_); if (it != column_path_value_map_.end()) { write_null_value(it->second); } break; } case stack_item_kind::stream_flat_row: { if (stack_.back().count_ > 0) { sink_.push_back(field_delimiter_); } value_buffer_.clear(); write_null_value(value_buffer_); sink_.append(value_buffer_.data(), value_buffer_.size()); break; } case stack_item_kind::column_multivalued_field: case stack_item_kind::multivalued_field: case stack_item_kind::stream_multivalued_field: { if (!value_buffer_.empty()) { value_buffer_.push_back(subfield_delimiter_); } write_null_value(value_buffer_); break; } case stack_item_kind::column: { (*column_it_).second.emplace_back(); write_null_value((*column_it_).second.back()); break; } default: break; } ++stack_.back().count_; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& sv, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_ASSERT(!stack_.empty()); switch (stack_.back().item_kind_) { case stack_item_kind::flat_object: case stack_item_kind::object: { if (stack_[0].count_ == 0) { if (!has_column_mapping_) { string_type str = stack_.back().column_path_; column_paths_.emplace_back(str); column_path_value_map_.emplace(std::move(str), string_type{alloc_}); } } auto it = column_path_value_map_.find(stack_.back().column_path_); if (it != column_path_value_map_.end()) { write_string_value(sv, it->second); } break; } case stack_item_kind::flat_row: case stack_item_kind::row: { append_array_path_component(); auto it = column_path_value_map_.find(stack_.back().column_path_); if (it != column_path_value_map_.end()) { write_string_value(sv, it->second); } break; } case stack_item_kind::stream_flat_row: { if (stack_.back().count_ > 0) { sink_.push_back(field_delimiter_); } value_buffer_.clear(); write_string_value(sv, value_buffer_); sink_.append(value_buffer_.data(), value_buffer_.size()); break; } case stack_item_kind::column_multivalued_field: case stack_item_kind::multivalued_field: case stack_item_kind::stream_multivalued_field: { if (!value_buffer_.empty()) { value_buffer_.push_back(subfield_delimiter_); } write_string_value(sv, value_buffer_); break; } case stack_item_kind::column: { (*column_it_).second.emplace_back(); write_string_value(sv, (*column_it_).second.back()); break; } default: break; } ++stack_.back().count_; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& b, semantic_tag tag, const ser_context& context, std::error_code& ec) override { JSONCONS_ASSERT(!stack_.empty()); byte_string_chars_format encoding_hint; switch (tag) { case semantic_tag::base16: encoding_hint = byte_string_chars_format::base16; break; case semantic_tag::base64: encoding_hint = byte_string_chars_format::base64; break; case semantic_tag::base64url: encoding_hint = byte_string_chars_format::base64url; break; default: encoding_hint = byte_string_chars_format::none; break; } byte_string_chars_format format = jsoncons::detail::resolve_byte_string_chars_format(encoding_hint,byte_string_chars_format::none,byte_string_chars_format::base64url); std::basic_string s; switch (format) { case byte_string_chars_format::base16: { encode_base16(b.begin(),b.end(),s); visit_string(s, semantic_tag::none, context, ec); break; } case byte_string_chars_format::base64: { encode_base64(b.begin(),b.end(),s); visit_string(s, semantic_tag::none, context, ec); break; } case byte_string_chars_format::base64url: { encode_base64url(b.begin(),b.end(),s); visit_string(s, semantic_tag::none, context, ec); break; } default: { JSONCONS_UNREACHABLE(); } } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_double(double val, semantic_tag, const ser_context& context, std::error_code& ec) override { JSONCONS_ASSERT(!stack_.empty()); switch (stack_.back().item_kind_) { case stack_item_kind::flat_object: case stack_item_kind::object: { if (stack_[0].count_ == 0) { if (!has_column_mapping_) { string_type str = stack_.back().column_path_; column_paths_.emplace_back(str); column_path_value_map_.emplace(std::move(str), string_type{alloc_}); } } auto it = column_path_value_map_.find(stack_.back().column_path_); if (it != column_path_value_map_.end()) { write_double_value(val, context, it->second, ec); } break; } case stack_item_kind::flat_row: case stack_item_kind::row: { append_array_path_component(); auto it = column_path_value_map_.find(stack_.back().column_path_); if (it != column_path_value_map_.end()) { write_double_value(val, context, it->second, ec); } break; } case stack_item_kind::stream_flat_row: { if (stack_.back().count_ > 0) { sink_.push_back(field_delimiter_); } value_buffer_.clear(); write_double_value(val, context, value_buffer_, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_VISITOR_RETURN; } sink_.append(value_buffer_.data(), value_buffer_.size()); break; } case stack_item_kind::multivalued_field: case stack_item_kind::column_multivalued_field: case stack_item_kind::stream_multivalued_field: { if (!value_buffer_.empty()) { value_buffer_.push_back(subfield_delimiter_); } write_double_value(val, context, value_buffer_, ec); break; } case stack_item_kind::column: { (*column_it_).second.emplace_back(); write_double_value(val, context, (*column_it_).second.back(), ec); break; } default: break; } ++stack_.back().count_; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t val, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_ASSERT(!stack_.empty()); switch (stack_.back().item_kind_) { case stack_item_kind::flat_object: case stack_item_kind::object: { if (stack_[0].count_ == 0) { if (!has_column_mapping_) { string_type str = stack_.back().column_path_; column_paths_.emplace_back(str); column_path_value_map_.emplace(std::move(str), string_type{alloc_}); } } auto it = column_path_value_map_.find(stack_.back().column_path_); if (it != column_path_value_map_.end()) { write_int64_value(val, it->second); } break; } case stack_item_kind::flat_row: case stack_item_kind::row: { append_array_path_component(); auto it = column_path_value_map_.find(stack_.back().column_path_); if (it != column_path_value_map_.end()) { write_int64_value(val, it->second); } break; } case stack_item_kind::stream_flat_row: { if (stack_.back().count_ > 0) { sink_.push_back(field_delimiter_); } value_buffer_.clear(); write_int64_value(val, value_buffer_); sink_.append(value_buffer_.data(), value_buffer_.size()); break; } case stack_item_kind::column_multivalued_field: case stack_item_kind::multivalued_field: case stack_item_kind::stream_multivalued_field: { if (!value_buffer_.empty()) { value_buffer_.push_back(subfield_delimiter_); } write_int64_value(val, value_buffer_); break; } case stack_item_kind::column: { (*column_it_).second.emplace_back(); write_int64_value(val, (*column_it_).second.back()); break; } default: break; } ++stack_.back().count_; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t val, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_ASSERT(!stack_.empty()); switch (stack_.back().item_kind_) { case stack_item_kind::flat_object: case stack_item_kind::object: { if (stack_[0].count_ == 0) { if (!has_column_mapping_) { string_type str = stack_.back().column_path_; column_paths_.emplace_back(str); column_path_value_map_.emplace(std::move(str), string_type{alloc_}); } } auto it = column_path_value_map_.find(stack_.back().column_path_); if (it != column_path_value_map_.end()) { write_uint64_value(val, it->second); } break; } case stack_item_kind::flat_row: case stack_item_kind::row: { append_array_path_component(); auto it = column_path_value_map_.find(stack_.back().column_path_); if (it != column_path_value_map_.end()) { write_uint64_value(val, it->second); } break; } case stack_item_kind::stream_flat_row: { if (stack_.back().count_ > 0) { sink_.push_back(field_delimiter_); } value_buffer_.clear(); write_uint64_value(val, value_buffer_); sink_.append(value_buffer_.data(), value_buffer_.size()); break; } case stack_item_kind::multivalued_field: case stack_item_kind::column_multivalued_field: case stack_item_kind::stream_multivalued_field: { if (!value_buffer_.empty()) { value_buffer_.push_back(subfield_delimiter_); } write_uint64_value(val, value_buffer_); break; } case stack_item_kind::column: { (*column_it_).second.emplace_back(); write_uint64_value(val, (*column_it_).second.back()); break; } default: break; } ++stack_.back().count_; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool val, semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_ASSERT(!stack_.empty()); switch (stack_.back().item_kind_) { case stack_item_kind::flat_object: case stack_item_kind::object: { if (stack_[0].count_ == 0) { if (!has_column_mapping_) { string_type str = stack_.back().column_path_; column_paths_.emplace_back(str); column_path_value_map_.emplace(std::move(str), string_type{alloc_}); } } auto it = column_path_value_map_.find(stack_.back().column_path_); if (it != column_path_value_map_.end()) { write_bool_value(val, it->second); } break; } case stack_item_kind::flat_row: case stack_item_kind::row: { append_array_path_component(); auto it = column_path_value_map_.find(stack_.back().column_path_); if (it != column_path_value_map_.end()) { write_bool_value(val, it->second); } break; } case stack_item_kind::stream_flat_row: { if (stack_.back().count_ > 0) { sink_.push_back(field_delimiter_); } value_buffer_.clear(); write_bool_value(val, value_buffer_); sink_.append(value_buffer_.data(), value_buffer_.size()); break; } case stack_item_kind::multivalued_field: case stack_item_kind::column_multivalued_field: case stack_item_kind::stream_multivalued_field: { if (!value_buffer_.empty()) { value_buffer_.push_back(subfield_delimiter_); } write_bool_value(val, value_buffer_); break; } case stack_item_kind::column: { (*column_it_).second.emplace_back(); write_bool_value(val, (*column_it_).second.back()); break; } default: break; } ++stack_.back().count_; JSONCONS_VISITOR_RETURN; } void write_string_value(const string_view_type& value, string_type& str) { const char* s = value.data(); const std::size_t length = value.length(); bool quote = false; if (quote_style_ == quote_style_kind::all || quote_style_ == quote_style_kind::nonnumeric || (quote_style_ == quote_style_kind::minimal && (std::char_traits::find(s, length, field_delimiter_) != nullptr || std::char_traits::find(s, length, quote_char_) != nullptr))) { quote = true; str.push_back(quote_char_); } escape_string(s, length, quote_char_, quote_escape_char_, str); if (quote) { str.push_back(quote_char_); } } void write_double_value(double val, const ser_context& context, string_type& str, std::error_code& ec) { if (!std::isfinite(val)) { if ((std::isnan)(val)) { if (enable_nan_to_num_) { str.append(nan_to_num_.data(), nan_to_num_.length()); } else if (enable_nan_to_str_) { visit_string(nan_to_str_, semantic_tag::none, context, ec); } else { str.append(null_constant().data(), null_constant().size()); } } else if (val == std::numeric_limits::infinity()) { if (enable_inf_to_num_) { str.append(inf_to_num_.data(), inf_to_num_.length()); } else if (enable_inf_to_str_) { visit_string(inf_to_str_, semantic_tag::none, context, ec); } else { str.append(null_constant().data(), null_constant().size()); } } else { if (enable_neginf_to_num_) { str.append(neginf_to_num_.data(), neginf_to_num_.length()); } else if (enable_neginf_to_str_) { visit_string(neginf_to_str_, semantic_tag::none, context, ec); } else { str.append(null_constant().data(), null_constant().size()); } } } else { fp_(val, str); } } void write_int64_value(int64_t val, string_type& str) { jsoncons::detail::from_integer(val,str); } void write_uint64_value(uint64_t val, string_type& str) { jsoncons::detail::from_integer(val,str); } void write_bool_value(bool val, string_type& str) { if (val) { str.append(true_constant().data(), true_constant().size()); } else { str.append(false_constant().data(), false_constant().size()); } } void write_null_value(string_type& str) { str.append(null_constant().data(), null_constant().size()); } }; using csv_stream_encoder = basic_csv_encoder; using csv_string_encoder = basic_csv_encoder>; using csv_wstream_encoder = basic_csv_encoder; using wcsv_string_encoder = basic_csv_encoder>; }} #endif jsoncons-1.3.2/include/jsoncons_ext/csv/csv_error.hpp000066400000000000000000000045351477700171100230340ustar00rootroot00000000000000/// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_CSV_CSV_ERROR_HPP #define JSONCONS_EXT_CSV_CSV_ERROR_HPP #include #include #include namespace jsoncons { namespace csv { enum class csv_errc : int { success = 0, unexpected_eof = 1, source_error, expected_quote, syntax_error, invalid_parse_state, invalid_escaped_char, unexpected_char_between_fields, max_nesting_depth_exceeded }; class csv_error_category_impl : public std::error_category { public: const char* name() const noexcept override { return "jsoncons/csv"; } std::string message(int ev) const override { switch (static_cast(ev)) { case csv_errc::unexpected_eof: return "Unexpected end of file"; case csv_errc::source_error: return "Source error"; case csv_errc::expected_quote: return "Expected quote character"; case csv_errc::syntax_error: return "CSV syntax error"; case csv_errc::invalid_parse_state: return "Invalid CSV parser state"; case csv_errc::invalid_escaped_char: return "Invalid character following quote escape character"; case csv_errc::unexpected_char_between_fields: return "Unexpected character between fields"; case csv_errc::max_nesting_depth_exceeded: return "Data item nesting exceeds limit in options"; default: return "Unknown CSV parser error"; } } }; inline const std::error_category& csv_error_category() { static csv_error_category_impl instance; return instance; } inline std::error_code make_error_code(csv_errc result) { return std::error_code(static_cast(result),csv_error_category()); } } // namespace jsonpath } // namespace jsoncons namespace std { template<> struct is_error_code_enum : public true_type { }; } // namespace std #endif // JSONCONS_EXT_CSV_CSV_ERROR_HPP jsoncons-1.3.2/include/jsoncons_ext/csv/csv_options.hpp000066400000000000000000000640751477700171100234030ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_CSV_CSV_OPTIONS_HPP #define JSONCONS_EXT_CSV_CSV_OPTIONS_HPP #include #include #include // std::numeric_limits #include #include #include // std::unordered_map #include // std::pair #include namespace jsoncons { namespace csv { enum class csv_column_type : uint8_t { string_t,integer_t,float_t,boolean_t,repeat_t }; enum class quote_style_kind : uint8_t { minimal,all,nonnumeric,none }; enum class csv_mapping_kind : uint8_t { n_rows = 1, n_objects, m_columns }; enum class column_state {sequence,label}; struct csv_type_info { csv_type_info() = default; csv_type_info(const csv_type_info&) = default; csv_type_info(csv_type_info&&) = default; csv_type_info(csv_column_type ctype, std::size_t lev, std::size_t repcount = 0) noexcept { col_type = ctype; level = lev; rep_count = repcount; } csv_column_type col_type; std::size_t level; std::size_t rep_count; }; namespace detail { template void parse_column_names(const std::basic_string& names, Container& cont) { column_state state = column_state::sequence; typename Container::value_type buffer(cont.get_allocator()); auto p = names.begin(); while (p != names.end()) { switch (state) { case column_state::sequence: { switch (*p) { case ' ': case '\t':case '\r': case '\n': ++p; break; default: buffer.clear(); state = column_state::label; break; } break; } case column_state::label: { switch (*p) { case ',': cont.push_back(buffer); buffer.clear(); ++p; state = column_state::sequence; break; default: buffer.push_back(*p); ++p; break; } break; } } } if (state == column_state::label) { cont.push_back(buffer); buffer.clear(); } } // namespace detail template void parse_column_types(const std::basic_string& types, Container& column_types) { const std::map,csv_column_type> type_dictionary = { {JSONCONS_STRING_VIEW_CONSTANT(CharT,"string"),csv_column_type::string_t}, {JSONCONS_STRING_VIEW_CONSTANT(CharT,"integer"),csv_column_type::integer_t}, {JSONCONS_STRING_VIEW_CONSTANT(CharT,"float"),csv_column_type::float_t}, {JSONCONS_STRING_VIEW_CONSTANT(CharT,"boolean"),csv_column_type::boolean_t} }; column_state state = column_state::sequence; int depth = 0; std::basic_string buffer; auto p = types.begin(); while (p != types.end()) { switch (state) { case column_state::sequence: { switch (*p) { case ' ': case '\t':case '\r': case '\n': ++p; break; case '[': ++depth; ++p; break; case ']': JSONCONS_ASSERT(depth > 0); --depth; ++p; break; case '*': { JSONCONS_ASSERT(column_types.size() != 0); std::size_t offset = 0; std::size_t level = column_types.size() > 0 ? column_types.back().level: 0; if (level > 0) { for (auto it = column_types.rbegin(); it != column_types.rend() && level == (*it).level; ++it) { ++offset; } } else { offset = 1; } column_types.emplace_back(csv_column_type::repeat_t,depth,offset); ++p; break; } default: buffer.clear(); state = column_state::label; break; } break; } case column_state::label: { switch (*p) { case '*': { auto it = type_dictionary.find(buffer); if (it != type_dictionary.end()) { column_types.emplace_back((*it).second,depth); buffer.clear(); } else { JSONCONS_ASSERT(false); } state = column_state::sequence; break; } case ',': { auto it = type_dictionary.find(buffer); if (it != type_dictionary.end()) { column_types.emplace_back((*it).second,depth); buffer.clear(); } else { JSONCONS_ASSERT(false); } ++p; state = column_state::sequence; break; } case ']': { JSONCONS_ASSERT(depth > 0); auto it = type_dictionary.find(buffer); if (it != type_dictionary.end()) { column_types.emplace_back((*it).second,depth); buffer.clear(); } else { JSONCONS_ASSERT(false); } --depth; ++p; state = column_state::sequence; break; } default: { buffer.push_back(*p); ++p; break; } } break; } } } if (state == column_state::label) { auto it = type_dictionary.find(buffer); if (it != type_dictionary.end()) { column_types.emplace_back((*it).second,depth); buffer.clear(); } else { JSONCONS_ASSERT(false); } } } } // namespace detail template class basic_csv_options; template class basic_csv_options_common { friend class basic_csv_options; public: using char_type = CharT; using string_type = std::basic_string; private: char_type field_delimiter_{','}; char_type quote_char_{'\"'}; char_type quote_escape_char_{'\"'}; char_type subfield_delimiter_{char_type{}}; bool flat_:1; bool enable_nan_to_num_:1; bool enable_inf_to_num_:1; bool enable_neginf_to_num_:1; bool enable_nan_to_str_:1; bool enable_inf_to_str_:1; bool enable_neginf_to_str_:1; bool enable_str_to_nan_:1; bool enable_str_to_inf_:1; bool enable_str_to_neginf_:1; string_type nan_to_num_; string_type inf_to_num_; string_type neginf_to_num_; string_type nan_to_str_; string_type inf_to_str_; string_type neginf_to_str_; string_type column_names_; std::vector> column_mapping_; std::size_t max_nesting_depth_{1024}; protected: basic_csv_options_common() : flat_{true}, enable_nan_to_num_{false}, enable_inf_to_num_{false}, enable_neginf_to_num_{false}, enable_nan_to_str_{false}, enable_inf_to_str_{false}, enable_neginf_to_str_{false}, enable_str_to_nan_{false}, enable_str_to_inf_{false}, enable_str_to_neginf_{false} { } basic_csv_options_common(const basic_csv_options_common&) = default; basic_csv_options_common& operator=(const basic_csv_options_common&) = default; //basic_csv_options_common& operator=(basic_csv_options_common&&) = default; virtual ~basic_csv_options_common() = default; public: bool flat() const { return flat_; } std::size_t max_nesting_depth() const { return max_nesting_depth_; } char_type field_delimiter() const { return field_delimiter_; } const char_type subfield_delimiter() const { return subfield_delimiter_; } char_type quote_char() const { return quote_char_; } char_type quote_escape_char() const { return quote_escape_char_; } const string_type& column_names() const { return column_names_; } const std::vector>& column_mapping() const { return column_mapping_; } bool enable_nan_to_num() const { return enable_nan_to_num_; } bool enable_inf_to_num() const { return enable_inf_to_num_; } bool enable_neginf_to_num() const { return enable_neginf_to_num_ || enable_inf_to_num_; } bool enable_nan_to_str() const { return enable_nan_to_str_; } bool enable_str_to_nan() const { return enable_str_to_nan_; } bool enable_inf_to_str() const { return enable_inf_to_str_; } bool enable_str_to_inf() const { return enable_str_to_inf_; } bool enable_neginf_to_str() const { return enable_neginf_to_str_ || enable_inf_to_str_; } bool enable_str_to_neginf() const { return enable_str_to_neginf_ || enable_str_to_inf_; } string_type nan_to_num() const { return nan_to_num_; } string_type inf_to_num() const { return inf_to_num_; } string_type neginf_to_num() const { if (enable_neginf_to_num_) { return neginf_to_num_; } else if (enable_inf_to_num_) { string_type s; s.push_back('-'); s.append(inf_to_num_); return s; } else { return neginf_to_num_; } } string_type nan_to_str() const { return nan_to_str_; } string_type inf_to_str() const { return inf_to_str_; } string_type neginf_to_str() const { if (enable_neginf_to_str_) { return neginf_to_str_; } else if (enable_inf_to_str_) { string_type s; s.push_back('-'); s.append(inf_to_str_); return s; } else { return neginf_to_str_; // empty string } } }; template class basic_csv_decode_options : public virtual basic_csv_options_common { friend class basic_csv_options; using super_type = basic_csv_options_common; public: using typename super_type::char_type; using typename super_type::string_type; private: bool assume_header_:1; bool ignore_empty_values_:1; bool ignore_empty_lines_:1; bool trim_leading_:1; bool trim_trailing_:1; bool trim_leading_inside_quotes_:1; bool trim_trailing_inside_quotes_:1; bool unquoted_empty_value_is_null_:1; bool infer_types_:1; bool lossless_number_:1; char_type comment_starter_{'\0'}; csv_mapping_kind mapping_kind_{}; std::size_t header_lines_{0}; std::size_t max_lines_{(std::numeric_limits::max)()}; string_type column_types_; string_type column_defaults_; public: basic_csv_decode_options() : assume_header_(false), ignore_empty_values_(false), ignore_empty_lines_(true), trim_leading_(false), trim_trailing_(false), trim_leading_inside_quotes_(false), trim_trailing_inside_quotes_(false), unquoted_empty_value_is_null_(false), infer_types_(true), lossless_number_(false) {} basic_csv_decode_options(const basic_csv_decode_options& other) = default; basic_csv_decode_options(basic_csv_decode_options&& other) noexcept : super_type(std::move(other)), assume_header_(other.assume_header_), ignore_empty_values_(other.ignore_empty_values_), ignore_empty_lines_(other.ignore_empty_lines_), trim_leading_(other.trim_leading_), trim_trailing_(other.trim_trailing_), trim_leading_inside_quotes_(other.trim_leading_inside_quotes_), trim_trailing_inside_quotes_(other.trim_trailing_inside_quotes_), unquoted_empty_value_is_null_(other.unquoted_empty_value_is_null_), infer_types_(other.infer_types_), lossless_number_(other.lossless_number_), comment_starter_(other.comment_starter_), mapping_kind_(other.mapping_kind_), header_lines_(other.header_lines_), max_lines_(other.max_lines_), column_types_(std::move(other.column_types_)), column_defaults_(std::move(other.column_defaults_)) {} protected: basic_csv_decode_options& operator=(const basic_csv_decode_options& other) = default; basic_csv_decode_options& operator=(basic_csv_decode_options&& other) = default; public: std::size_t header_lines() const { return (assume_header_ && header_lines_ <= 1) ? 1 : header_lines_; } bool assume_header() const { return assume_header_; } bool ignore_empty_values() const { return ignore_empty_values_; } bool ignore_empty_lines() const { return ignore_empty_lines_; } bool trim_leading() const { return trim_leading_; } bool trim_trailing() const { return trim_trailing_; } bool trim_leading_inside_quotes() const { return trim_leading_inside_quotes_; } bool trim_trailing_inside_quotes() const { return trim_trailing_inside_quotes_; } bool trim() const { return trim_leading_ && trim_trailing_; } bool trim_inside_quotes() const { return trim_leading_inside_quotes_ && trim_trailing_inside_quotes_; } bool unquoted_empty_value_is_null() const { return unquoted_empty_value_is_null_; } bool infer_types() const { return infer_types_; } bool lossless_number() const { return lossless_number_; } char_type comment_starter() const { return comment_starter_; } csv_mapping_kind mapping_kind() const { return mapping_kind_ != csv_mapping_kind() ? mapping_kind_ : (assume_header() || this->column_names().size() > 0 ? csv_mapping_kind::n_objects : csv_mapping_kind::n_rows); } std::size_t max_lines() const { return max_lines_; } string_type column_types() const { return column_types_; } string_type column_defaults() const { return column_defaults_; } }; template class basic_csv_encode_options : public virtual basic_csv_options_common { friend class basic_csv_options; using super_type = basic_csv_options_common; public: using typename super_type::char_type; using typename super_type::string_type; private: quote_style_kind quote_style_{quote_style_kind::minimal}; float_chars_format float_format_{float_chars_format::general}; int8_t precision_{0}; string_type line_delimiter_; public: basic_csv_encode_options() { line_delimiter_.push_back('\n'); } basic_csv_encode_options(const basic_csv_encode_options& other) = default; basic_csv_encode_options(basic_csv_encode_options&& other) noexcept : super_type(std::move(other)), quote_style_(other.quote_style_), float_format_(other.float_format_), precision_(other.precision_), line_delimiter_(std::move(other.line_delimiter_)) { } protected: basic_csv_encode_options& operator=(const basic_csv_encode_options& other) = default; basic_csv_encode_options& operator=(basic_csv_encode_options&& other) = default; public: quote_style_kind quote_style() const { return quote_style_; } float_chars_format float_format() const { return float_format_; } int8_t precision() const { return precision_; } string_type line_delimiter() const { return line_delimiter_; } }; template class basic_csv_options final : public basic_csv_decode_options, public basic_csv_encode_options { using char_type = CharT; using string_type = std::basic_string; public: using basic_csv_decode_options::enable_str_to_nan; using basic_csv_decode_options::enable_str_to_inf; using basic_csv_decode_options::enable_str_to_neginf; using basic_csv_decode_options::nan_to_str; using basic_csv_decode_options::inf_to_str; using basic_csv_decode_options::neginf_to_str; using basic_csv_decode_options::nan_to_num; using basic_csv_decode_options::inf_to_num; using basic_csv_decode_options::neginf_to_num; using basic_csv_decode_options::flat; using basic_csv_decode_options::max_nesting_depth; using basic_csv_decode_options::field_delimiter; using basic_csv_decode_options::subfield_delimiter; using basic_csv_decode_options::quote_char; using basic_csv_decode_options::quote_escape_char; using basic_csv_decode_options::column_names; using basic_csv_decode_options::column_mapping; using basic_csv_decode_options::header_lines; using basic_csv_decode_options::assume_header; using basic_csv_decode_options::ignore_empty_values; using basic_csv_decode_options::ignore_empty_lines; using basic_csv_decode_options::trim_leading; using basic_csv_decode_options::trim_trailing; using basic_csv_decode_options::trim_leading_inside_quotes; using basic_csv_decode_options::trim_trailing_inside_quotes; using basic_csv_decode_options::trim; using basic_csv_decode_options::trim_inside_quotes; using basic_csv_decode_options::unquoted_empty_value_is_null; using basic_csv_decode_options::infer_types; using basic_csv_decode_options::lossless_number; using basic_csv_decode_options::comment_starter; using basic_csv_decode_options::mapping_kind; using basic_csv_decode_options::max_lines; using basic_csv_decode_options::column_types; using basic_csv_decode_options::column_defaults; using basic_csv_encode_options::float_format; using basic_csv_encode_options::precision; using basic_csv_encode_options::line_delimiter; using basic_csv_encode_options::quote_style; static constexpr size_t default_indent = 4; // Constructors basic_csv_options() = default; basic_csv_options(const basic_csv_options&) = default; basic_csv_options(basic_csv_options&&) = default; basic_csv_options& operator=(const basic_csv_options&) = default; basic_csv_options& operator=(basic_csv_options&&) = default; basic_csv_options& float_format(float_chars_format value) { this->float_format_ = value; return *this; } basic_csv_options& precision(int8_t value) { this->precision_ = value; return *this; } basic_csv_options& header_lines(std::size_t value) { this->header_lines_ = value; return *this; } basic_csv_options& assume_header(bool value) { this->assume_header_ = value; return *this; } basic_csv_options& ignore_empty_values(bool value) { this->ignore_empty_values_ = value; return *this; } basic_csv_options& ignore_empty_lines(bool value) { this->ignore_empty_lines_ = value; return *this; } basic_csv_options& trim_leading(bool value) { this->trim_leading_ = value; return *this; } basic_csv_options& trim_trailing(bool value) { this->trim_trailing_ = value; return *this; } basic_csv_options& trim_leading_inside_quotes(bool value) { this->trim_leading_inside_quotes_ = value; return *this; } basic_csv_options& trim_trailing_inside_quotes(bool value) { this->trim_trailing_inside_quotes_ = value; return *this; } basic_csv_options& trim(bool value) { this->trim_leading_ = value; this->trim_trailing_ = value; return *this; } basic_csv_options& trim_inside_quotes(bool value) { this->trim_leading_inside_quotes_ = value; this->trim_trailing_inside_quotes_ = value; return *this; } basic_csv_options& unquoted_empty_value_is_null(bool value) { this->unquoted_empty_value_is_null_ = value; return *this; } basic_csv_options& column_names(const string_type& value) { this->column_names_ = value; return *this; } basic_csv_options& column_mapping(const std::vector>& value) { this->column_mapping_ = value; return *this; } basic_csv_options& column_types(const string_type& value) { this->column_types_ = value; return *this; } basic_csv_options& column_defaults(const string_type& value) { this->column_defaults_ = value; return *this; } basic_csv_options& flat(bool value) { this->flat_ = value; return *this; } basic_csv_options& max_nesting_depth(std::size_t value) { this->max_nesting_depth_ = value; return *this; } basic_csv_options& field_delimiter(char_type value) { this->field_delimiter_ = value; return *this; } basic_csv_options& subfield_delimiter(char_type value) { this->subfield_delimiter_ = value; return *this; } basic_csv_options& line_delimiter(const string_type& value) { this->line_delimiter_ = value; return *this; } basic_csv_options& quote_char(char_type value) { this->quote_char_ = value; return *this; } basic_csv_options& infer_types(bool value) { this->infer_types_ = value; return *this; } basic_csv_options& lossless_number(bool value) { this->lossless_number_ = value; return *this; } basic_csv_options& quote_escape_char(char_type value) { this->quote_escape_char_ = value; return *this; } basic_csv_options& comment_starter(char_type value) { this->comment_starter_ = value; return *this; } basic_csv_options& quote_style(quote_style_kind value) { this->quote_style_ = value; return *this; } basic_csv_options& mapping_kind(csv_mapping_kind value) { this->mapping_kind_ = value; return *this; } basic_csv_options& max_lines(std::size_t value) { this->max_lines_ = value; return *this; } basic_csv_options& nan_to_num(const string_type& value) { this->enable_nan_to_num_ = true; this->nan_to_str_.clear(); this->nan_to_num_ = value; return *this; } basic_csv_options& inf_to_num(const string_type& value) { this->enable_inf_to_num_ = true; this->inf_to_str_.clear(); this->inf_to_num_ = value; return *this; } basic_csv_options& neginf_to_num(const string_type& value) { this->enable_neginf_to_num_ = true; this->neginf_to_str_.clear(); this->neginf_to_num_ = value; return *this; } basic_csv_options& nan_to_str(const string_type& value, bool enable_inverse = true) { this->enable_nan_to_str_ = true; this->enable_str_to_nan_ = enable_inverse; this->nan_to_num_.clear(); this->nan_to_str_ = value; return *this; } basic_csv_options& inf_to_str(const string_type& value, bool enable_inverse = true) { this->enable_inf_to_str_ = true; this->enable_inf_to_str_ = enable_inverse; this->inf_to_num_.clear(); this->inf_to_str_ = value; return *this; } basic_csv_options& neginf_to_str(const string_type& value, bool enable_inverse = true) { this->enable_neginf_to_str_ = true; this->enable_neginf_to_str_ = enable_inverse; this->neginf_to_num_.clear(); this->neginf_to_str_ = value; return *this; } }; using csv_options = basic_csv_options; using wcsv_options = basic_csv_options; } // namespace jsonpath } // namespace jsoncons #endif // JSONCONS_EXT_CSV_CSV_OPTIONS_HPP jsoncons-1.3.2/include/jsoncons_ext/csv/csv_parser.hpp000066400000000000000000002536761477700171100232130ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_CSV_CSV_PARSER_HPP #define JSONCONS_CSV_CSV_PARSER_HPP #include #include #include #include #include // std::allocator #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace csv { enum class csv_mode { initial, header, data, subfields }; enum class csv_parse_state { start, cr, expect_comment_or_record, expect_record, end_record, no_more_records, comment, between_values, quoted_string, unquoted_string, before_unquoted_string, escaped_value, minus, zero, integer, fraction, exp1, exp2, exp3, accept, before_unquoted_field, before_unquoted_field_tail, before_unquoted_field_tail1, before_last_unquoted_field, before_last_unquoted_field_tail, before_unquoted_subfield, before_unquoted_subfield_tail, before_quoted_subfield, before_quoted_subfield_tail, before_quoted_field, before_quoted_field_tail, before_last_quoted_field, before_last_quoted_field_tail, done }; enum class cached_state { begin_object, end_object, begin_array, end_array, name, item, done }; struct default_csv_parsing { bool operator()(csv_errc, const ser_context&) noexcept { return false; } }; namespace detail { template class parse_event { using temp_allocator_type = TempAllocator; using string_view_type = typename basic_json_visitor::string_view_type; using char_allocator_type = typename std::allocator_traits:: template rebind_alloc; using byte_allocator_type = typename std::allocator_traits:: template rebind_alloc; using string_type = std::basic_string,char_allocator_type>; using byte_string_type = basic_byte_string; staj_event_type event_type; string_type string_value; byte_string_type byte_string_value; union { bool bool_value; int64_t int64_value; uint64_t uint64_value; double double_value; }; semantic_tag tag; public: parse_event(staj_event_type event_type, semantic_tag tag, const TempAllocator& alloc) : event_type(event_type), string_value(alloc), byte_string_value(alloc), tag(tag) { } parse_event(const string_view_type& value, semantic_tag tag, const TempAllocator& alloc) : event_type(staj_event_type::string_value), string_value(value.data(),value.length(),alloc), byte_string_value(alloc), tag(tag) { } parse_event(const byte_string_view& value, semantic_tag tag, const TempAllocator& alloc) : event_type(staj_event_type::byte_string_value), string_value(alloc), byte_string_value(value.data(),value.size(),alloc), tag(tag) { } parse_event(bool value, semantic_tag tag, const TempAllocator& alloc) : event_type(staj_event_type::bool_value), string_value(alloc), byte_string_value(alloc), bool_value(value), tag(tag) { } parse_event(int64_t value, semantic_tag tag, const TempAllocator& alloc) : event_type(staj_event_type::int64_value), string_value(alloc), byte_string_value(alloc), int64_value(value), tag(tag) { } parse_event(uint64_t value, semantic_tag tag, const TempAllocator& alloc) : event_type(staj_event_type::uint64_value), string_value(alloc), byte_string_value(alloc), uint64_value(value), tag(tag) { } parse_event(double value, semantic_tag tag, const TempAllocator& alloc) : event_type(staj_event_type::double_value), string_value(alloc), byte_string_value(alloc), double_value(value), tag(tag) { } parse_event(const parse_event&) = default; parse_event(parse_event&&) = default; parse_event& operator=(const parse_event&) = default; parse_event& operator=(parse_event&&) = default; void replay(basic_json_visitor& visitor) const { switch (event_type) { case staj_event_type::begin_array: visitor.begin_array(tag, ser_context()); break; case staj_event_type::end_array: visitor.end_array(ser_context()); break; case staj_event_type::string_value: visitor.string_value(string_value, tag, ser_context()); break; case staj_event_type::byte_string_value: visitor.byte_string_value(byte_string_value, tag, ser_context()); break; case staj_event_type::null_value: visitor.null_value(tag, ser_context()); break; case staj_event_type::bool_value: visitor.bool_value(bool_value, tag, ser_context()); break; case staj_event_type::int64_value: visitor.int64_value(int64_value, tag, ser_context()); break; case staj_event_type::uint64_value: visitor.uint64_value(uint64_value, tag, ser_context()); break; case staj_event_type::double_value: visitor.double_value(double_value, tag, ser_context()); break; default: break; } } }; template class m_columns_filter : public basic_json_visitor { public: using string_view_type = typename basic_json_visitor::string_view_type; using char_type = CharT; using temp_allocator_type = TempAllocator; using char_allocator_type = typename std::allocator_traits:: template rebind_alloc; using string_type = std::basic_string,char_allocator_type>; using string_allocator_type = typename std::allocator_traits:: template rebind_alloc; using parse_event_allocator_type = typename std::allocator_traits:: template rebind_alloc>; using parse_event_vector_type = std::vector, parse_event_allocator_type>; using parse_event_vector_allocator_type = typename std::allocator_traits:: template rebind_alloc; private: TempAllocator alloc_; std::size_t name_index_{0}; int level_{0}; int level2_{0}; cached_state state_{cached_state::begin_object}; std::size_t column_index_{0}; std::size_t row_index_{0}; std::vector column_names_; std::vector cached_events_; public: m_columns_filter(const TempAllocator& alloc) : alloc_(alloc), column_names_(alloc), cached_events_(alloc) { } void reset() { name_index_ = 0; level_ = 0; level2_ = 0; state_ = cached_state::begin_object; column_index_ = 0; row_index_ = 0; column_names_.clear(); cached_events_.clear(); } bool done() const { return state_ == cached_state::done; } void initialize(const std::vector& column_names) { for (const auto& name : column_names) { column_names_.push_back(name); cached_events_.emplace_back(alloc_); } name_index_ = 0; level_ = 0; level2_ = 0; column_index_ = 0; row_index_ = 0; state_ = cached_state::begin_object; } void skip_column() { ++name_index_; } int level() const { return static_cast(level_); } bool replay_parse_events(basic_json_visitor& visitor, bool cursor_mode, int mark_level) { bool more = true; while (more) { switch (state_) { case cached_state::begin_object: visitor.begin_object(semantic_tag::none, ser_context()); ++level_; more = !cursor_mode; column_index_ = 0; state_ = cached_state::name; break; case cached_state::end_object: visitor.end_object(ser_context()); more = !cursor_mode; if (level_ == mark_level) { more = false; } --level_; state_ = cached_state::done; break; case cached_state::name: if (column_index_ < column_names_.size()) { visitor.key(column_names_[column_index_], ser_context()); more = !cursor_mode; state_ = cached_state::begin_array; } else { state_ = cached_state::end_object; } break; case cached_state::begin_array: visitor.begin_array(semantic_tag::none, ser_context()); ++level_; more = !cursor_mode; row_index_ = 0; state_ = cached_state::item; break; case cached_state::end_array: visitor.end_array(ser_context()); more = !cursor_mode; if (level_ == mark_level) { more = false; } --level_; ++column_index_; state_ = cached_state::name; break; case cached_state::item: if (row_index_ < cached_events_[column_index_].size()) { cached_events_[column_index_][row_index_].replay(visitor); more = !cursor_mode; ++row_index_; } else { state_ = cached_state::end_array; } break; default: more = false; break; } } return more; } void visit_flush() override { } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag, const ser_context&, std::error_code& ec) override { ec = csv_errc::invalid_parse_state; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context&, std::error_code& ec) override { ec = csv_errc::invalid_parse_state; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag tag, const ser_context&, std::error_code&) override { if (name_index_ < column_names_.size()) { cached_events_[name_index_].emplace_back(staj_event_type::begin_array, tag, alloc_); ++level2_; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context&, std::error_code&) override { if (level2_ > 0) { cached_events_[name_index_].emplace_back(staj_event_type::end_array, semantic_tag::none, alloc_); ++name_index_; --level2_; } else { name_index_ = 0; } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type&, const ser_context&, std::error_code& ec) override { ec = csv_errc::invalid_parse_state; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag tag, const ser_context&, std::error_code&) override { if (name_index_ < column_names_.size()) { cached_events_[name_index_].emplace_back(staj_event_type::null_value, tag, alloc_); if (level2_ == 0) { ++name_index_; } } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& value, semantic_tag tag, const ser_context&, std::error_code&) override { if (name_index_ < column_names_.size()) { cached_events_[name_index_].emplace_back(value, tag, alloc_); if (level2_ == 0) { ++name_index_; } } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& value, semantic_tag tag, const ser_context&, std::error_code&) override { if (name_index_ < column_names_.size()) { cached_events_[name_index_].emplace_back(value, tag, alloc_); if (level2_ == 0) { ++name_index_; } } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_double(double value, semantic_tag tag, const ser_context&, std::error_code&) override { if (name_index_ < column_names_.size()) { cached_events_[name_index_].emplace_back(value, tag, alloc_); if (level2_ == 0) { ++name_index_; } } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t value, semantic_tag tag, const ser_context&, std::error_code&) override { if (name_index_ < column_names_.size()) { cached_events_[name_index_].emplace_back(value, tag, alloc_); if (level2_ == 0) { ++name_index_; } } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t value, semantic_tag tag, const ser_context&, std::error_code&) override { if (name_index_ < column_names_.size()) { cached_events_[name_index_].emplace_back(value, tag, alloc_); if (level2_ == 0) { ++name_index_; } } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool value, semantic_tag tag, const ser_context&, std::error_code&) override { if (name_index_ < column_names_.size()) { cached_events_[name_index_].emplace_back(value, tag, alloc_); if (level2_ == 0) { ++name_index_; } } JSONCONS_VISITOR_RETURN; } }; } // namespace detail template > class basic_csv_parser : public ser_context { public: using string_view_type = jsoncons::basic_string_view; using char_type = CharT; private: struct string_maps_to_double { string_view_type s; bool operator()(const std::pair& val) const { return val.first == s; } }; using temp_allocator_type = TempAllocator; typedef typename std::allocator_traits:: template rebind_alloc char_allocator_type; using string_type = std::basic_string,char_allocator_type>; typedef typename std::allocator_traits:: template rebind_alloc string_allocator_type; typedef typename std::allocator_traits:: template rebind_alloc csv_mode_allocator_type; typedef typename std::allocator_traits:: template rebind_alloc csv_type_info_allocator_type; typedef typename std::allocator_traits:: template rebind_alloc> string_vector_allocator_type; typedef typename std::allocator_traits:: template rebind_alloc csv_parse_state_allocator_type; static constexpr int default_depth = 3; temp_allocator_type alloc_; csv_parse_state state_; std::function err_handler_; std::size_t column_{1}; std::size_t line_{1}; int nesting_depth_{default_depth}; bool assume_header_; char_type comment_starter_; char_type field_delimiter_; std::size_t header_lines_; bool ignore_empty_values_; bool ignore_empty_lines_; bool infer_types_; bool lossless_number_; csv_mapping_kind mapping_kind_; std::size_t max_lines_; char_type quote_char_; char_type quote_escape_char_; char_type subfield_delimiter_; bool trim_leading_; bool trim_leading_inside_quotes_; bool trim_trailing_; bool trim_trailing_inside_quotes_; bool unquoted_empty_value_is_null_; std::size_t min_column_names_{0}; std::size_t column_index_{0}; int level_{0}; std::size_t depth_{0}; std::size_t offset_{0}; jsoncons::detail::chars_to to_double_; const CharT* begin_input_{nullptr}; const CharT* input_end_{nullptr}; const CharT* input_ptr_{nullptr}; bool more_{true}; std::size_t header_line_{1}; bool cursor_mode_{false}; bool actual_cursor_mode_{false}; int mark_level_{0}; std::size_t header_line_offset_{0}; detail::m_columns_filter m_columns_filter_; std::vector stack_; std::vector column_names_; std::vector column_types_; std::vector column_defaults_; std::vector state_stack_; string_type buffer_; std::vector,double>> string_double_map_; public: basic_csv_parser(const TempAllocator& alloc = TempAllocator()) : basic_csv_parser(basic_csv_decode_options(), default_csv_parsing(), alloc) { } basic_csv_parser(const basic_csv_decode_options& options, const TempAllocator& alloc = TempAllocator()) : basic_csv_parser(options, default_csv_parsing(), alloc) { } basic_csv_parser(std::function err_handler, const TempAllocator& alloc = TempAllocator()) : basic_csv_parser(basic_csv_decode_options(), err_handler, alloc) { } basic_csv_parser(const basic_csv_decode_options& options, std::function err_handler, const TempAllocator& alloc = TempAllocator()) : alloc_(alloc), state_(csv_parse_state::start), err_handler_(err_handler), assume_header_(options.assume_header()), comment_starter_(options.comment_starter()), field_delimiter_(options.field_delimiter()), header_lines_(options.header_lines()), ignore_empty_values_(options.ignore_empty_values()), ignore_empty_lines_(options.ignore_empty_lines()), infer_types_(options.infer_types()), lossless_number_(options.lossless_number()), mapping_kind_(options.mapping_kind()), max_lines_(options.max_lines()), quote_char_(options.quote_char()), quote_escape_char_(options.quote_escape_char()), subfield_delimiter_(options.subfield_delimiter()), trim_leading_(options.trim_leading()), trim_leading_inside_quotes_(options.trim_leading_inside_quotes()), trim_trailing_(options.trim_trailing()), trim_trailing_inside_quotes_(options.trim_trailing_inside_quotes()), unquoted_empty_value_is_null_(options.unquoted_empty_value_is_null()), m_columns_filter_(alloc), stack_(alloc), column_names_(alloc), column_types_(alloc), column_defaults_(alloc), state_stack_(alloc), buffer_(alloc) { if (options.enable_str_to_nan()) { string_double_map_.emplace_back(options.nan_to_str(),std::nan("")); } if (options.enable_str_to_inf()) { string_double_map_.emplace_back(options.inf_to_str(),std::numeric_limits::infinity()); } if (options.enable_str_to_neginf()) { string_double_map_.emplace_back(options.neginf_to_str(),-std::numeric_limits::infinity()); } jsoncons::csv::detail::parse_column_types(options.column_types(), column_types_); jsoncons::csv::detail::parse_column_names(options.column_defaults(), column_defaults_); jsoncons::csv::detail::parse_column_names(options.column_names(), column_names_); min_column_names_ = column_names_.size(); initialize(); } ~basic_csv_parser() noexcept { } void cursor_mode(bool value) { actual_cursor_mode_ = value; cursor_mode_ = (mapping_kind_ == csv_mapping_kind::m_columns) ? false : value; } int level() const { return level_; } int mark_level() const { return mark_level_; } void mark_level(int value) { mark_level_ = value; } bool done() const { return state_ == csv_parse_state::done; } bool accept() const { return state_ == csv_parse_state::accept || state_ == csv_parse_state::done; } bool stopped() const { return !more_; } bool source_exhausted() const { return input_ptr_ == input_end_; } const std::vector& column_labels() const { return column_names_; } void reinitialize() { state_ = csv_parse_state::start; column_ = 1; line_ = 1; nesting_depth_ = default_depth; column_index_ = 0; level_ = 0; depth_ = 0; offset_ = 0; begin_input_ = nullptr; input_end_ = nullptr; input_ptr_ = nullptr; more_ = true; header_line_ = 1; m_columns_filter_.reset(); stack_.clear(); column_names_.erase(column_names_.begin() + min_column_names_, column_names_.end()); state_stack_.clear(); buffer_.clear(); initialize(); } void restart() { more_ = true; } void parse_some(basic_json_visitor& visitor) { std::error_code ec; parse_some(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,line_,column_)); } } void parse_some(basic_json_visitor& visitor, std::error_code& ec) { basic_json_visitor& local_visitor = (mapping_kind_ == csv_mapping_kind::m_columns) ? m_columns_filter_ : visitor; switch (mapping_kind_) { case csv_mapping_kind::m_columns: cursor_mode_ = false; break; default: break; } const CharT* local_input_end = input_end_; if (input_ptr_ == local_input_end && more_) { switch (state_) { case csv_parse_state::start: ec = csv_errc::source_error; more_ = false; return; case csv_parse_state::before_unquoted_field: case csv_parse_state::before_last_unquoted_field: end_unquoted_string_value(local_visitor, ec); state_ = csv_parse_state::before_last_unquoted_field_tail; break; case csv_parse_state::before_last_unquoted_field_tail: if (stack_.back() == csv_mode::subfields) { stack_.pop_back(); local_visitor.end_array(*this, ec); more_ = !cursor_mode_; if (mapping_kind_ != csv_mapping_kind::m_columns) { if (level() == mark_level_) { more_ = false; } } --level_; } ++column_index_; state_ = csv_parse_state::end_record; break; case csv_parse_state::before_unquoted_string: buffer_.clear(); JSONCONS_FALLTHROUGH; case csv_parse_state::unquoted_string: if (trim_leading_ || trim_trailing_) { trim_string_buffer(trim_leading_,trim_trailing_); } if (ignore_empty_values_ && buffer_.empty()) { state_ = csv_parse_state::end_record; } else { before_value(local_visitor, ec); state_ = csv_parse_state::before_unquoted_field; } break; case csv_parse_state::before_last_quoted_field: end_quoted_string_value(local_visitor, ec); ++column_index_; state_ = csv_parse_state::end_record; break; case csv_parse_state::escaped_value: if (quote_escape_char_ == quote_char_) { if (!(ignore_empty_values_ && buffer_.empty())) { before_value(local_visitor, ec); ++column_; state_ = csv_parse_state::before_last_quoted_field; } else { state_ = csv_parse_state::end_record; } } else { ec = csv_errc::invalid_escaped_char; more_ = false; return; } break; case csv_parse_state::end_record: if (column_index_ > 0) { end_record(local_visitor, ec); } state_ = csv_parse_state::no_more_records; break; case csv_parse_state::no_more_records: switch (stack_.back()) { case csv_mode::header: stack_.pop_back(); break; case csv_mode::data: stack_.pop_back(); break; default: break; } local_visitor.end_array(*this, ec); more_ = !cursor_mode_; if (mapping_kind_ != csv_mapping_kind::m_columns) { if (level() == mark_level_) { more_ = false; } } --level_; if (mapping_kind_ == csv_mapping_kind::m_columns) { if (!m_columns_filter_.done()) { more_ = m_columns_filter_.replay_parse_events(visitor, actual_cursor_mode_, mark_level_); } else { state_ = csv_parse_state::accept; } } else { state_ = csv_parse_state::accept; } break; case csv_parse_state::accept: if (!(stack_.size() == 1 && stack_.back() == csv_mode::initial)) { err_handler_(csv_errc::unexpected_eof, *this); ec = csv_errc::unexpected_eof; more_ = false; return; } stack_.pop_back(); local_visitor.flush(); state_ = csv_parse_state::done; more_ = false; return; default: state_ = csv_parse_state::end_record; break; } } for (; (input_ptr_ < local_input_end) && more_;) { CharT curr_char = *input_ptr_; switch (state_) { case csv_parse_state::cr: ++line_; column_ = 1; switch (*input_ptr_) { case '\n': ++input_ptr_; state_ = pop_state(); break; default: state_ = pop_state(); break; } break; case csv_parse_state::start: if (mapping_kind_ != csv_mapping_kind::m_columns) { local_visitor.begin_array(semantic_tag::none, *this, ec); more_ = !cursor_mode_; ++level_; } if (assume_header_ && mapping_kind_ == csv_mapping_kind::n_rows && !column_names_.empty()) { column_index_ = 0; local_visitor.begin_array(semantic_tag::none, *this, ec); ++level_; more_ = !cursor_mode_; state_ = csv_parse_state::expect_comment_or_record; } else { state_ = csv_parse_state::expect_comment_or_record; } break; case csv_parse_state::comment: switch (curr_char) { case '\n': { ++line_; if (stack_.back() == csv_mode::header) { ++header_line_offset_; } column_ = 1; state_ = csv_parse_state::expect_comment_or_record; break; } case '\r': ++line_; if (stack_.back() == csv_mode::header) { ++header_line_offset_; } column_ = 1; state_ = csv_parse_state::expect_comment_or_record; push_state(state_); state_ = csv_parse_state::cr; break; default: ++column_; break; } ++input_ptr_; break; case csv_parse_state::expect_comment_or_record: buffer_.clear(); if (curr_char == comment_starter_) { state_ = csv_parse_state::comment; ++column_; ++input_ptr_; } else { state_ = csv_parse_state::expect_record; } break; case csv_parse_state::quoted_string: { if (curr_char == quote_escape_char_) { state_ = csv_parse_state::escaped_value; } else if (curr_char == quote_char_) { state_ = csv_parse_state::between_values; } else { buffer_.push_back(static_cast(curr_char)); } } ++column_; ++input_ptr_; break; case csv_parse_state::escaped_value: { if (curr_char == quote_char_) { buffer_.push_back(static_cast(curr_char)); state_ = csv_parse_state::quoted_string; ++column_; ++input_ptr_; } else if (quote_escape_char_ == quote_char_) { state_ = csv_parse_state::between_values; } else { ec = csv_errc::invalid_escaped_char; more_ = false; return; } } break; case csv_parse_state::between_values: switch (curr_char) { case '\r': case '\n': { if (trim_leading_ || trim_trailing_) { trim_string_buffer(trim_leading_,trim_trailing_); } if (!(ignore_empty_values_ && buffer_.empty())) { before_value(local_visitor, ec); state_ = csv_parse_state::before_last_quoted_field; } else { state_ = csv_parse_state::end_record; } break; } default: if (curr_char == field_delimiter_) { if (trim_leading_ || trim_trailing_) { trim_string_buffer(trim_leading_,trim_trailing_); } before_value(local_visitor, ec); state_ = csv_parse_state::before_quoted_field; } else if (subfield_delimiter_ != char_type() && curr_char == subfield_delimiter_) { if (trim_leading_ || trim_trailing_) { trim_string_buffer(trim_leading_,trim_trailing_); } before_value(local_visitor, ec); state_ = csv_parse_state::before_quoted_subfield; } else if (curr_char == ' ' || curr_char == '\t') { ++column_; ++input_ptr_; } else { ec = csv_errc::unexpected_char_between_fields; more_ = false; return; } break; } break; case csv_parse_state::before_unquoted_string: { buffer_.clear(); state_ = csv_parse_state::unquoted_string; break; } case csv_parse_state::before_unquoted_field: end_unquoted_string_value(local_visitor, ec); state_ = csv_parse_state::before_unquoted_field_tail; break; case csv_parse_state::before_unquoted_field_tail: { if (stack_.back() == csv_mode::subfields) { stack_.pop_back(); local_visitor.end_array(*this, ec); more_ = !cursor_mode_; if (mapping_kind_ != csv_mapping_kind::m_columns) { if (level() == mark_level_) { more_ = false; } } --level_; } ++column_index_; state_ = csv_parse_state::before_unquoted_string; ++column_; ++input_ptr_; break; } case csv_parse_state::before_unquoted_field_tail1: { if (stack_.back() == csv_mode::subfields) { stack_.pop_back(); local_visitor.end_array(*this, ec); more_ = !cursor_mode_; if (mapping_kind_ != csv_mapping_kind::m_columns) { if (level() == mark_level_) { more_ = false; } } --level_; } state_ = csv_parse_state::end_record; ++column_; ++input_ptr_; break; } case csv_parse_state::before_last_unquoted_field: end_unquoted_string_value(local_visitor, ec); state_ = csv_parse_state::before_last_unquoted_field_tail; break; case csv_parse_state::before_last_unquoted_field_tail: if (stack_.back() == csv_mode::subfields) { stack_.pop_back(); local_visitor.end_array(*this, ec); more_ = !cursor_mode_; if (mapping_kind_ != csv_mapping_kind::m_columns) { if (level() == mark_level_) { more_ = false; } } --level_; } ++column_index_; state_ = csv_parse_state::end_record; break; case csv_parse_state::before_unquoted_subfield: if (stack_.back() == csv_mode::data) { stack_.push_back(csv_mode::subfields); local_visitor.begin_array(semantic_tag::none, *this, ec); more_ = !cursor_mode_; ++level_; } state_ = csv_parse_state::before_unquoted_subfield_tail; break; case csv_parse_state::before_unquoted_subfield_tail: end_unquoted_string_value(local_visitor, ec); state_ = csv_parse_state::before_unquoted_string; ++column_; ++input_ptr_; break; case csv_parse_state::before_quoted_field: end_quoted_string_value(local_visitor, ec); state_ = csv_parse_state::before_unquoted_field_tail; // return to unquoted break; case csv_parse_state::before_quoted_subfield: if (stack_.back() == csv_mode::data) { stack_.push_back(csv_mode::subfields); local_visitor.begin_array(semantic_tag::none, *this, ec); more_ = !cursor_mode_; ++level_; } state_ = csv_parse_state::before_quoted_subfield_tail; break; case csv_parse_state::before_quoted_subfield_tail: end_quoted_string_value(local_visitor, ec); state_ = csv_parse_state::before_unquoted_string; ++column_; ++input_ptr_; break; case csv_parse_state::before_last_quoted_field: end_quoted_string_value(local_visitor, ec); state_ = csv_parse_state::before_last_quoted_field_tail; break; case csv_parse_state::before_last_quoted_field_tail: if (stack_.back() == csv_mode::subfields) { stack_.pop_back(); local_visitor.end_array(*this, ec); more_ = !cursor_mode_; if (mapping_kind_ != csv_mapping_kind::m_columns) { if (level() == mark_level_) { more_ = false; } } --level_; } ++column_index_; state_ = csv_parse_state::end_record; break; case csv_parse_state::unquoted_string: { switch (curr_char) { case '\n': case '\r': { if (trim_leading_ || trim_trailing_) { trim_string_buffer(trim_leading_,trim_trailing_); } if (!(ignore_empty_values_ && buffer_.empty())) { before_value(local_visitor, ec); state_ = csv_parse_state::before_last_unquoted_field; } else { state_ = csv_parse_state::end_record; } break; } default: if (curr_char == field_delimiter_) { if (trim_leading_ || trim_trailing_) { trim_string_buffer(trim_leading_,trim_trailing_); } before_value(local_visitor, ec); state_ = csv_parse_state::before_unquoted_field; } else if (subfield_delimiter_ != char_type() && curr_char == subfield_delimiter_) { if (trim_leading_ || trim_trailing_) { trim_string_buffer(trim_leading_,trim_trailing_); } before_value(local_visitor, ec); state_ = csv_parse_state::before_unquoted_subfield; } else if (curr_char == quote_char_) { buffer_.clear(); state_ = csv_parse_state::quoted_string; ++column_; ++input_ptr_; } else { buffer_.push_back(static_cast(curr_char)); ++column_; ++input_ptr_; } break; } break; } case csv_parse_state::expect_record: { switch (curr_char) { case '\n': { if (!ignore_empty_lines_) { begin_record(local_visitor, ec); state_ = csv_parse_state::end_record; } else { ++line_; column_ = 1; state_ = csv_parse_state::expect_comment_or_record; ++input_ptr_; } break; } case '\r': if (!ignore_empty_lines_) { begin_record(local_visitor, ec); state_ = csv_parse_state::end_record; } else { ++input_ptr_; push_state(state_); state_ = csv_parse_state::cr; } break; case ' ': case '\t': if (!trim_leading_) { buffer_.push_back(static_cast(curr_char)); begin_record(local_visitor, ec); state_ = csv_parse_state::unquoted_string; } ++column_; ++input_ptr_; break; default: begin_record(local_visitor, ec); if (curr_char == quote_char_) { buffer_.clear(); state_ = csv_parse_state::quoted_string; ++column_; ++input_ptr_; } else { state_ = csv_parse_state::unquoted_string; } break; } break; } case csv_parse_state::end_record: { switch (curr_char) { case '\n': { ++line_; column_ = 1; state_ = csv_parse_state::expect_comment_or_record; end_record(local_visitor, ec); ++input_ptr_; break; } case '\r': ++line_; column_ = 1; state_ = csv_parse_state::expect_comment_or_record; end_record(local_visitor, ec); push_state(state_); state_ = csv_parse_state::cr; ++input_ptr_; break; case ' ': case '\t': ++column_; ++input_ptr_; break; default: err_handler_(csv_errc::syntax_error, *this); ec = csv_errc::syntax_error; more_ = false; return; } break; } default: err_handler_(csv_errc::invalid_parse_state, *this); ec = csv_errc::invalid_parse_state; more_ = false; return; } if (line_ > max_lines_) { state_ = csv_parse_state::done; more_ = false; } } } void finish_parse() { std::error_code ec; finish_parse(ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,line_,column_)); } } void finish_parse(std::error_code& ec) { while (more_) { parse_some(ec); } } csv_parse_state state() const { return state_; } void update(const string_view_type sv) { update(sv.data(),sv.length()); } void update(const CharT* data, std::size_t length) { begin_input_ = data; input_end_ = data + length; input_ptr_ = begin_input_; } std::size_t line() const override { return line_; } std::size_t column() const override { return column_; } private: void initialize() { stack_.reserve(default_depth); stack_.push_back(csv_mode::initial); stack_.push_back((header_lines_ > 0) ? csv_mode::header : csv_mode::data); } // name void before_value(basic_json_visitor& visitor, std::error_code& ec) { switch (stack_.back()) { case csv_mode::header: if (trim_leading_inside_quotes_ || trim_trailing_inside_quotes_) { trim_string_buffer(trim_leading_inside_quotes_,trim_trailing_inside_quotes_); } if (line_ == (header_line_+header_line_offset_) && column_index_ >= min_column_names_) { column_names_.push_back(buffer_); if (assume_header_ && mapping_kind_ == csv_mapping_kind::n_rows) { visitor.string_value(buffer_, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } } break; case csv_mode::data: if (mapping_kind_ == csv_mapping_kind::n_objects) { if (!(ignore_empty_values_ && buffer_.empty())) { if (column_index_ < column_names_.size() + offset_) { visitor.key(column_names_[column_index_ - offset_], *this, ec); more_ = !cursor_mode_; } } } break; default: break; } } // begin_array or begin_record void begin_record(basic_json_visitor& visitor, std::error_code& ec) { offset_ = 0; if (stack_.back() == csv_mode::header && line_ > (header_lines_+header_line_offset_)) { stack_.back() = csv_mode::data; } switch (stack_.back()) { case csv_mode::header: switch (mapping_kind_) { case csv_mapping_kind::n_rows: if (assume_header_ && line_ == (header_line_+header_line_offset_)) { visitor.begin_array(semantic_tag::none, *this, ec); more_ = !cursor_mode_; ++level_; } break; default: break; } break; case csv_mode::data: switch (mapping_kind_) { case csv_mapping_kind::n_rows: visitor.begin_array(semantic_tag::none, *this, ec); more_ = !cursor_mode_; ++level_; break; case csv_mapping_kind::n_objects: visitor.begin_object(semantic_tag::none, *this, ec); more_ = !cursor_mode_; ++level_; break; case csv_mapping_kind::m_columns: break; default: break; } break; default: break; } } // end_array, begin_array, string_value (headers) void end_record(basic_json_visitor& visitor, std::error_code& ec) { if (!column_types_.empty()) { switch (mapping_kind_) { case csv_mapping_kind::n_rows: case csv_mapping_kind::n_objects: if (depth_ > 0) { visitor.end_array(*this, ec); more_ = !cursor_mode_; if (level_ == mark_level_) { more_ = false; } --level_; depth_ = 0; } break; case csv_mapping_kind::m_columns: if (depth_ > 0) { visitor.end_array(*this, ec); more_ = !cursor_mode_; --level_; depth_ = 0; } break; default: break; } } switch (stack_.back()) { case csv_mode::header: if (line_ >= header_lines_) { stack_.back() = csv_mode::data; } switch (mapping_kind_) { case csv_mapping_kind::n_rows: if (assume_header_) { visitor.end_array(*this, ec); more_ = !cursor_mode_; if (level() == mark_level_) { more_ = false; } --level_; } break; case csv_mapping_kind::m_columns: m_columns_filter_.initialize(column_names_); break; default: break; } break; case csv_mode::data: case csv_mode::subfields: { switch (mapping_kind_) { case csv_mapping_kind::n_rows: visitor.end_array(*this, ec); more_ = !cursor_mode_; if (level_ == mark_level_) { more_ = false; } --level_; break; case csv_mapping_kind::n_objects: visitor.end_object(*this, ec); more_ = !cursor_mode_; if (level_ == mark_level_) { more_ = false; } --level_; break; case csv_mapping_kind::m_columns: visitor.end_array(*this, ec); more_ = !cursor_mode_; --level_; break; } break; } default: break; } column_index_ = 0; } void trim_string_buffer(bool trim_leading, bool trim_trailing) { std::size_t start = 0; std::size_t length = buffer_.length(); if (trim_leading) { bool done = false; while (!done && start < buffer_.length()) { if ((buffer_[start] < 256) && std::isspace(buffer_[start])) { ++start; } else { done = true; } } } if (trim_trailing) { bool done = false; while (!done && length > 0) { if ((buffer_[length-1] < 256) && std::isspace(buffer_[length-1])) { --length; } else { done = true; } } } if (start != 0 || length != buffer_.size()) { // Do not use buffer_.substr(...), as this won't preserve the allocator state. buffer_.resize(length); buffer_.erase(0, start); } } /* end_array, begin_array, xxx_value (end_value) */ void end_unquoted_string_value(basic_json_visitor& visitor, std::error_code& ec) { switch (stack_.back()) { case csv_mode::data: case csv_mode::subfields: switch (mapping_kind_) { case csv_mapping_kind::n_rows: if (unquoted_empty_value_is_null_ && buffer_.length() == 0) { visitor.null_value(semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else { end_value(visitor, infer_types_, ec); } break; case csv_mapping_kind::n_objects: if (!(ignore_empty_values_ && buffer_.empty())) { if (column_index_ < column_names_.size() + offset_) { if (unquoted_empty_value_is_null_ && buffer_.length() == 0) { visitor.null_value(semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else { end_value(visitor, infer_types_, ec); } } else if (depth_ > 0) { if (unquoted_empty_value_is_null_ && buffer_.length() == 0) { visitor.null_value(semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else { end_value(visitor, infer_types_, ec); } } } break; case csv_mapping_kind::m_columns: if (!(ignore_empty_values_ && buffer_.empty())) { end_value(visitor, infer_types_, ec); } else { m_columns_filter_.skip_column(); } break; } break; default: break; } } void end_quoted_string_value(basic_json_visitor& visitor, std::error_code& ec) { switch (stack_.back()) { case csv_mode::data: case csv_mode::subfields: if (trim_leading_inside_quotes_ || trim_trailing_inside_quotes_) { trim_string_buffer(trim_leading_inside_quotes_,trim_trailing_inside_quotes_); } switch (mapping_kind_) { case csv_mapping_kind::n_rows: end_value(visitor, false, ec); break; case csv_mapping_kind::n_objects: if (!(ignore_empty_values_ && buffer_.empty())) { if (column_index_ < column_names_.size() + offset_) { if (unquoted_empty_value_is_null_ && buffer_.length() == 0) { visitor.null_value(semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else { end_value(visitor, false, ec); } } else if (depth_ > 0) { if (unquoted_empty_value_is_null_ && buffer_.length() == 0) { visitor.null_value(semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else { end_value(visitor, false, ec); } } } break; case csv_mapping_kind::m_columns: if (!(ignore_empty_values_ && buffer_.empty())) { end_value(visitor, false, ec); } else { m_columns_filter_.skip_column(); } break; } break; default: break; } } void end_value(basic_json_visitor& visitor, bool infer_types, std::error_code& ec) { auto it = std::find_if(string_double_map_.begin(), string_double_map_.end(), string_maps_to_double{ buffer_ }); if (it != string_double_map_.end()) { visitor.double_value((*it).second, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else if (column_index_ < column_types_.size() + offset_) { if (column_types_[column_index_ - offset_].col_type == csv_column_type::repeat_t) { offset_ = offset_ + column_types_[column_index_ - offset_].rep_count; if (column_index_ - offset_ + 1 < column_types_.size()) { if (column_index_ == offset_ || depth_ > column_types_[column_index_-offset_].level) { visitor.end_array(*this, ec); more_ = !cursor_mode_; if (mapping_kind_ != csv_mapping_kind::m_columns) { if (level() == mark_level_) { more_ = false; } } --level_; } depth_ = column_index_ == offset_ ? 0 : column_types_[column_index_ - offset_].level; } } if (depth_ < column_types_[column_index_ - offset_].level) { visitor.begin_array(semantic_tag::none, *this, ec); more_ = !cursor_mode_; depth_ = column_types_[column_index_ - offset_].level; ++level_; } else if (depth_ > column_types_[column_index_ - offset_].level) { visitor.end_array(*this, ec); more_ = !cursor_mode_; if (mapping_kind_ != csv_mapping_kind::m_columns) { if (level() == mark_level_) { more_ = false; } } --level_; depth_ = column_types_[column_index_ - offset_].level; } switch (column_types_[column_index_ - offset_].col_type) { case csv_column_type::integer_t: { std::basic_istringstream,char_allocator_type> iss{buffer_}; int64_t val; iss >> val; if (!iss.fail()) { visitor.int64_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else { if (column_index_ - offset_ < column_defaults_.size() && column_defaults_[column_index_ - offset_].length() > 0) { basic_json_parser parser(alloc_); parser.update(column_defaults_[column_index_ - offset_].data(),column_defaults_[column_index_ - offset_].length()); parser.parse_some(visitor); parser.finish_parse(visitor); } else { visitor.null_value(semantic_tag::none, *this, ec); more_ = !cursor_mode_; } } } break; case csv_column_type::float_t: { if (lossless_number_) { visitor.string_value(buffer_,semantic_tag::bigdec, *this, ec); more_ = !cursor_mode_; } else { std::basic_istringstream, char_allocator_type> iss{ buffer_ }; double val; iss >> val; if (!iss.fail()) { visitor.double_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else { if (column_index_ - offset_ < column_defaults_.size() && column_defaults_[column_index_ - offset_].length() > 0) { basic_json_parser parser(alloc_); parser.update(column_defaults_[column_index_ - offset_].data(),column_defaults_[column_index_ - offset_].length()); parser.parse_some(visitor); parser.finish_parse(visitor); } else { visitor.null_value(semantic_tag::none, *this, ec); more_ = !cursor_mode_; } } } } break; case csv_column_type::boolean_t: { if (buffer_.length() == 1 && buffer_[0] == '0') { visitor.bool_value(false, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else if (buffer_.length() == 1 && buffer_[0] == '1') { visitor.bool_value(true, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else if (buffer_.length() == 5 && ((buffer_[0] == 'f' || buffer_[0] == 'F') && (buffer_[1] == 'a' || buffer_[1] == 'A') && (buffer_[2] == 'l' || buffer_[2] == 'L') && (buffer_[3] == 's' || buffer_[3] == 'S') && (buffer_[4] == 'e' || buffer_[4] == 'E'))) { visitor.bool_value(false, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else if (buffer_.length() == 4 && ((buffer_[0] == 't' || buffer_[0] == 'T') && (buffer_[1] == 'r' || buffer_[1] == 'R') && (buffer_[2] == 'u' || buffer_[2] == 'U') && (buffer_[3] == 'e' || buffer_[3] == 'E'))) { visitor.bool_value(true, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else { if (column_index_ - offset_ < column_defaults_.size() && column_defaults_[column_index_ - offset_].length() > 0) { basic_json_parser parser(alloc_); parser.update(column_defaults_[column_index_ - offset_].data(),column_defaults_[column_index_ - offset_].length()); parser.parse_some(visitor); parser.finish_parse(visitor); } else { visitor.null_value(semantic_tag::none, *this, ec); more_ = !cursor_mode_; } } } break; default: if (buffer_.length() > 0) { visitor.string_value(buffer_, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else { if (column_index_ < column_defaults_.size() + offset_ && column_defaults_[column_index_ - offset_].length() > 0) { basic_json_parser parser(alloc_); parser.update(column_defaults_[column_index_ - offset_].data(),column_defaults_[column_index_ - offset_].length()); parser.parse_some(visitor); parser.finish_parse(visitor); } else { visitor.string_value(string_view_type(), semantic_tag::none, *this, ec); more_ = !cursor_mode_; } } break; } } else { if (infer_types) { end_value_with_numeric_check(visitor, ec); } else { visitor.string_value(buffer_, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } } } enum class numeric_check_state { initial, null, boolean_true, boolean_false, minus, zero, integer, fraction1, fraction, exp1, exp, not_a_number }; /* xxx_value */ void end_value_with_numeric_check(basic_json_visitor& visitor, std::error_code& ec) { numeric_check_state state = numeric_check_state::initial; bool is_negative = false; //int precision = 0; //uint8_t decimal_places = 0; auto last = buffer_.end(); std::string buffer; for (auto p = buffer_.begin(); state != numeric_check_state::not_a_number && p != last; ++p) { switch (state) { case numeric_check_state::initial: { switch (*p) { case 'n':case 'N': if ((last-p) == 4 && (p[1] == 'u' || p[1] == 'U') && (p[2] == 'l' || p[2] == 'L') && (p[3] == 'l' || p[3] == 'L')) { state = numeric_check_state::null; } else { state = numeric_check_state::not_a_number; } break; case 't':case 'T': if ((last-p) == 4 && (p[1] == 'r' || p[1] == 'R') && (p[2] == 'u' || p[2] == 'U') && (p[3] == 'e' || p[3] == 'U')) { state = numeric_check_state::boolean_true; } else { state = numeric_check_state::not_a_number; } break; case 'f':case 'F': if ((last-p) == 5 && (p[1] == 'a' || p[1] == 'A') && (p[2] == 'l' || p[2] == 'L') && (p[3] == 's' || p[3] == 'S') && (p[4] == 'e' || p[4] == 'E')) { state = numeric_check_state::boolean_false; } else { state = numeric_check_state::not_a_number; } break; case '-': is_negative = true; buffer.push_back(*p); state = numeric_check_state::minus; break; case '0': //++precision; buffer.push_back(*p); state = numeric_check_state::zero; break; case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': //++precision; buffer.push_back(*p); state = numeric_check_state::integer; break; default: state = numeric_check_state::not_a_number; break; } break; } case numeric_check_state::zero: { switch (*p) { case '.': buffer.push_back(to_double_.get_decimal_point()); state = numeric_check_state::fraction1; break; case 'e':case 'E': buffer.push_back(*p); state = numeric_check_state::exp1; break; default: state = numeric_check_state::not_a_number; break; } break; } case numeric_check_state::integer: { switch (*p) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': //++precision; buffer.push_back(*p); break; case '.': buffer.push_back(to_double_.get_decimal_point()); state = numeric_check_state::fraction1; break; case 'e':case 'E': buffer.push_back(*p); state = numeric_check_state::exp1; break; default: state = numeric_check_state::not_a_number; break; } break; } case numeric_check_state::minus: { switch (*p) { case '0': //++precision; buffer.push_back(*p); state = numeric_check_state::zero; break; case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': //++precision; buffer.push_back(*p); state = numeric_check_state::integer; break; default: state = numeric_check_state::not_a_number; break; } break; } case numeric_check_state::fraction1: { switch (*p) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': //++precision; //++decimal_places; buffer.push_back(*p); state = numeric_check_state::fraction; break; default: state = numeric_check_state::not_a_number; break; } break; } case numeric_check_state::fraction: { switch (*p) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': //++precision; //++decimal_places; buffer.push_back(*p); break; case 'e':case 'E': buffer.push_back(*p); state = numeric_check_state::exp1; break; default: state = numeric_check_state::not_a_number; break; } break; } case numeric_check_state::exp1: { switch (*p) { case '-': buffer.push_back(*p); break; case '+': break; case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': state = numeric_check_state::exp; buffer.push_back(*p); break; default: state = numeric_check_state::not_a_number; break; } break; } case numeric_check_state::exp: { switch (*p) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': buffer.push_back(*p); break; default: state = numeric_check_state::not_a_number; break; } break; } default: break; } } switch (state) { case numeric_check_state::null: visitor.null_value(semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; case numeric_check_state::boolean_true: visitor.bool_value(true, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; case numeric_check_state::boolean_false: visitor.bool_value(false, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; case numeric_check_state::zero: case numeric_check_state::integer: { if (is_negative) { int64_t val{ 0 }; auto result = jsoncons::detail::decimal_to_integer(buffer_.data(), buffer_.length(), val); if (result) { visitor.int64_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else // Must be overflow { visitor.string_value(buffer_, semantic_tag::bigint, *this, ec); more_ = !cursor_mode_; } } else { uint64_t val{ 0 }; auto result = jsoncons::detail::decimal_to_integer(buffer_.data(), buffer_.length(), val); if (result) { visitor.uint64_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else if (result.ec == jsoncons::detail::to_integer_errc::overflow) { visitor.string_value(buffer_, semantic_tag::bigint, *this, ec); more_ = !cursor_mode_; } else { ec = result.ec; more_ = false; return; } } break; } case numeric_check_state::fraction: case numeric_check_state::exp: { if (lossless_number_) { visitor.string_value(buffer_,semantic_tag::bigdec, *this, ec); more_ = !cursor_mode_; } else { double d = to_double_(buffer.c_str(), buffer.length()); visitor.double_value(d, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } break; } default: { visitor.string_value(buffer_, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } } } void push_state(csv_parse_state state) { state_stack_.push_back(state); } csv_parse_state pop_state() { JSONCONS_ASSERT(!state_stack_.empty()) csv_parse_state state = state_stack_.back(); state_stack_.pop_back(); return state; } }; using csv_parser = basic_csv_parser; using wcsv_parser = basic_csv_parser; }} #endif jsoncons-1.3.2/include/jsoncons_ext/csv/csv_reader.hpp000066400000000000000000000134471477700171100231470ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_CSV_CSV_READER_HPP #define JSONCONS_CSV_CSV_READER_HPP #include #include #include // std::allocator #include #include // std::move #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace csv { template ,typename Allocator=std::allocator> class basic_csv_reader { struct stack_item { stack_item() noexcept : array_begun_(false) { } bool array_begun_; }; using char_type = CharT; using temp_allocator_type = Allocator; using char_allocator_type = typename std::allocator_traits:: template rebind_alloc; basic_csv_reader(const basic_csv_reader&) = delete; basic_csv_reader& operator = (const basic_csv_reader&) = delete; basic_default_json_visitor default_visitor_; text_source_adaptor source_; basic_json_visitor& visitor_; basic_csv_parser parser_; public: // Structural characters static constexpr size_t default_max_buffer_size = 16384; //! Parse an input stream of CSV text into a json object /*! \param is The input stream to read from */ template basic_csv_reader(Sourceable&& source, basic_json_visitor& visitor, const Allocator& alloc = Allocator()) : basic_csv_reader(std::forward(source), visitor, basic_csv_decode_options(), default_csv_parsing(), alloc) { } template basic_csv_reader(Sourceable&& source, basic_json_visitor& visitor, const basic_csv_decode_options& options, const Allocator& alloc = Allocator()) : basic_csv_reader(std::forward(source), visitor, options, default_csv_parsing(), alloc) { } template basic_csv_reader(Sourceable&& source, basic_json_visitor& visitor, std::function err_handler, const Allocator& alloc = Allocator()) : basic_csv_reader(std::forward(source), visitor, basic_csv_decode_options(), err_handler, alloc) { } template basic_csv_reader(Sourceable&& source, basic_json_visitor& visitor, const basic_csv_decode_options& options, std::function err_handler, const Allocator& alloc = Allocator()) : source_(std::forward(source)), visitor_(visitor), parser_(options, err_handler, alloc) { } ~basic_csv_reader() noexcept = default; void read() { std::error_code ec; read(ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); } } void read(std::error_code& ec) { read_internal(ec); } std::size_t line() const { return parser_.line(); } std::size_t column() const { return parser_.column(); } bool eof() const { return parser_.source_exhausted() && source_.eof(); } private: void read_internal(std::error_code& ec) { if (source_.is_error()) { ec = csv_errc::source_error; return; } while (!parser_.stopped()) { if (parser_.source_exhausted()) { auto s = source_.read_buffer(ec); if (JSONCONS_UNLIKELY(ec)) return; if (s.size() > 0) { parser_.update(s.data(),s.size()); } } parser_.parse_some(visitor_, ec); if (JSONCONS_UNLIKELY(ec)) return; } } }; using csv_string_reader = basic_csv_reader>; using wcsv_string_reader = basic_csv_reader>; using csv_stream_reader = basic_csv_reader>; using wcsv_stream_reader = basic_csv_reader>; }} #endif jsoncons-1.3.2/include/jsoncons_ext/csv/decode_csv.hpp000066400000000000000000000226231477700171100231240ustar00rootroot00000000000000/// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_CSV_DECODE_CSV_HPP #define JSONCONS_EXT_CSV_DECODE_CSV_HPP #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace csv { template typename std::enable_if::value && extension_traits::is_sequence_of::value,T>::type decode_csv(const Source& s, const basic_csv_decode_options& options = basic_csv_decode_options()) { using char_type = typename Source::value_type; json_decoder decoder; basic_csv_reader> reader(s,decoder,options); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value && extension_traits::is_char_sequence::value,T>::type decode_csv(const Source& s, const basic_csv_decode_options& options = basic_csv_decode_options()) { using char_type = typename Source::value_type; basic_csv_cursor cursor(s, options); jsoncons::json_decoder> decoder; std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } template typename std::enable_if::value,T>::type decode_csv(std::basic_istream& is, const basic_csv_decode_options& options = basic_csv_decode_options()) { using char_type = CharT; json_decoder decoder; basic_csv_reader> reader(is,decoder,options); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value,T>::type decode_csv(std::basic_istream& is, const basic_csv_decode_options& options = basic_csv_decode_options()) { basic_csv_cursor cursor(is, options); jsoncons::json_decoder> decoder; std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } template typename std::enable_if::value,T>::type decode_csv(InputIt first, InputIt last, const basic_csv_decode_options::value_type>& options = basic_csv_decode_options::value_type>()) { using char_type = typename std::iterator_traits::value_type; jsoncons::json_decoder decoder; basic_csv_reader> reader(iterator_source(first,last), decoder, options); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value,T>::type decode_csv(InputIt first, InputIt last, const basic_csv_decode_options::value_type>& options = basic_csv_decode_options::value_type>()) { using char_type = typename std::iterator_traits::value_type; basic_csv_cursor> cursor(iterator_source(first, last), options); jsoncons::json_decoder> decoder; std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } // With leading allocator_set parameter template typename std::enable_if::value && extension_traits::is_sequence_of::value,T>::type decode_csv(const allocator_set& alloc_set, const Source& s, const basic_csv_decode_options& options = basic_csv_decode_options()) { using char_type = typename Source::value_type; json_decoder decoder(alloc_set.get_allocator(), alloc_set.get_temp_allocator()); basic_csv_reader,TempAllocator> reader(s,decoder,options,alloc_set.get_temp_allocator()); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value && extension_traits::is_char_sequence::value,T>::type decode_csv(const allocator_set& alloc_set, const Source& s, const basic_csv_decode_options& options = basic_csv_decode_options()) { using char_type = typename Source::value_type; basic_csv_cursor,TempAllocator> cursor(s, options, alloc_set.get_temp_allocator()); json_decoder,TempAllocator> decoder(alloc_set.get_temp_allocator(), alloc_set.get_temp_allocator()); std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } template typename std::enable_if::value,T>::type decode_csv(const allocator_set& alloc_set, std::basic_istream& is, const basic_csv_decode_options& options = basic_csv_decode_options()) { using char_type = CharT; json_decoder decoder(alloc_set.get_allocator(), alloc_set.get_temp_allocator()); basic_csv_reader,TempAllocator> reader(is,decoder,options,alloc_set.get_temp_allocator()); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value,T>::type decode_csv(const allocator_set& alloc_set, std::basic_istream& is, const basic_csv_decode_options& options = basic_csv_decode_options()) { basic_csv_cursor,TempAllocator> cursor(is, options, alloc_set.get_temp_allocator()); json_decoder,TempAllocator> decoder(alloc_set.get_temp_allocator(), alloc_set.get_temp_allocator()); std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } } // namespace csv } // namespace jsoncons #endif // JSONCONS_EXT_CSV_DECODE_CSV_HPP jsoncons-1.3.2/include/jsoncons_ext/csv/encode_csv.hpp000066400000000000000000000145301477700171100231340ustar00rootroot00000000000000/// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_CSV_ENCODE_CSV_HPP #define JSONCONS_EXT_CSV_ENCODE_CSV_HPP #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace csv { template typename std::enable_if::value && extension_traits::is_back_insertable_char_container::value>::type encode_csv(const T& j, CharContainer& cont, const basic_csv_encode_options& options = basic_csv_encode_options()) { using char_type = typename CharContainer::value_type; basic_csv_encoder>> encoder(cont,options); j.dump(encoder); } template typename std::enable_if::value && extension_traits::is_back_insertable_char_container::value>::type encode_csv(const T& val, CharContainer& cont, const basic_csv_encode_options& options = basic_csv_encode_options()) { using char_type = typename CharContainer::value_type; basic_csv_encoder>> encoder(cont,options); std::error_code ec; encode_traits::encode(val, encoder, json(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } template typename std::enable_if::value,void>::type encode_csv(const T& j, std::basic_ostream& os, const basic_csv_encode_options& options = basic_csv_encode_options()) { using char_type = CharT; basic_csv_encoder> encoder(os,options); j.dump(encoder); } template typename std::enable_if::value,void>::type encode_csv(const T& val, std::basic_ostream& os, const basic_csv_encode_options& options = basic_csv_encode_options()) { using char_type = CharT; basic_csv_encoder> encoder(os,options); std::error_code ec; encode_traits::encode(val, encoder, json(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } // with alloc_set.get_temp_allocator()ator_arg_t template typename std::enable_if::value && extension_traits::is_back_insertable_char_container::value>::type encode_csv(const allocator_set& alloc_set, const T& j, CharContainer& cont, const basic_csv_encode_options& options = basic_csv_encode_options()) { using char_type = typename CharContainer::value_type; basic_csv_encoder>,TempAllocator> encoder(cont, options, alloc_set.get_temp_allocator()); j.dump(encoder); } template typename std::enable_if::value && extension_traits::is_back_insertable_char_container::value>::type encode_csv(const allocator_set& alloc_set, const T& val, CharContainer& cont, const basic_csv_encode_options& options = basic_csv_encode_options()) { using char_type = typename CharContainer::value_type; basic_csv_encoder>,TempAllocator> encoder(cont, options, alloc_set.get_temp_allocator()); std::error_code ec; encode_traits::encode(val, encoder, json(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } template typename std::enable_if::value,void>::type encode_csv(const allocator_set& alloc_set, const T& j, std::basic_ostream& os, const basic_csv_encode_options& options = basic_csv_encode_options()) { using char_type = CharT; basic_csv_encoder,TempAllocator> encoder(os, options, alloc_set.get_temp_allocator()); j.dump(encoder); } template typename std::enable_if::value,void>::type encode_csv(const allocator_set& alloc_set, const T& val, std::basic_ostream& os, const basic_csv_encode_options& options = basic_csv_encode_options()) { using char_type = CharT; basic_csv_encoder,TempAllocator> encoder(os, options, alloc_set.get_temp_allocator()); std::error_code ec; encode_traits::encode(val, encoder, json(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } } // namespace csv } // namespace jsoncons #endif // JSONCONS_EXT_CSV_ENCODE_CSV_HPP jsoncons-1.3.2/include/jsoncons_ext/jmespath/000077500000000000000000000000001477700171100213305ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons_ext/jmespath/jmespath.hpp000066400000000000000000006322131477700171100236630ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JMESPATH_JMESPATH_HPP #define JSONCONS_EXT_JMESPATH_JMESPATH_HPP #include // std::stable_sort, std::reverse #include // std::abs #include #include #include // #include // std::numeric_limits #include #include #include #include // std::is_const #include // std::unordered_map #include // std::move #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace jmespath { enum class operator_kind { default_op, // Identifier, CurrentNode, Index, MultiSelectList, MultiSelectHash, FunctionExpression projection_op, flatten_projection_op, // FlattenProjection or_op, and_op, eq_op, ne_op, lt_op, lte_op, gt_op, gte_op, not_op }; struct operator_table final { static int precedence_level(operator_kind oper) { switch (oper) { case operator_kind::projection_op: return 11; case operator_kind::flatten_projection_op: return 11; case operator_kind::or_op: return 9; case operator_kind::and_op: return 8; case operator_kind::eq_op: case operator_kind::ne_op: return 6; case operator_kind::lt_op: case operator_kind::lte_op: case operator_kind::gt_op: case operator_kind::gte_op: return 5; case operator_kind::not_op: return 1; default: return 1; } } static bool is_right_associative(operator_kind oper) { switch (oper) { case operator_kind::not_op: return true; case operator_kind::projection_op: return true; case operator_kind::flatten_projection_op: return false; case operator_kind::or_op: case operator_kind::and_op: case operator_kind::eq_op: case operator_kind::ne_op: case operator_kind::lt_op: case operator_kind::lte_op: case operator_kind::gt_op: case operator_kind::gte_op: return false; default: return false; } } }; // eval_context template class eval_context { public: using char_type = typename Json::char_type; using char_traits_type = typename Json::char_traits_type; using string_type = std::basic_string; using string_view_type = typename Json::string_view_type; using reference = typename Json::const_reference; using pointer = typename Json::pointer; public: std::vector>& temp_storage_; std::map variables_; public: eval_context(std::vector>& temp_storage) : temp_storage_(temp_storage) { } eval_context(std::vector>& temp_storage, const std::map& variables) : temp_storage_(temp_storage), variables_(variables) { } ~eval_context() noexcept = default; void set_variable(const string_type& key, const Json& value) { variables_[key] = std::addressof(value); } const Json& get_variable(const string_type& key, std::error_code& ec) const { auto it = variables_.find(key); if (it == variables_.end()) { ec = jmespath_errc::undefined_variable; return Json::null(); } return *it->second; } reference number_type_name() { static Json number_type_name(JSONCONS_STRING_CONSTANT(char_type, "number")); return number_type_name; } reference boolean_type_name() { static Json boolean_type_name(JSONCONS_STRING_CONSTANT(char_type, "boolean")); return boolean_type_name; } reference string_type_name() { static Json string_type_name(JSONCONS_STRING_CONSTANT(char_type, "string")); return string_type_name; } reference object_type_name() { static Json object_type_name(JSONCONS_STRING_CONSTANT(char_type, "object")); return object_type_name; } reference array_type_name() { static Json array_type_name(JSONCONS_STRING_CONSTANT(char_type, "array")); return array_type_name; } reference null_type_name() { static Json null_type_name(JSONCONS_STRING_CONSTANT(char_type, "null")); return null_type_name; } reference true_value() const { static const Json true_value(true, semantic_tag::none); return true_value; } reference false_value() const { static const Json false_value(false, semantic_tag::none); return false_value; } reference null_value() const { static const Json null_value(null_type(), semantic_tag::none); return null_value; } template Json* create_json(Args&& ... args) { auto temp = jsoncons::make_unique(std::forward(args)...); Json* ptr = temp.get(); temp_storage_.push_back(std::move(temp)); return ptr; } }; // expr_base template class expr_base { public: using reference = const Json&; virtual ~expr_base() = default; virtual reference evaluate(reference val, eval_context& context, std::error_code& ec) const = 0; }; template class expr_wrapper : public expr_base { public: using reference = const Json&; using pointer = const Json*; private: const expr_base* expr_{nullptr}; public: expr_wrapper() noexcept = default; expr_wrapper(const expr_base& expr) : expr_(std::addressof(expr)) { } expr_wrapper(const expr_wrapper& other) : expr_(other.expr_) { } expr_wrapper& operator=(const expr_wrapper& other) { expr_ = other.expr_; return *this; } reference evaluate(reference val, eval_context& context, std::error_code& ec) const final { return *context.create_json(deep_copy(expr_->evaluate(val, context, ec))); } }; // expr_base_impl template class expr_base_impl : public expr_base { public: using reference = const Json&; private: std::size_t precedence_level_{0}; bool is_right_associative_; bool is_projection_; public: expr_base_impl(operator_kind oper, bool is_projection) : precedence_level_(operator_table::precedence_level(oper)), is_right_associative_(operator_table::is_right_associative(oper)), is_projection_(is_projection) { } ~expr_base_impl() = default; std::size_t precedence_level() const { return precedence_level_; } bool is_right_associative() const { return is_right_associative_; } bool is_projection() const { return is_projection_; } virtual void add_expression(expr_base_impl* expressions) = 0; }; // parameter enum class parameter_kind{value, expression}; template class parameter { public: using reference = const Json&; using expression_type = expr_base; private: parameter_kind type_; public: union { const expression_type* expression_; const Json* value_; }; public: parameter(const parameter& other) noexcept : type_(other.type_) { switch (type_) { case parameter_kind::expression: expression_ = other.expression_; break; case parameter_kind::value: value_ = other.value_; break; default: break; } } parameter(reference value) noexcept : type_(parameter_kind::value), value_(std::addressof(value)) { } parameter(const expression_type& expression) noexcept : type_(parameter_kind::expression), expression_(std::addressof(expression)) { } parameter& operator=(const parameter& other) { if (&other != this) { type_ = other.type_; switch (type_) { case parameter_kind::expression: expression_ = other.expression_; break; case parameter_kind::value: value_ = other.value_; break; default: break; } } return *this; } bool is_value() const { return type_ == parameter_kind::value; } bool is_expression() const { return type_ == parameter_kind::expression; } const Json& value() const { return *value_; } const expression_type& expression() const { return *expression_; } }; template class custom_function { public: using value_type = Json; using reference = const Json&; using char_type = typename Json::char_type; using parameter_type = parameter; using custom_function_type = std::function, eval_context&, std::error_code& ec)>; using string_type = typename Json::string_type; string_type function_name_; optional arity_; custom_function_type f_; custom_function(const string_type& function_name, const optional& arity, const custom_function_type& f) : function_name_(function_name), arity_(arity), f_(f) { } custom_function(string_type&& function_name, optional&& arity, custom_function_type&& f) : function_name_(std::move(function_name)), arity_(std::move(arity)), f_(std::move(f)) { } custom_function(const custom_function&) = default; custom_function(custom_function&&) = default; const string_type& name() const { return function_name_; } optional arity() const { return arity_; } const custom_function_type& function() const { return f_; } }; // function_base template class function_base { public: using reference = const Json&; using parameter_type = parameter; private: jsoncons::optional arg_count_; public: function_base(jsoncons::optional arg_count) : arg_count_(arg_count) { } jsoncons::optional arity() const { return arg_count_; } virtual ~function_base() = default; virtual reference evaluate(const std::vector& params, eval_context& context, std::error_code& ec) const = 0; virtual bool is_custom() const { return false; } }; template class function_wrapper : public function_base { public: using value_type = Json; using reference = const Json&; using parameter_type = parameter; using string_view_type = typename Json::string_view_type; using custom_function_type = std::function, eval_context&, std::error_code& ec)>; private: custom_function_type f_; public: function_wrapper(jsoncons::optional arity, const custom_function_type& f) : function_base(arity), f_(f) { } bool is_custom() const final { return true; } reference evaluate(const std::vector& params, eval_context& context, std::error_code& ec) const override { auto val = f_(params, context, ec); auto ptr = context.create_json(std::move(val)); return *ptr; } }; template class custom_functions { using char_type = typename Json::char_type; using string_type = typename Json::string_type; using value_type = Json; using reference = const Json&; using parameter_type = parameter; using custom_function_type = std::function, eval_context& context, std::error_code& ec)>; using const_iterator = typename std::vector>::const_iterator; std::vector> functions_; public: void register_function(const string_type& name, jsoncons::optional arity, const custom_function_type& f) { functions_.emplace_back(name, arity, f); } const_iterator begin() const { return functions_.begin(); } const_iterator end() const { return functions_.end(); } }; namespace detail { template class unary_operator { public: using reference = typename Json::const_reference; private: std::size_t precedence_level_; bool is_right_associative_; protected: virtual ~unary_operator() = default; public: unary_operator(operator_kind oper) : precedence_level_(operator_table::precedence_level(oper)), is_right_associative_(operator_table::is_right_associative(oper)) { } std::size_t precedence_level() const { return precedence_level_; } bool is_right_associative() const { return is_right_associative_; } virtual reference evaluate(reference val, eval_context&, std::error_code& ec) const = 0; }; template class binary_operator { public: using reference = typename Json::const_reference; private: std::size_t precedence_level_; bool is_right_associative_; protected: virtual ~binary_operator() = default; public: binary_operator(operator_kind oper) : precedence_level_(operator_table::precedence_level(oper)), is_right_associative_(operator_table::is_right_associative(oper)) { } std::size_t precedence_level() const { return precedence_level_; } bool is_right_associative() const { return is_right_associative_; } virtual reference evaluate(reference lhs, reference rhs, eval_context&, std::error_code& ec) const = 0; }; enum class token_kind { current_node, lparen, rparen, begin_multi_select_hash, end_multi_select_hash, begin_multi_select_list, end_multi_select_list, begin_filter, end_filter, pipe, separator, key, literal, expression, binary_operator, unary_operator, function, end_function, argument, begin_expression_type, end_expression_type, end_of_expression, variable, variable_binding }; struct literal_arg_t { explicit literal_arg_t() = default; }; constexpr literal_arg_t literal_arg{}; struct begin_expression_type_arg_t { explicit begin_expression_type_arg_t() = default; }; constexpr begin_expression_type_arg_t begin_expression_type_arg{}; struct end_expression_type_arg_t { explicit end_expression_type_arg_t() = default; }; constexpr end_expression_type_arg_t end_expression_type_arg{}; struct end_of_expression_arg_t { explicit end_of_expression_arg_t() = default; }; constexpr end_of_expression_arg_t end_of_expression_arg{}; struct separator_arg_t { explicit separator_arg_t() = default; }; constexpr separator_arg_t separator_arg{}; struct key_arg_t { explicit key_arg_t() = default; }; constexpr key_arg_t key_arg{}; struct lparen_arg_t { explicit lparen_arg_t() = default; }; constexpr lparen_arg_t lparen_arg{}; struct rparen_arg_t { explicit rparen_arg_t() = default; }; constexpr rparen_arg_t rparen_arg{}; struct begin_multi_select_hash_arg_t { explicit begin_multi_select_hash_arg_t() = default; }; constexpr begin_multi_select_hash_arg_t begin_multi_select_hash_arg{}; struct end_multi_select_hash_arg_t { explicit end_multi_select_hash_arg_t() = default; }; constexpr end_multi_select_hash_arg_t end_multi_select_hash_arg{}; struct begin_multi_select_list_arg_t { explicit begin_multi_select_list_arg_t() = default; }; constexpr begin_multi_select_list_arg_t begin_multi_select_list_arg{}; struct end_multi_select_list_arg_t { explicit end_multi_select_list_arg_t() = default; }; constexpr end_multi_select_list_arg_t end_multi_select_list_arg{}; struct begin_filter_arg_t { explicit begin_filter_arg_t() = default; }; constexpr begin_filter_arg_t begin_filter_arg{}; struct end_filter_arg_t { explicit end_filter_arg_t() = default; }; constexpr end_filter_arg_t end_filter_arg{}; struct pipe_arg_t { explicit pipe_arg_t() = default; }; constexpr pipe_arg_t pipe_arg{}; struct current_node_arg_t { explicit current_node_arg_t() = default; }; constexpr current_node_arg_t current_node_arg{}; struct end_function_arg_t { explicit end_function_arg_t() = default; }; constexpr end_function_arg_t end_function_arg{}; struct argument_arg_t { explicit argument_arg_t() = default; }; constexpr argument_arg_t argument_arg{}; struct variable_binding_arg_t { explicit variable_binding_arg_t() = default; }; constexpr variable_binding_arg_t variable_binding_arg{}; struct slice { jsoncons::optional start_; jsoncons::optional stop_; int64_t step_; slice() : step_(1) { } slice(const jsoncons::optional& start, const jsoncons::optional& end, int64_t step) : start_(start), stop_(end), step_(step) { } slice(const slice& other) = default; slice(slice&& other) = default; slice& operator=(const slice& other) = default; slice& operator=(slice&& other) = default; ~slice() = default; int64_t get_start(std::size_t size) const { if (start_) { auto len = *start_ >= 0 ? *start_ : (static_cast(size) + *start_); return len <= static_cast(size) ? len : static_cast(size); } else { if (step_ >= 0) { return 0; } else { return static_cast(size); } } } int64_t get_stop(std::size_t size) const { if (stop_) { auto len = *stop_ >= 0 ? *stop_ : (static_cast(size) + *stop_); return len <= static_cast(size) ? len : static_cast(size); } else { return step_ >= 0 ? static_cast(size) : -1; } } int64_t step() const { return step_; // Allow negative } }; template class token { public: using char_type = typename Json::char_type; using char_traits_type = typename Json::char_traits_type; using string_type = std::basic_string; token_kind type_; string_type key_; union { expr_base_impl* expression_; const unary_operator* unary_operator_; const binary_operator* binary_operator_; const function_base* function_; Json value_; }; public: token(current_node_arg_t) noexcept : type_(token_kind::current_node), expression_{nullptr} { } token(end_function_arg_t) noexcept : type_(token_kind::end_function), expression_{nullptr} { } token(separator_arg_t) noexcept : type_(token_kind::separator), expression_{nullptr} { } token(lparen_arg_t) noexcept : type_(token_kind::lparen), expression_{nullptr} { } token(rparen_arg_t) noexcept : type_(token_kind::rparen), expression_{nullptr} { } token(end_of_expression_arg_t) noexcept : type_(token_kind::end_of_expression), expression_{nullptr} { } token(begin_multi_select_hash_arg_t) noexcept : type_(token_kind::begin_multi_select_hash), expression_{nullptr} { } token(end_multi_select_hash_arg_t) noexcept : type_(token_kind::end_multi_select_hash) { } token(begin_multi_select_list_arg_t) noexcept : type_(token_kind::begin_multi_select_list) { } token(end_multi_select_list_arg_t) noexcept : type_(token_kind::end_multi_select_list) { } token(begin_filter_arg_t) noexcept : type_(token_kind::begin_filter) { } token(end_filter_arg_t) noexcept : type_(token_kind::end_filter) { } token(pipe_arg_t) noexcept : type_(token_kind::pipe) { } token(key_arg_t, const string_type& key) : type_(token_kind::key) { new (&key_) string_type(key); } token(expr_base_impl* expression) : type_(token_kind::expression), expression_(expression) { } token(const unary_operator* expression) noexcept : type_(token_kind::unary_operator), unary_operator_(expression) { } token(const binary_operator* expression) noexcept : type_(token_kind::binary_operator), binary_operator_(expression) { } token(const function_base* function) noexcept : type_(token_kind::function), function_(function) { } token(argument_arg_t) noexcept : type_(token_kind::argument) { } token(begin_expression_type_arg_t) noexcept : type_(token_kind::begin_expression_type) { } token(end_expression_type_arg_t) noexcept : type_(token_kind::end_expression_type) { } token(literal_arg_t, Json&& value) noexcept : type_(token_kind::literal), value_(std::move(value)) { } token(token&& other) noexcept { construct(std::move(other)); } token(const token& other) { construct(other); } token(const string_type& variable_ref, expr_base_impl* expression) noexcept : type_(token_kind::variable), key_(variable_ref), expression_(expression) { } token(variable_binding_arg_t, const string_type& variable_ref) : type_(token_kind::variable_binding), key_(variable_ref) { } ~token() noexcept { destroy(); } token& operator=(const token& other) { if (&other != this) { destroy(); construct(other); } return *this; } token& operator=(token&& other) noexcept { if (&other != this) { destroy(); construct(std::move(other)); } return *this; } token_kind type() const { return type_; } bool is_lparen() const { return type_ == token_kind::lparen; } bool is_lbrace() const { return type_ == token_kind::begin_multi_select_hash; } bool is_key() const { return type_ == token_kind::key; } bool is_rparen() const { return type_ == token_kind::rparen; } bool is_current_node() const { return type_ == token_kind::current_node; } bool is_projection() const { if (is_expression()) { JSONCONS_ASSERT(expression_ != nullptr); return expression_->is_projection();; } return false; } bool is_expression() const { return type_ == token_kind::expression; } bool is_operator() const { return type_ == token_kind::unary_operator || type_ == token_kind::binary_operator; } std::size_t precedence_level() const { switch(type_) { case token_kind::unary_operator: JSONCONS_ASSERT(unary_operator_ != nullptr); return unary_operator_->precedence_level(); case token_kind::binary_operator: JSONCONS_ASSERT(binary_operator_ != nullptr); return binary_operator_->precedence_level(); case token_kind::expression: JSONCONS_ASSERT(expression_ != nullptr); return expression_->precedence_level(); default: return 0; } } jsoncons::optional arity() const { return type_ == token_kind::function ? function_->arity() : jsoncons::optional(); } bool is_right_associative() const { switch(type_) { case token_kind::unary_operator: JSONCONS_ASSERT(unary_operator_ != nullptr); return unary_operator_->is_right_associative(); case token_kind::binary_operator: JSONCONS_ASSERT(binary_operator_ != nullptr); return binary_operator_->is_right_associative(); case token_kind::expression: JSONCONS_ASSERT(expression_ != nullptr); return expression_->is_right_associative(); default: return false; } } void construct(token&& other) { type_ = other.type_; switch (type_) { case token_kind::variable: key_ = std::move(other.key_); expression_ = other.expression_; break; case token_kind::variable_binding: case token_kind::key: key_ = std::move(other.key_); break; case token_kind::literal: new (&value_) Json(std::move(other.value_)); break; case token_kind::expression: expression_ = other.expression_; break; case token_kind::unary_operator: unary_operator_ = other.unary_operator_; break; case token_kind::binary_operator: binary_operator_ = other.binary_operator_; break; case token_kind::function: function_ = other.function_; break; default: break; } } void construct(const token& other) { type_ = other.type_; switch (type_) { case token_kind::variable: key_ = other.key_; expression_ = other.expression_; break; case token_kind::variable_binding: case token_kind::key: key_ = other.key_; break; case token_kind::literal: new (&value_) Json(other.value_); break; case token_kind::expression: expression_ = other.expression_; break; case token_kind::unary_operator: unary_operator_ = other.unary_operator_; break; case token_kind::binary_operator: binary_operator_ = other.binary_operator_; break; case token_kind::function: function_ = other.function_; break; default: break; } } void destroy() noexcept { switch(type_) { case token_kind::literal: value_.~Json(); break; default: break; } } }; enum class expr_state { start, lhs_expression, rhs_expression, sub_expression, expression_type, comparator_expression, function_expression, argument, expression_or_expression_type, quoted_string, raw_string, raw_string_escape_char, quoted_string_escape_char, escape_u1, escape_u2, escape_u3, escape_u4, escape_expect_surrogate_pair1, escape_expect_surrogate_pair2, escape_u5, escape_u6, escape_u7, escape_u8, literal, key_expr, val_expr, identifier_or_function_expr, unquoted_string, key_val_expr, number, digit, index_or_slice_expression, bracket_specifier, bracket_specifier_or_multi_select_list, filter, multi_select_list, multi_select_hash, rhs_slice_expression_stop, rhs_slice_expression_step, expect_rbracket, expect_rparen, expect_dot, expect_rbrace, expect_colon, expect_multi_select_list, cmp_lt_or_lte, cmp_eq, cmp_gt_or_gte, cmp_ne, expect_pipe_or_or, expect_and, variable_binding, variable_ref, expect_assign, expect_in_or_comma, substitute_variable }; template struct expression_context { using string_type = std::basic_string; std::size_t end_index{0}; string_type variable_ref; expression_context() = default; }; template class jmespath_evaluator { public: typedef typename Json::char_type char_type; typedef typename Json::char_traits_type char_traits_type; typedef std::basic_string string_type; typedef typename Json::string_view_type string_view_type; using reference = const Json&; using pointer = typename Json::const_pointer; using const_pointer = typename Json::const_pointer; using parameter_type = parameter; using expression_type = expr_base_impl; using function_type = function_base; static bool is_false(reference ref) { return (ref.is_array() && ref.empty()) || (ref.is_object() && ref.empty()) || (ref.is_string() && ref.as_string_view().size() == 0) || (ref.is_bool() && !ref.as_bool()) || ref.is_null(); } static bool is_true(reference ref) { return !is_false(ref); } class not_expression final : public unary_operator { public: not_expression() : unary_operator(operator_kind::not_op) {} reference evaluate(reference val, eval_context& context, std::error_code&) const override { return is_false(val) ? context.true_value() : context.false_value(); } }; class abs_function : public function_base { public: abs_function() : function_base(1) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!args[0].is_value()) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); switch (arg0.type()) { case json_type::uint64_value: return arg0; case json_type::int64_value: { return arg0.template as() >= 0 ? arg0 : *context.create_json(std::abs(arg0.template as())); } case json_type::double_value: { return arg0.template as() >= 0 ? arg0 : *context.create_json(std::abs(arg0.template as())); } default: { ec = jmespath_errc::invalid_type; return context.null_value(); } } } }; class avg_function : public function_base { public: avg_function() : function_base(1) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!args[0].is_value()) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); if (!arg0.is_array()) { ec = jmespath_errc::invalid_type; return context.null_value(); } if (arg0.empty()) { return context.null_value(); } double sum = 0; for (auto& j : arg0.array_range()) { if (!j.is_number()) { ec = jmespath_errc::invalid_type; return context.null_value(); } sum += j.template as(); } return arg0.size() == 0 ? context.null_value() : *context.create_json(sum / arg0.size()); } }; class ceil_function : public function_base { public: ceil_function() : function_base(1) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!args[0].is_value()) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); switch (arg0.type()) { case json_type::uint64_value: case json_type::int64_value: { return *context.create_json(arg0.template as()); } case json_type::double_value: { return *context.create_json(std::ceil(arg0.template as())); } default: ec = jmespath_errc::invalid_type; return context.null_value(); } } }; class contains_function : public function_base { public: contains_function() : function_base(2) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!(args[0].is_value() && args[1].is_value())) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); reference arg1 = args[1].value(); switch (arg0.type()) { case json_type::array_value: for (auto& j : arg0.array_range()) { if (j == arg1) { return context.true_value(); } } return context.false_value(); case json_type::string_value: { if (!arg1.is_string()) { ec = jmespath_errc::invalid_type; return context.null_value(); } auto sv0 = arg0.template as(); auto sv1 = arg1.template as(); return sv0.find(sv1) != string_view_type::npos ? context.true_value() : context.false_value(); } default: { ec = jmespath_errc::invalid_type; return context.null_value(); } } } }; class ends_with_function : public function_base { public: ends_with_function() : function_base(2) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!(args[0].is_value() && args[1].is_value())) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); if (!arg0.is_string()) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg1 = args[1].value(); if (!arg1.is_string()) { ec = jmespath_errc::invalid_type; return context.null_value(); } auto sv0 = arg0.template as(); auto sv1 = arg1.template as(); if (sv1.length() <= sv0.length() && sv1 == sv0.substr(sv0.length() - sv1.length())) { return context.true_value(); } else { return context.false_value(); } } }; class floor_function : public function_base { public: floor_function() : function_base(1) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!args[0].is_value()) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); switch (arg0.type()) { case json_type::uint64_value: case json_type::int64_value: { return *context.create_json(arg0.template as()); } case json_type::double_value: { return *context.create_json(std::floor(arg0.template as())); } default: ec = jmespath_errc::invalid_type; return context.null_value(); } } }; class join_function : public function_base { public: join_function() : function_base(2) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); reference arg0 = args[0].value(); reference arg1 = args[1].value(); if (!(args[0].is_value() && args[1].is_value())) { ec = jmespath_errc::invalid_type; return context.null_value(); } if (!arg0.is_string()) { ec = jmespath_errc::invalid_type; return context.null_value(); } if (!arg1.is_array()) { ec = jmespath_errc::invalid_type; return context.null_value(); } string_type sep = arg0.template as(); string_type buf; bool is_first = true; for (auto &j : arg1.array_range()) { if (!j.is_string()) { ec = jmespath_errc::invalid_type; return context.null_value(); } if (is_first) { is_first = false; } else { buf.append(sep); } auto sv = j.template as(); buf.append(sv.begin(), sv.end()); } return *context.create_json(buf); } }; class length_function : public function_base { public: length_function() : function_base(1) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!args[0].is_value()) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); switch (arg0.type()) { case json_type::object_value: case json_type::array_value: return *context.create_json(arg0.size()); case json_type::string_value: { auto sv0 = arg0.template as(); auto length = unicode_traits::count_codepoints(sv0.data(), sv0.size()); return *context.create_json(length); } default: { ec = jmespath_errc::invalid_type; return context.null_value(); } } } }; class max_function : public function_base { public: max_function() : function_base(1) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!args[0].is_value()) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); if (!arg0.is_array()) { ec = jmespath_errc::invalid_type; return context.null_value(); } if (arg0.empty()) { return context.null_value(); } bool is_number = arg0.at(0).is_number(); bool is_string = arg0.at(0).is_string(); if (!is_number && !is_string) { ec = jmespath_errc::invalid_type; return context.null_value(); } std::size_t index = 0; for (std::size_t i = 1; i < arg0.size(); ++i) { if (!(arg0.at(i).is_number() == is_number && arg0.at(i).is_string() == is_string)) { ec = jmespath_errc::invalid_type; return context.null_value(); } if (arg0.at(i) > arg0.at(index)) { index = i; } } return arg0.at(index); } }; class max_by_function : public function_base { public: max_by_function() : function_base(2) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!(args[0].is_value() && args[1].is_expression())) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); if (!arg0.is_array()) { ec = jmespath_errc::invalid_type; return context.null_value(); } if (arg0.empty()) { return context.null_value(); } const auto& expr = args[1].expression(); std::error_code ec2; Json key1 = expr.evaluate(arg0.at(0), context, ec2); bool is_number = key1.is_number(); bool is_string = key1.is_string(); if (!(is_number || is_string)) { ec = jmespath_errc::invalid_type; return context.null_value(); } std::size_t index = 0; for (std::size_t i = 1; i < arg0.size(); ++i) { reference key2 = expr.evaluate(arg0.at(i), context, ec2); if (!(key2.is_number() == is_number && key2.is_string() == is_string)) { ec = jmespath_errc::invalid_type; return context.null_value(); } if (key2 > key1) { key1 = key2; index = i; } } return arg0.at(index); } }; class map_function : public function_base { public: map_function() : function_base(2) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!(args[0].is_expression() && args[1].is_value())) { ec = jmespath_errc::invalid_type; return context.null_value(); } const auto& expr = args[0].expression(); reference arg0 = args[1].value(); if (!arg0.is_array()) { ec = jmespath_errc::invalid_type; return context.null_value(); } auto result = context.create_json(json_array_arg); for (auto& item : arg0.array_range()) { auto& j = expr.evaluate(item, context, ec); if (JSONCONS_UNLIKELY(ec)) { ec = jmespath_errc::invalid_type; return context.null_value(); } result->emplace_back(json_const_pointer_arg, std::addressof(j)); } return *result; } }; class min_function : public function_base { public: min_function() : function_base(1) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!args[0].is_value()) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); if (!arg0.is_array()) { ec = jmespath_errc::invalid_type; return context.null_value(); } if (arg0.empty()) { return context.null_value(); } bool is_number = arg0.at(0).is_number(); bool is_string = arg0.at(0).is_string(); if (!is_number && !is_string) { ec = jmespath_errc::invalid_type; return context.null_value(); } std::size_t index = 0; for (std::size_t i = 1; i < arg0.size(); ++i) { if (!(arg0.at(i).is_number() == is_number && arg0.at(i).is_string() == is_string)) { ec = jmespath_errc::invalid_type; return context.null_value(); } if (arg0.at(i) < arg0.at(index)) { index = i; } } return arg0.at(index); } }; class min_by_function : public function_base { public: min_by_function() : function_base(2) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!(args[0].is_value() && args[1].is_expression())) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); if (!arg0.is_array()) { ec = jmespath_errc::invalid_type; return context.null_value(); } if (arg0.empty()) { return context.null_value(); } const auto& expr = args[1].expression(); std::error_code ec2; Json key1 = expr.evaluate(arg0.at(0), context, ec2); bool is_number = key1.is_number(); bool is_string = key1.is_string(); if (!(is_number || is_string)) { ec = jmespath_errc::invalid_type; return context.null_value(); } std::size_t index = 0; for (std::size_t i = 1; i < arg0.size(); ++i) { reference key2 = expr.evaluate(arg0.at(i), context, ec2); if (!(key2.is_number() == is_number && key2.is_string() == is_string)) { ec = jmespath_errc::invalid_type; return context.null_value(); } if (key2 < key1) { key1 = key2; index = i; } } return arg0.at(index); } }; class merge_function : public function_base { public: merge_function() : function_base(jsoncons::optional()) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { if (args.empty()) { ec = jmespath_errc::invalid_arity; return context.null_value(); } for (auto& param : args) { if (!param.is_value()) { ec = jmespath_errc::invalid_type; return context.null_value(); } } reference arg0 = args[0].value(); if (!arg0.is_object()) { ec = jmespath_errc::invalid_type; return context.null_value(); } if (args.size() == 1) { return arg0; } auto result = context.create_json(arg0); for (std::size_t i = 1; i < args.size(); ++i) { reference argi = args[i].value(); if (!argi.is_object()) { ec = jmespath_errc::invalid_type; return context.null_value(); } for (auto& item : argi.object_range()) { result->insert_or_assign(item.key(),item.value()); } } return *result; } }; class type_function : public function_base { public: type_function() : function_base(1) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!args[0].is_value()) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); switch (arg0.type()) { case json_type::int64_value: case json_type::uint64_value: case json_type::double_value: return context.number_type_name(); case json_type::bool_value: return context.boolean_type_name(); case json_type::string_value: return context.string_type_name(); case json_type::object_value: return context.object_type_name(); case json_type::array_value: return context.array_type_name(); default: return context.null_type_name(); break; } } }; class sort_function : public function_base { public: sort_function() : function_base(1) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!args[0].is_value()) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); if (!arg0.is_array()) { ec = jmespath_errc::invalid_type; return context.null_value(); } if (arg0.size() <= 1) { return arg0; } bool is_number = arg0.at(0).is_number(); bool is_string = arg0.at(0).is_string(); if (!is_number && !is_string) { ec = jmespath_errc::invalid_type; return context.null_value(); } for (std::size_t i = 1; i < arg0.size(); ++i) { if (arg0.at(i).is_number() != is_number || arg0.at(i).is_string() != is_string) { ec = jmespath_errc::invalid_type; return context.null_value(); } } auto v = context.create_json(arg0); std::stable_sort((v->array_range()).begin(), (v->array_range()).end()); return *v; } }; class sort_by_function : public function_base { public: sort_by_function() : function_base(2) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!(args[0].is_value() && args[1].is_expression())) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); if (!arg0.is_array()) { ec = jmespath_errc::invalid_type; return context.null_value(); } if (arg0.size() <= 1) { return arg0; } const auto& expr = args[1].expression(); auto v = context.create_json(arg0); std::stable_sort((v->array_range()).begin(), (v->array_range()).end(), [&expr,&context,&ec](reference lhs, reference rhs) -> bool { std::error_code ec2; reference key1 = expr.evaluate(lhs, context, ec2); bool is_number = key1.is_number(); bool is_string = key1.is_string(); if (!(is_number || is_string)) { ec = jmespath_errc::invalid_type; } reference key2 = expr.evaluate(rhs, context, ec2); if (!(key2.is_number() == is_number && key2.is_string() == is_string)) { ec = jmespath_errc::invalid_type; } return key1 < key2; }); return ec ? context.null_value() : *v; } }; class keys_function final : public function_base { public: keys_function() : function_base(1) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!args[0].is_value()) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); if (!arg0.is_object()) { ec = jmespath_errc::invalid_type; return context.null_value(); } auto result = context.create_json(json_array_arg); result->reserve(args.size()); for (auto& item : arg0.object_range()) { result->emplace_back(item.key()); } return *result; } }; class values_function final : public function_base { public: values_function() : function_base(1) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!args[0].is_value()) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); if (!arg0.is_object()) { ec = jmespath_errc::invalid_type; return context.null_value(); } auto result = context.create_json(json_array_arg); result->reserve(args.size()); for (auto& item : arg0.object_range()) { result->emplace_back(item.value()); } return *result; } }; class reverse_function final : public function_base { public: reverse_function() : function_base(1) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!args[0].is_value()) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); switch (arg0.type()) { case json_type::string_value: { string_view_type sv = arg0.as_string_view(); std::basic_string buf; unicode_traits::convert(sv.data(), sv.size(), buf); std::reverse(buf.begin(), buf.end()); string_type s; unicode_traits::convert(buf.data(), buf.size(), s); return *context.create_json(s); } case json_type::array_value: { auto result = context.create_json(arg0); std::reverse(result->array_range().begin(),result->array_range().end()); return *result; } default: ec = jmespath_errc::invalid_type; return context.null_value(); } } }; class starts_with_function : public function_base { public: starts_with_function() : function_base(2) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!(args[0].is_value() && args[1].is_value())) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); if (!arg0.is_string()) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg1 = args[1].value(); if (!arg1.is_string()) { ec = jmespath_errc::invalid_type; return context.null_value(); } auto sv0 = arg0.template as(); auto sv1 = arg1.template as(); if (sv1.length() <= sv0.length() && sv1 == sv0.substr(0, sv1.length())) { return context.true_value(); } else { return context.false_value(); } } }; class sum_function : public function_base { public: sum_function() : function_base(1) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!args[0].is_value()) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); if (!arg0.is_array()) { ec = jmespath_errc::invalid_type; return context.null_value(); } double sum = 0; for (auto& j : arg0.array_range()) { if (!j.is_number()) { ec = jmespath_errc::invalid_type; return context.null_value(); } sum += j.template as(); } return *context.create_json(sum); } }; class to_array_function final : public function_base { public: to_array_function() : function_base(1) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!args[0].is_value()) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); if (arg0.is_array()) { return arg0; } else { auto result = context.create_json(json_array_arg); result->push_back(arg0); return *result; } } }; class to_number_function final : public function_base { public: to_number_function() : function_base(1) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!args[0].is_value()) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); switch (arg0.type()) { case json_type::int64_value: case json_type::uint64_value: case json_type::double_value: return arg0; case json_type::string_value: { auto sv = arg0.as_string_view(); uint64_t uval{ 0 }; auto result1 = jsoncons::detail::to_integer(sv.data(), sv.length(), uval); if (result1) { return *context.create_json(uval); } int64_t sval{ 0 }; auto result2 = jsoncons::detail::to_integer(sv.data(), sv.length(), sval); if (result2) { return *context.create_json(sval); } const jsoncons::detail::chars_to to_double; try { auto s = arg0.as_string(); double d = to_double(s.c_str(), s.length()); return *context.create_json(d); } catch (const std::exception&) { return context.null_value(); } } default: return context.null_value(); } } }; class to_string_function final : public function_base { public: to_string_function() : function_base(1) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code& ec) const override { JSONCONS_ASSERT(args.size() == *this->arity()); if (!args[0].is_value()) { ec = jmespath_errc::invalid_type; return context.null_value(); } reference arg0 = args[0].value(); return *context.create_json(arg0.template as()); } }; class not_null_function final : public function_base { public: not_null_function() : function_base(jsoncons::optional()) { } reference evaluate(const std::vector& args, eval_context& context, std::error_code&) const override { for (auto& param : args) { if (param.is_value() && !param.value().is_null()) { return param.value(); } } return context.null_value(); } }; static pointer evaluate_tokens(reference doc, const std::vector>& output_stack, eval_context& context, std::error_code& ec) { pointer root_ptr = std::addressof(doc); std::vector stack; std::vector arg_stack; for (std::size_t i = 0; i < output_stack.size(); ++i) { auto& t = output_stack[i]; switch (t.type()) { case token_kind::literal: { stack.emplace_back(t.value_); break; } case token_kind::begin_expression_type: { JSONCONS_ASSERT(i+1 < output_stack.size()); ++i; JSONCONS_ASSERT(output_stack[i].is_expression()); JSONCONS_ASSERT(!stack.empty()); stack.pop_back(); stack.emplace_back(*output_stack[i].expression_); break; } case token_kind::pipe: { JSONCONS_ASSERT(!stack.empty()); root_ptr = std::addressof(stack.back().value()); break; } case token_kind::current_node: stack.emplace_back(*root_ptr); break; case token_kind::expression: { JSONCONS_ASSERT(!stack.empty()); pointer ptr = std::addressof(stack.back().value()); stack.pop_back(); auto& ref = t.expression_->evaluate(*ptr, context, ec); stack.emplace_back(ref); break; } case token_kind::variable: { auto& ref = t.expression_->evaluate(doc, context, ec); context.set_variable(t.key_, ref); break; } case token_kind::variable_binding: { JSONCONS_ASSERT(!stack.empty()); stack.pop_back(); const auto& j = context.get_variable(t.key_, ec); if (JSONCONS_UNLIKELY(ec)) { ec = jmespath_errc::undefined_variable; return std::addressof(context.null_value()); } stack.push_back(j); break; } case token_kind::unary_operator: { JSONCONS_ASSERT(!stack.empty()); pointer ptr = std::addressof(stack.back().value()); stack.pop_back(); reference r = t.unary_operator_->evaluate(*ptr, context, ec); stack.emplace_back(r); break; } case token_kind::binary_operator: { JSONCONS_ASSERT(stack.size() >= 2); pointer rhs = std::addressof(stack.back().value()); stack.pop_back(); pointer lhs = std::addressof(stack.back().value()); stack.pop_back(); reference r = t.binary_operator_->evaluate(*lhs,*rhs, context, ec); stack.emplace_back(r); break; } case token_kind::argument: { JSONCONS_ASSERT(!stack.empty()); arg_stack.push_back(std::move(stack.back())); stack.pop_back(); break; } case token_kind::function: { if (t.function_->arity() && *(t.function_->arity()) != arg_stack.size()) { ec = jmespath_errc::invalid_arity; return std::addressof(context.null_value()); } std::vector> expr_wrappers; if (t.function_->is_custom()) { if (expr_wrappers.empty()) { expr_wrappers.resize(arg_stack.size()); } for (std::size_t k = 0; k < arg_stack.size(); ++k) { if (arg_stack[k].is_expression()) { expr_wrappers[k] = expr_wrapper{ *(arg_stack[k].expression_) }; arg_stack[k].expression_ = std::addressof(expr_wrappers[k]); } } } reference r = t.function_->evaluate(arg_stack, context, ec); if (JSONCONS_UNLIKELY(ec)) { return std::addressof(context.null_value()); } arg_stack.clear(); stack.emplace_back(r); break; } default: break; } } JSONCONS_ASSERT(stack.size() == 1); return std::addressof(stack.back().value()); } // Implementations class or_operator final : public binary_operator { public: or_operator() : binary_operator(operator_kind::or_op) { } reference evaluate(reference lhs, reference rhs, eval_context& context, std::error_code&) const override { if (lhs.is_null() && rhs.is_null()) { return context.null_value(); } if (!is_false(lhs)) { return lhs; } else { return rhs; } } }; class and_operator final : public binary_operator { public: and_operator() : binary_operator(operator_kind::and_op) { } reference evaluate(reference lhs, reference rhs, eval_context&, std::error_code&) const override { if (is_true(lhs)) { return rhs; } else { return lhs; } } }; class eq_operator final : public binary_operator { public: eq_operator() : binary_operator(operator_kind::eq_op) { } reference evaluate(reference lhs, reference rhs, eval_context& context, std::error_code&) const override { return lhs == rhs ? context.true_value() : context.false_value(); } }; class ne_operator final : public binary_operator { public: ne_operator() : binary_operator(operator_kind::ne_op) { } reference evaluate(reference lhs, reference rhs, eval_context& context, std::error_code&) const override { return lhs != rhs ? context.true_value() : context.false_value(); } }; class lt_operator final : public binary_operator { public: lt_operator() : binary_operator(operator_kind::lt_op) { } reference evaluate(reference lhs, reference rhs, eval_context& context, std::error_code&) const override { if (!(lhs.is_number() && rhs.is_number())) { return context.null_value(); } return lhs < rhs ? context.true_value() : context.false_value(); } }; class lte_operator final : public binary_operator { public: lte_operator() : binary_operator(operator_kind::lte_op) { } reference evaluate(reference lhs, reference rhs, eval_context& context, std::error_code&) const override { if (!(lhs.is_number() && rhs.is_number())) { return context.null_value(); } return lhs <= rhs ? context.true_value() : context.false_value(); } }; class gt_operator final : public binary_operator { public: gt_operator() : binary_operator(operator_kind::gt_op) { } reference evaluate(reference lhs, reference rhs, eval_context& context, std::error_code&) const override { if (!(lhs.is_number() && rhs.is_number())) { return context.null_value(); } return lhs > rhs ? context.true_value() : context.false_value(); } }; class gte_operator final : public binary_operator { public: gte_operator() : binary_operator(operator_kind::gte_op) { } reference evaluate(reference lhs, reference rhs, eval_context& context, std::error_code&) const override { if (!(lhs.is_number() && rhs.is_number())) { return context.null_value(); } return lhs >= rhs ? context.true_value() : context.false_value(); } }; // basic_expression class basic_expression : public expression_type { public: basic_expression() : expression_type(operator_kind::default_op, false) { } void add_expression(expression_type*) override { } }; class identifier_selector final : public basic_expression { private: string_type identifier_; public: identifier_selector(const string_view_type& name) : identifier_(name) { } reference evaluate(reference val, eval_context& context, std::error_code&) const override { //std::cout << "(identifier_selector " << identifier_ << " ) " << pretty_print(val) << "\n"; if (val.is_object() && val.contains(identifier_)) { return val.at(identifier_); } else { return context.null_value(); } } }; class current_node final : public basic_expression { public: current_node() { } reference evaluate(reference val, eval_context&, std::error_code&) const override { return val; } }; class index_selector final : public basic_expression { int64_t index_; public: index_selector(int64_t index) : index_(index) { } reference evaluate(reference val, eval_context& context, std::error_code&) const override { if (!val.is_array()) { return context.null_value(); } auto slen = static_cast(val.size()); if (index_ >= 0 && index_ < slen) { std::size_t index = static_cast(index_); return val.at(index); } else if ((slen + index_) >= 0 && (slen+index_) < slen) { std::size_t index = static_cast(slen + index_); return val.at(index); } else { return context.null_value(); } } }; // projection_base class projection_base : public expression_type { protected: std::vector expressions_; public: projection_base(operator_kind oper) : expression_type(oper, true) { } void add_expression(expression_type* expr) override { if (!expressions_.empty() && expressions_.back()->is_projection() && (expr->precedence_level() < expressions_.back()->precedence_level() || (expr->precedence_level() == expressions_.back()->precedence_level() && expr->is_right_associative()))) { expressions_.back()->add_expression(expr); } else { expressions_.emplace_back(expr); } } reference apply_expressions(reference val, eval_context& context, std::error_code& ec) const { pointer ptr = std::addressof(val); for (auto& expression : expressions_) { ptr = std::addressof(expression->evaluate(*ptr, context, ec)); } return *ptr; } }; class object_projection final : public projection_base { public: object_projection() : projection_base(operator_kind::projection_op) { } reference evaluate(reference val, eval_context& context, std::error_code& ec) const override { if (!val.is_object()) { return context.null_value(); } auto result = context.create_json(json_array_arg); for (auto& item : val.object_range()) { if (!item.value().is_null()) { reference j = this->apply_expressions(item.value(), context, ec); if (!j.is_null()) { result->emplace_back(json_const_pointer_arg, std::addressof(j)); } } } return *result; } }; class list_projection final : public projection_base { public: list_projection() : projection_base(operator_kind::projection_op) { } reference evaluate(reference val, eval_context& context, std::error_code& ec) const override { if (!val.is_array()) { return context.null_value(); } auto result = context.create_json(json_array_arg); for (reference item : val.array_range()) { if (!item.is_null()) { reference j = this->apply_expressions(item, context, ec); if (!j.is_null()) { result->emplace_back(json_const_pointer_arg, std::addressof(j)); } } } return *result; } }; class slice_projection final : public projection_base { slice slice_; public: slice_projection(const slice& s) : projection_base(operator_kind::projection_op), slice_(s) { } reference evaluate(reference val, eval_context& context, std::error_code& ec) const override { if (!val.is_array()) { return context.null_value(); } auto start = slice_.get_start(val.size()); auto end = slice_.get_stop(val.size()); auto step = slice_.step(); if (step == 0) { ec = jmespath_errc::step_cannot_be_zero; return context.null_value(); } auto result = context.create_json(json_array_arg); if (step > 0) { if (start < 0) { start = 0; } if (end > static_cast(val.size())) { end = val.size(); } for (int64_t i = start; i < end; i += step) { reference j = this->apply_expressions(val.at(static_cast(i)), context, ec); if (!j.is_null()) { result->emplace_back(json_const_pointer_arg, std::addressof(j)); } } } else { if (start >= static_cast(val.size())) { start = static_cast(val.size()) - 1; } if (end < -1) { end = -1; } for (int64_t i = start; i > end; i += step) { reference j = this->apply_expressions(val.at(static_cast(i)), context, ec); if (!j.is_null()) { result->emplace_back(json_const_pointer_arg, std::addressof(j)); } } } return *result; } }; class filter_expression final : public projection_base { std::vector> token_list_; public: filter_expression(std::vector>&& token_list) : projection_base(operator_kind::projection_op), token_list_(std::move(token_list)) { } reference evaluate(reference val, eval_context& context, std::error_code& ec) const override { if (!val.is_array()) { return context.null_value(); } auto result = context.create_json(json_array_arg); for (auto& item : val.array_range()) { eval_context new_context{ context.temp_storage_, context.variables_ }; Json j(json_const_pointer_arg, evaluate_tokens(item, token_list_, new_context, ec)); if (is_true(j)) { reference jj = this->apply_expressions(item, context, ec); if (!jj.is_null()) { result->emplace_back(json_const_pointer_arg, std::addressof(jj)); } } } return *result; } }; class flatten_projection final : public projection_base { public: flatten_projection() : projection_base(operator_kind::flatten_projection_op) { } reference evaluate(reference val, eval_context& context, std::error_code& ec) const override { if (!val.is_array()) { return context.null_value(); } auto result = context.create_json(json_array_arg); for (reference current_elem : val.array_range()) { if (current_elem.is_array()) { for (reference elem : current_elem.array_range()) { if (!elem.is_null()) { reference j = this->apply_expressions(elem, context, ec); if (!j.is_null()) { result->emplace_back(json_const_pointer_arg, std::addressof(j)); } } } } else { if (!current_elem.is_null()) { reference j = this->apply_expressions(current_elem, context, ec); if (!j.is_null()) { result->emplace_back(json_const_pointer_arg, std::addressof(j)); } } } } return *result; } }; class multi_select_list final : public basic_expression { std::vector>> token_lists_; public: multi_select_list(std::vector>>&& token_lists) : token_lists_(std::move(token_lists)) { } reference evaluate(reference val, eval_context& context, std::error_code& ec) const override { if (val.is_null()) { return val; } auto result = context.create_json(json_array_arg); result->reserve(token_lists_.size()); for (auto& list : token_lists_) { eval_context new_context{ context.temp_storage_, context.variables_ }; result->emplace_back(json_const_pointer_arg, evaluate_tokens(val, list, new_context, ec)); } return *result; } }; class variable_expression final : public basic_expression { std::vector> tokens_; public: variable_expression(std::vector>&& tokens) : tokens_(std::move(tokens)) { } reference evaluate(reference val, eval_context& context, std::error_code& ec) const override { eval_context new_context{ context.temp_storage_, context.variables_ }; auto ptr = evaluate_tokens(val, tokens_, new_context, ec); return *ptr; } }; struct key_tokens { string_type key; std::vector> tokens; key_tokens(string_type&& Key, std::vector>&& Tokens) noexcept : key(std::move(Key)), tokens(std::move(Tokens)) { } }; class multi_select_hash final : public basic_expression { public: std::vector key_toks_; multi_select_hash(std::vector&& key_toks) : key_toks_(std::move(key_toks)) { } reference evaluate(reference val, eval_context& context, std::error_code& ec) const override { if (val.is_null()) { return val; } auto resultp = context.create_json(json_object_arg); resultp->reserve(key_toks_.size()); for (auto& item : key_toks_) { eval_context new_context{ context.temp_storage_, context.variables_ }; resultp->try_emplace(item.key, json_const_pointer_arg, evaluate_tokens(val, item.tokens, new_context, ec)); } return *resultp; } }; class function_expression final : public basic_expression { public: std::vector> toks_; function_expression(std::vector>&& toks) : toks_(std::move(toks)) { } reference evaluate(reference val, eval_context& context, std::error_code& ec) const override { eval_context new_context{ context.temp_storage_, context.variables_ }; return *evaluate_tokens(val, toks_, new_context, ec); } }; class static_resources { struct MyHash { std::uintmax_t operator()(string_type const& s) const noexcept { const int p = 31; const int m = static_cast(1e9) + 9; std::uintmax_t hash_value = 0; std::uintmax_t p_pow = 1; for (char_type c : s) { hash_value = (hash_value + (c - 'a' + 1) * p_pow) % m; p_pow = (p_pow * p) % m; } return hash_value; } }; std::unordered_map>,MyHash> custom_functions_; std::vector>> expr_storage_; public: static_resources() = default; static_resources(const static_resources& expr) = delete; static_resources& operator=(const static_resources& expr) = delete; static_resources(static_resources&& expr) = default; static_resources& operator=(static_resources&& expr) = default; static_resources(const custom_functions& functions) : static_resources{} { for (const auto& item : functions) { custom_functions_.emplace(item.name(), jsoncons::make_unique>(item.arity(),item.function())); } } template expr_base_impl* create_expression(T&& val) { auto temp = jsoncons::make_unique(std::forward(val)); expr_base_impl* ptr = temp.get(); expr_storage_.push_back(std::move(temp)); return ptr; } const function_base* get_function(const string_type& name, std::error_code& ec) const { static abs_function abs_func; static avg_function avg_func; static ceil_function ceil_func; static contains_function contains_func; static ends_with_function ends_with_func; static floor_function floor_func; static join_function join_func; static length_function length_func; static max_function max_func; static max_by_function max_by_func; static map_function map_func; static merge_function merge_func; static min_function min_func; static min_by_function min_by_func; static type_function type_func; static sort_function sort_func; static sort_by_function sort_by_func; static keys_function keys_func; static values_function values_func; static reverse_function reverse_func; static starts_with_function starts_with_func; static const sum_function sum_func; static to_array_function to_array_func; static to_number_function to_number_func; static to_string_function to_string_func; static not_null_function not_null_func; using function_dictionary = std::unordered_map*>; static const function_dictionary functions_ = { {string_type{'a','b','s'}, &abs_func}, {string_type{'a','v','g'}, &avg_func}, {string_type{'c','e','i', 'l'}, &ceil_func}, {string_type{'c','o','n', 't', 'a', 'i', 'n', 's'}, &contains_func}, {string_type{'e','n','d', 's', '_', 'w', 'i', 't', 'h'}, &ends_with_func}, {string_type{'f','l','o', 'o', 'r'}, &floor_func}, {string_type{'j','o','i', 'n'}, &join_func}, {string_type{'l','e','n', 'g', 't', 'h'}, &length_func}, {string_type{'m','a','x'}, &max_func}, {string_type{'m','a','x','_','b','y'}, &max_by_func}, {string_type{'m','a','p'}, &map_func}, {string_type{'m','i','n'}, &min_func}, {string_type{'m','i','n','_','b','y'}, &min_by_func}, {string_type{'m','e','r', 'g', 'e'}, &merge_func}, {string_type{'t','y','p', 'e'}, &type_func}, {string_type{'s','o','r', 't'}, &sort_func}, {string_type{'s','o','r', 't','_','b','y'}, &sort_by_func}, {string_type{'k','e','y', 's'}, &keys_func}, {string_type{'v','a','l', 'u','e','s'}, &values_func}, {string_type{'r','e','v', 'e', 'r', 's','e'}, &reverse_func}, {string_type{'s','t','a', 'r','t','s','_','w','i','t','h'}, &starts_with_func}, {string_type{'s','u','m'}, &sum_func}, {string_type{'t','o','_','a','r','r','a','y',}, &to_array_func}, {string_type{'t','o','_', 'n', 'u', 'm','b','e','r'}, &to_number_func}, {string_type{'t','o','_', 's', 't', 'r','i','n','g'}, &to_string_func}, {string_type{'n','o','t', '_', 'n', 'u','l','l'}, ¬_null_func} }; auto it = functions_.find(name); if (it != functions_.end()) { return (*it).second; } auto it2 = custom_functions_.find(name); if (it2 == custom_functions_.end()) { ec = jmespath_errc::unknown_function; return nullptr; } return it2->second.get(); } const unary_operator* get_not_operator() const { static const not_expression not_oper; return ¬_oper; } const binary_operator* get_or_operator() const { static const or_operator or_oper; return &or_oper; } const binary_operator* get_and_operator() const { static const and_operator and_oper; return &and_oper; } const binary_operator* get_eq_operator() const { static const eq_operator eq_oper; return &eq_oper; } const binary_operator* get_ne_operator() const { static const ne_operator ne_oper; return &ne_oper; } const binary_operator* get_lt_operator() const { static const lt_operator lt_oper; return <_oper; } const binary_operator* get_lte_operator() const { static const lte_operator lte_oper; return <e_oper; } const binary_operator* get_gt_operator() const { static const gt_operator gt_oper; return >_oper; } const binary_operator* get_gte_operator() const { static const gte_operator gte_oper; return >e_oper; } }; class jmespath_expression { public: static_resources resources_; std::vector> output_stack_; public: jmespath_expression() = default; jmespath_expression(const jmespath_expression& expr) = delete; jmespath_expression& operator=(const jmespath_expression& expr) = delete; jmespath_expression(jmespath_expression&& expr) : resources_(std::move(expr.resources_)), output_stack_(std::move(expr.output_stack_)) { } jmespath_expression(static_resources&& resources, std::vector>&& output_stack) : resources_(std::move(resources)), output_stack_(std::move(output_stack)) { } Json evaluate(reference doc) const { if (output_stack_.empty()) { return Json::null(); } std::error_code ec; Json result = evaluate(doc, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(jmespath_error(ec)); } return result; } Json evaluate(reference doc, const std::map& params) const { if (output_stack_.empty()) { return Json::null(); } std::error_code ec; Json result = evaluate(doc, params, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(jmespath_error(ec)); } return result; } Json evaluate(reference doc, std::error_code& ec) const { if (output_stack_.empty()) { return Json::null(); } std::vector> temp_storage; eval_context context{temp_storage}; return deep_copy(*evaluate_tokens(doc, output_stack_, context, ec)); } Json evaluate(reference doc, const std::map& params, std::error_code& ec) const { if (output_stack_.empty()) { return Json::null(); } std::vector> temp_storage; eval_context context{temp_storage}; for (const auto& param : params) { context.set_variable(param.first, param.second); } return deep_copy(*evaluate_tokens(doc, output_stack_, context, ec)); } }; public: std::size_t line_{1}; std::size_t column_{1}; const char_type* begin_input_{nullptr}; const char_type* end_input_{nullptr}; const char_type* p_{nullptr}; std::vector> operator_stack_; public: jmespath_evaluator() { } ~jmespath_evaluator() = default; std::size_t line() const { return line_; } std::size_t column() const { return column_; } jmespath_expression compile(const char_type* path, std::size_t length, const jsoncons::jmespath::custom_functions& funcs, std::error_code& ec) { static_resources resources{funcs}; std::vector> context_stack; std::vector state_stack; std::vector> output_stack; string_type key_buffer; state_stack.push_back(expr_state::start); string_type buffer; uint32_t cp = 0; uint32_t cp2 = 0; begin_input_ = path; end_input_ = path + length; p_ = begin_input_; slice slic{}; bool done = false; while (p_ < end_input_ && !done) { switch (state_stack.back()) { case expr_state::start: { state_stack.back() = expr_state::rhs_expression; state_stack.push_back(expr_state::lhs_expression); context_stack.push_back(expression_context{}); break; } case expr_state::rhs_expression: switch(*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '.': ++p_; ++column_; state_stack.push_back(expr_state::sub_expression); break; case '|': ++p_; ++column_; state_stack.push_back(expr_state::lhs_expression); state_stack.push_back(expr_state::expect_pipe_or_or); break; case '&': ++p_; ++column_; state_stack.push_back(expr_state::lhs_expression); state_stack.push_back(expr_state::expect_and); break; case '<': case '>': case '=': { state_stack.push_back(expr_state::lhs_expression); state_stack.push_back(expr_state::comparator_expression); break; } case '!': { ++p_; ++column_; state_stack.push_back(expr_state::lhs_expression); state_stack.push_back(expr_state::cmp_ne); break; } case '[': state_stack.push_back(expr_state::bracket_specifier); ++p_; ++column_; break; case ')': { state_stack.pop_back(); JSONCONS_ASSERT(!context_stack.empty()); context_stack.pop_back(); break; } default: if (state_stack.size() > 1) { state_stack.pop_back(); JSONCONS_ASSERT(!context_stack.empty()); context_stack.pop_back(); } else { ec = jmespath_errc::syntax_error; return jmespath_expression{}; } break; } break; case expr_state::comparator_expression: switch(*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '<': ++p_; ++column_; state_stack.back() = expr_state::cmp_lt_or_lte; break; case '>': ++p_; ++column_; state_stack.back() = expr_state::cmp_gt_or_gte; break; case '=': { ++p_; ++column_; state_stack.back() = expr_state::cmp_eq; break; } default: if (state_stack.size() > 1) { state_stack.pop_back(); } else { ec = jmespath_errc::syntax_error; return jmespath_expression{}; } break; } break; case expr_state::substitute_variable: { push_token(token{variable_binding_arg, buffer}, resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) { return jmespath_expression{}; } buffer.clear(); state_stack.pop_back(); break; } case expr_state::lhs_expression: { switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '\"': state_stack.back() = expr_state::val_expr; state_stack.push_back(expr_state::quoted_string); ++p_; ++column_; break; case '\'': state_stack.back() = expr_state::raw_string; ++p_; ++column_; break; case '`': state_stack.back() = expr_state::literal; ++p_; ++column_; break; case '{': push_token(begin_multi_select_hash_arg, resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.back() = expr_state::multi_select_hash; ++p_; ++column_; break; case '*': // wildcard push_token(token(resources.create_expression(object_projection())), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.pop_back(); ++p_; ++column_; break; case '(': { ++p_; ++column_; push_token(lparen_arg, resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.back() = expr_state::expect_rparen; state_stack.push_back(expr_state::rhs_expression); state_stack.push_back(expr_state::lhs_expression); context_stack.push_back(expression_context{}); break; } case '!': { ++p_; ++column_; push_token(token(resources.get_not_operator()), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} break; } case '@': ++p_; ++column_; push_token(resources.create_expression(current_node()), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.pop_back(); break; case '[': state_stack.back() = expr_state::bracket_specifier_or_multi_select_list; ++p_; ++column_; break; case '$': state_stack.back() = expr_state::substitute_variable; state_stack.push_back(expr_state::unquoted_string); buffer.clear(); ++p_; ++column_; break; default: if ((*p_ >= 'A' && *p_ <= 'Z') || (*p_ >= 'a' && *p_ <= 'z') || (*p_ == '_')) { buffer.clear(); state_stack.back() = expr_state::identifier_or_function_expr; state_stack.push_back(expr_state::unquoted_string); buffer.push_back(*p_); ++p_; ++column_; } else { ec = jmespath_errc::expected_identifier; return jmespath_expression{}; } break; }; break; } case expr_state::sub_expression: { switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '\"': state_stack.back() = expr_state::val_expr; state_stack.push_back(expr_state::quoted_string); ++p_; ++column_; break; case '{': push_token(begin_multi_select_hash_arg, resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.back() = expr_state::multi_select_hash; ++p_; ++column_; break; case '*': push_token(resources.create_expression(object_projection()), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.pop_back(); ++p_; ++column_; break; case '[': state_stack.back() = expr_state::expect_multi_select_list; ++p_; ++column_; break; default: if ((*p_ >= 'A' && *p_ <= 'Z') || (*p_ >= 'a' && *p_ <= 'z') || (*p_ == '_')) { buffer.clear(); state_stack.back() = expr_state::identifier_or_function_expr; state_stack.push_back(expr_state::unquoted_string); buffer.push_back(*p_); ++p_; ++column_; } else { ec = jmespath_errc::expected_identifier; return jmespath_expression{}; } break; }; break; } case expr_state::key_expr: push_token(token(key_arg, buffer), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} buffer.clear(); state_stack.pop_back(); break; case expr_state::val_expr: push_token(resources.create_expression(identifier_selector(buffer)), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} buffer.clear(); state_stack.pop_back(); break; case expr_state::expression_or_expression_type: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '&': state_stack.back() = expr_state::argument; if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} push_token(token(begin_expression_type_arg), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.push_back(expr_state::expression_type); state_stack.push_back(expr_state::rhs_expression); state_stack.push_back(expr_state::lhs_expression); context_stack.push_back(expression_context{}); ++p_; ++column_; break; default: state_stack.back() = expr_state::argument; if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.push_back(expr_state::rhs_expression); state_stack.push_back(expr_state::lhs_expression); context_stack.push_back(expression_context{}); break; } break; case expr_state::expect_in_or_comma: { //std::cout << "expr_state::expect_in_or_comma\n"; advance_past_space_character(); if (*p_ == ',') { std::vector> toks; for (std::size_t i = context_stack.back().end_index; i < output_stack.size(); ++i) { toks.push_back(std::move(output_stack[i])); } output_stack.erase(output_stack.begin() + context_stack.back().end_index, output_stack.end()); JSONCONS_ASSERT(!toks.empty()); if (toks.front().type() != token_kind::literal) { toks.emplace(toks.begin(), current_node_arg); } push_token(token{ context_stack.back().variable_ref, resources.create_expression(variable_expression(std::move(toks))) }, resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) { return jmespath_expression{}; } state_stack.back() = expr_state::variable_binding; ++p_; ++column_; } else if (*p_ == 'i' && (p_ + 1) < end_input_ && *(p_ + 1) == 'n') { p_ += 2; column_ += 2; std::vector> toks; for (std::size_t i = context_stack.back().end_index; i < output_stack.size(); ++i) { toks.push_back(std::move(output_stack[i])); } output_stack.erase(output_stack.begin() + context_stack.back().end_index, output_stack.end()); JSONCONS_ASSERT(!toks.empty()); if (toks.front().type() != token_kind::literal) { toks.emplace(toks.begin(), current_node_arg); } push_token(token{ context_stack.back().variable_ref, resources.create_expression(variable_expression(std::move(toks))) }, resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) { return jmespath_expression{}; } state_stack.pop_back(); // pop expect_in_or_comma } else { ec = jmespath_errc::syntax_error; return jmespath_expression{}; } break; } case expr_state::expect_assign: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '=': { ++p_; ++column_; context_stack.back().end_index = output_stack.size(); context_stack.back().variable_ref = buffer; state_stack.back() = expr_state::expect_in_or_comma; state_stack.push_back(expr_state::rhs_expression); state_stack.push_back(expr_state::lhs_expression); context_stack.push_back(expression_context{}); buffer.clear(); break; } default: { ec = jmespath_errc::syntax_error; return jmespath_expression{}; } } break; case expr_state::variable_ref: state_stack.back() = expr_state::expect_assign; break; case expr_state::variable_binding: { //std::cout << "expr_state::variable_binding\n"; switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '$': state_stack.back() = expr_state::variable_ref; state_stack.push_back(expr_state::unquoted_string); buffer.clear(); ++p_; ++column_; break; default: { ec = jmespath_errc::syntax_error; return jmespath_expression{}; } } break; } case expr_state::identifier_or_function_expr: switch(*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '(': { auto f = resources.get_function(buffer, ec); if (JSONCONS_UNLIKELY(ec)) { return jmespath_expression{}; } buffer.clear(); push_token(token(f), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.back() = expr_state::function_expression; // check no-args function bool is_no_args_func = true; bool isEnd = false; for (const char_type *p2_ = p_ + 1; p2_ < end_input_ && !isEnd; ++p2_) { switch (*p2_) { case ' ':case '\t':case '\r':case '\n': break; case ')': isEnd = true; break; default: is_no_args_func = false; isEnd = true; break; } } if (!is_no_args_func) { push_token(lparen_arg, resources, output_stack, ec); state_stack.push_back(expr_state::expression_or_expression_type); } ++p_; ++column_; break; } case '$': { if (buffer.size() == 3 && buffer[0] == 'l' && buffer[1] == 'e' && buffer[2] == 't') { state_stack.back() = expr_state::lhs_expression; state_stack.push_back(expr_state::variable_binding); buffer.clear(); } else { ec = jmespath_errc::syntax_error; return jmespath_expression{}; } break; } default: { push_token(resources.create_expression(identifier_selector(buffer)), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} buffer.clear(); state_stack.pop_back(); break; } } break; case expr_state::function_expression: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ',': push_token(lparen_arg, resources, output_stack, ec); push_token(token(current_node_arg), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.push_back(expr_state::expression_or_expression_type); ++p_; ++column_; break; case ')': { push_token(token(end_function_arg), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.pop_back(); ++p_; ++column_; break; } default: break; } break; case expr_state::argument: push_token(argument_arg, resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.pop_back(); break; case expr_state::expression_type: push_token(end_expression_type_arg, resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) { return jmespath_expression{}; } state_stack.pop_back(); break; case expr_state::quoted_string: switch (*p_) { case '\"': state_stack.pop_back(); // quoted_string ++p_; ++column_; break; case '\\': state_stack.push_back(expr_state::quoted_string_escape_char); ++p_; ++column_; break; default: buffer.push_back(*p_); ++p_; ++column_; break; }; break; case expr_state::unquoted_string: switch (*p_) { case ' ':case '\t':case '\r':case '\n': state_stack.pop_back(); // unquoted_string advance_past_space_character(); break; default: if ((*p_ >= '0' && *p_ <= '9') || (*p_ >= 'A' && *p_ <= 'Z') || (*p_ >= 'a' && *p_ <= 'z') || (*p_ == '_')) { buffer.push_back(*p_); ++p_; ++column_; } else { state_stack.pop_back(); // unquoted_string } break; }; break; case expr_state::raw_string_escape_char: switch (*p_) { case '\'': buffer.push_back(*p_); state_stack.pop_back(); ++p_; ++column_; break; default: buffer.push_back('\\'); buffer.push_back(*p_); state_stack.pop_back(); ++p_; ++column_; break; } break; case expr_state::quoted_string_escape_char: switch (*p_) { case '\"': buffer.push_back('\"'); ++p_; ++column_; state_stack.pop_back(); break; case '\\': buffer.push_back('\\'); ++p_; ++column_; state_stack.pop_back(); break; case '/': buffer.push_back('/'); ++p_; ++column_; state_stack.pop_back(); break; case 'b': buffer.push_back('\b'); ++p_; ++column_; state_stack.pop_back(); break; case 'f': buffer.push_back('\f'); ++p_; ++column_; state_stack.pop_back(); break; case 'n': buffer.push_back('\n'); ++p_; ++column_; state_stack.pop_back(); break; case 'r': buffer.push_back('\r'); ++p_; ++column_; state_stack.pop_back(); break; case 't': buffer.push_back('\t'); ++p_; ++column_; state_stack.pop_back(); break; case 'u': ++p_; ++column_; state_stack.back() = expr_state::escape_u1; break; default: ec = jmespath_errc::illegal_escaped_character; return jmespath_expression{}; } break; case expr_state::escape_u1: cp = append_to_codepoint(0, *p_, ec); if (JSONCONS_UNLIKELY(ec)) { return jmespath_expression{}; } ++p_; ++column_; state_stack.back() = expr_state::escape_u2; break; case expr_state::escape_u2: cp = append_to_codepoint(cp, *p_, ec); if (JSONCONS_UNLIKELY(ec)) { return jmespath_expression{}; } ++p_; ++column_; state_stack.back() = expr_state::escape_u3; break; case expr_state::escape_u3: cp = append_to_codepoint(cp, *p_, ec); if (JSONCONS_UNLIKELY(ec)) { return jmespath_expression{}; } ++p_; ++column_; state_stack.back() = expr_state::escape_u4; break; case expr_state::escape_u4: cp = append_to_codepoint(cp, *p_, ec); if (JSONCONS_UNLIKELY(ec)) { return jmespath_expression{}; } if (unicode_traits::is_high_surrogate(cp)) { ++p_; ++column_; state_stack.back() = expr_state::escape_expect_surrogate_pair1; } else { unicode_traits::convert(&cp, 1, buffer); ++p_; ++column_; state_stack.pop_back(); } break; case expr_state::escape_expect_surrogate_pair1: switch (*p_) { case '\\': ++p_; ++column_; state_stack.back() = expr_state::escape_expect_surrogate_pair2; break; default: ec = jmespath_errc::invalid_codepoint; return jmespath_expression{}; } break; case expr_state::escape_expect_surrogate_pair2: switch (*p_) { case 'u': ++p_; ++column_; state_stack.back() = expr_state::escape_u5; break; default: ec = jmespath_errc::invalid_codepoint; return jmespath_expression{}; } break; case expr_state::escape_u5: cp2 = append_to_codepoint(0, *p_, ec); if (JSONCONS_UNLIKELY(ec)) { return jmespath_expression{}; } ++p_; ++column_; state_stack.back() = expr_state::escape_u6; break; case expr_state::escape_u6: cp2 = append_to_codepoint(cp2, *p_, ec); if (JSONCONS_UNLIKELY(ec)) { return jmespath_expression{}; } ++p_; ++column_; state_stack.back() = expr_state::escape_u7; break; case expr_state::escape_u7: cp2 = append_to_codepoint(cp2, *p_, ec); if (JSONCONS_UNLIKELY(ec)) { return jmespath_expression{}; } ++p_; ++column_; state_stack.back() = expr_state::escape_u8; break; case expr_state::escape_u8: { cp2 = append_to_codepoint(cp2, *p_, ec); if (JSONCONS_UNLIKELY(ec)) { return jmespath_expression{}; } uint32_t codepoint = 0x10000 + ((cp & 0x3FF) << 10) + (cp2 & 0x3FF); unicode_traits::convert(&codepoint, 1, buffer); state_stack.pop_back(); ++p_; ++column_; break; } case expr_state::raw_string: switch (*p_) { case '\'': { push_token(token(literal_arg, Json(buffer)), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} buffer.clear(); state_stack.pop_back(); // raw_string ++p_; ++column_; break; } case '\\': state_stack.push_back(expr_state::raw_string_escape_char); ++p_; ++column_; break; default: buffer.push_back(*p_); ++p_; ++column_; break; }; break; case expr_state::literal: switch (*p_) { case '`': { json_decoder decoder; basic_json_reader> reader(buffer, decoder); std::error_code parse_ec; reader.read(parse_ec); if (parse_ec) { ec = jmespath_errc::invalid_literal; return jmespath_expression{}; } auto j = decoder.get_result(); push_token(token(literal_arg, std::move(j)), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} buffer.clear(); state_stack.pop_back(); // json_value ++p_; ++column_; break; } case '\\': if (p_+1 < end_input_) { ++p_; ++column_; if (*p_ != '`') { buffer.push_back('\\'); } buffer.push_back(*p_); } else { ec = jmespath_errc::unexpected_end_of_input; return jmespath_expression{}; } ++p_; ++column_; break; default: buffer.push_back(*p_); ++p_; ++column_; break; }; break; case expr_state::number: switch(*p_) { case '-': buffer.push_back(*p_); state_stack.back() = expr_state::digit; ++p_; ++column_; break; default: state_stack.back() = expr_state::digit; break; } break; case expr_state::digit: switch(*p_) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': buffer.push_back(*p_); ++p_; ++column_; break; default: state_stack.pop_back(); // digit break; } break; case expr_state::bracket_specifier: switch(*p_) { case '*': push_token(resources.create_expression(list_projection()), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.back() = expr_state::expect_rbracket; ++p_; ++column_; break; case ']': // [] push_token(resources.create_expression(flatten_projection()), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.pop_back(); // bracket_specifier ++p_; ++column_; break; case '?': push_token(token(begin_filter_arg), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.back() = expr_state::filter; state_stack.push_back(expr_state::rhs_expression); state_stack.push_back(expr_state::lhs_expression); context_stack.push_back(expression_context{}); ++p_; ++column_; break; case ':': // slice_expression state_stack.back() = expr_state::rhs_slice_expression_stop ; state_stack.push_back(expr_state::number); ++p_; ++column_; break; // number case '-':case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': state_stack.back() = expr_state::index_or_slice_expression; state_stack.push_back(expr_state::number); break; default: ec = jmespath_errc::expected_index_expression; return jmespath_expression{}; } break; case expr_state::bracket_specifier_or_multi_select_list: switch(*p_) { case '*': if (p_+1 >= end_input_) { ec = jmespath_errc::unexpected_end_of_input; return jmespath_expression{}; } if (*(p_+1) == ']') { state_stack.back() = expr_state::bracket_specifier; } else { push_token(token(begin_multi_select_list_arg), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.back() = expr_state::multi_select_list; state_stack.push_back(expr_state::rhs_expression); state_stack.push_back(expr_state::lhs_expression); context_stack.push_back(expression_context{}); } break; case ']': // [] case '?': case ':': // slice_expression case '-':case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': state_stack.back() = expr_state::bracket_specifier; break; default: push_token(token(begin_multi_select_list_arg), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.back() = expr_state::multi_select_list; state_stack.push_back(expr_state::rhs_expression); state_stack.push_back(expr_state::lhs_expression); context_stack.push_back(expression_context{}); break; } break; case expr_state::expect_multi_select_list: switch(*p_) { case ']': case '?': case ':': case '-':case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': ec = jmespath_errc::expected_multi_select_list; return jmespath_expression{}; case '*': push_token(resources.create_expression(list_projection()), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.back() = expr_state::expect_rbracket; ++p_; ++column_; break; default: push_token(token(begin_multi_select_list_arg), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.back() = expr_state::multi_select_list; state_stack.push_back(expr_state::rhs_expression); state_stack.push_back(expr_state::lhs_expression); context_stack.push_back(expression_context{}); break; } break; case expr_state::multi_select_hash: switch(*p_) { case '*': case ']': case '?': case ':': case '-':case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': break; default: state_stack.back() = expr_state::key_val_expr; break; } break; case expr_state::index_or_slice_expression: switch(*p_) { case ']': { if (buffer.empty()) { push_token(resources.create_expression(flatten_projection()), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} } else { int64_t val{ 0 }; auto r = jsoncons::detail::to_integer(buffer.data(), buffer.size(), val); if (!r) { ec = jmespath_errc::invalid_number; return jmespath_expression{}; } push_token(resources.create_expression(index_selector(val)), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} buffer.clear(); } state_stack.pop_back(); // bracket_specifier ++p_; ++column_; break; } case ':': { if (!buffer.empty()) { int64_t val{}; auto r = jsoncons::detail::to_integer(buffer.data(), buffer.size(), val); if (!r) { ec = jmespath_errc::invalid_number; return jmespath_expression{}; } slic.start_ = val; buffer.clear(); } state_stack.back() = expr_state::rhs_slice_expression_stop; state_stack.push_back(expr_state::number); ++p_; ++column_; break; } default: ec = jmespath_errc::expected_rbracket; return jmespath_expression{}; } break; case expr_state::rhs_slice_expression_stop : { if (!buffer.empty()) { int64_t val{ 0 }; auto r = jsoncons::detail::to_integer(buffer.data(), buffer.size(), val); if (!r) { ec = jmespath_errc::invalid_number; return jmespath_expression{}; } slic.stop_ = jsoncons::optional(val); buffer.clear(); } switch(*p_) { case ']': push_token(resources.create_expression(slice_projection(slic)), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} slic = slice{}; state_stack.pop_back(); // bracket_specifier2 ++p_; ++column_; break; case ':': state_stack.back() = expr_state::rhs_slice_expression_step; state_stack.push_back(expr_state::number); ++p_; ++column_; break; default: ec = jmespath_errc::expected_rbracket; return jmespath_expression{}; } break; } case expr_state::rhs_slice_expression_step: { if (!buffer.empty()) { int64_t val{ 0 }; auto r = jsoncons::detail::to_integer(buffer.data(), buffer.size(), val); if (!r) { ec = jmespath_errc::invalid_number; return jmespath_expression{}; } if (val == 0) { ec = jmespath_errc::step_cannot_be_zero; return jmespath_expression{}; } slic.step_ = val; buffer.clear(); } switch(*p_) { case ']': push_token(resources.create_expression(slice_projection(slic)), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} buffer.clear(); slic = slice{}; state_stack.pop_back(); // rhs_slice_expression_step ++p_; ++column_; break; default: ec = jmespath_errc::expected_rbracket; return jmespath_expression{}; } break; } case expr_state::expect_rbracket: { switch(*p_) { case ']': state_stack.pop_back(); // expect_rbracket ++p_; ++column_; break; default: ec = jmespath_errc::expected_rbracket; return jmespath_expression{}; } break; } case expr_state::expect_rparen: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ')': ++p_; ++column_; push_token(rparen_arg, resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.pop_back(); break; default: ec = jmespath_errc::expected_rparen; return jmespath_expression{}; } break; case expr_state::key_val_expr: { switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '\"': state_stack.back() = expr_state::expect_colon; state_stack.push_back(expr_state::key_expr); state_stack.push_back(expr_state::quoted_string); ++p_; ++column_; break; case '\'': state_stack.back() = expr_state::expect_colon; state_stack.push_back(expr_state::raw_string); ++p_; ++column_; break; default: if ((*p_ >= 'A' && *p_ <= 'Z') || (*p_ >= 'a' && *p_ <= 'z') || (*p_ == '_')) { state_stack.back() = expr_state::expect_colon; state_stack.push_back(expr_state::key_expr); state_stack.push_back(expr_state::unquoted_string); buffer.push_back(*p_); ++p_; ++column_; } else { ec = jmespath_errc::expected_key; return jmespath_expression{}; } break; }; break; } case expr_state::cmp_lt_or_lte: { switch(*p_) { case '=': push_token(token(resources.get_lte_operator()), resources, output_stack, ec); push_token(token(current_node_arg), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.pop_back(); ++p_; ++column_; break; default: push_token(token(resources.get_lt_operator()), resources, output_stack, ec); push_token(token(current_node_arg), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.pop_back(); break; } break; } case expr_state::cmp_gt_or_gte: { switch(*p_) { case '=': push_token(token(resources.get_gte_operator()), resources, output_stack, ec); push_token(token(current_node_arg), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.pop_back(); ++p_; ++column_; break; default: push_token(token(resources.get_gt_operator()), resources, output_stack, ec); push_token(token(current_node_arg), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.pop_back(); break; } break; } case expr_state::cmp_eq: { switch(*p_) { case '=': push_token(token(resources.get_eq_operator()), resources, output_stack, ec); push_token(token(current_node_arg), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.pop_back(); ++p_; ++column_; break; default: ec = jmespath_errc::expected_comparator; return jmespath_expression{}; } break; } case expr_state::cmp_ne: { switch(*p_) { case '=': push_token(token(resources.get_ne_operator()), resources, output_stack, ec); push_token(token(current_node_arg), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.pop_back(); ++p_; ++column_; break; default: ec = jmespath_errc::expected_comparator; return jmespath_expression{}; } break; } case expr_state::expect_dot: { switch(*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '.': state_stack.pop_back(); // expect_dot ++p_; ++column_; break; default: ec = jmespath_errc::expected_dot; return jmespath_expression{}; } break; } case expr_state::expect_pipe_or_or: { switch(*p_) { case '|': push_token(token(resources.get_or_operator()), resources, output_stack, ec); push_token(token(current_node_arg), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.pop_back(); ++p_; ++column_; break; default: push_token(token(pipe_arg), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.pop_back(); break; } break; } case expr_state::expect_and: { switch(*p_) { case '&': push_token(token(resources.get_and_operator()), resources, output_stack, ec); push_token(token(current_node_arg), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.pop_back(); // expect_and ++p_; ++column_; break; default: ec = jmespath_errc::expected_and; return jmespath_expression{}; } break; } case expr_state::multi_select_list: { switch(*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ',': JSONCONS_ASSERT(!context_stack.empty()); push_token(token(separator_arg), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.push_back(expr_state::lhs_expression); ++p_; ++column_; break; case '[': state_stack.push_back(expr_state::lhs_expression); break; case '.': state_stack.push_back(expr_state::sub_expression); ++p_; ++column_; break; case '|': { ++p_; ++column_; state_stack.push_back(expr_state::lhs_expression); state_stack.push_back(expr_state::expect_pipe_or_or); break; } case ']': { push_token(token(end_multi_select_list_arg), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.pop_back(); ++p_; ++column_; break; } default: ec = jmespath_errc::expected_rbracket; return jmespath_expression{}; } break; } case expr_state::filter: { switch(*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ']': { push_token(token(end_filter_arg), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.pop_back(); ++p_; ++column_; break; } default: ec = jmespath_errc::expected_rbracket; return jmespath_expression{}; } break; } case expr_state::expect_rbrace: { switch(*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ',': push_token(token(separator_arg), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.back() = expr_state::key_val_expr; ++p_; ++column_; break; case '[': case '{': state_stack.push_back(expr_state::lhs_expression); break; case '.': state_stack.push_back(expr_state::sub_expression); ++p_; ++column_; break; case '}': { state_stack.pop_back(); push_token(end_multi_select_hash_arg, resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} ++p_; ++column_; break; } default: ec = jmespath_errc::expected_rbrace; return jmespath_expression{}; } break; } case expr_state::expect_colon: { switch(*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ':': state_stack.back() = expr_state::expect_rbrace; state_stack.push_back(expr_state::lhs_expression); ++p_; ++column_; break; default: ec = jmespath_errc::expected_colon; return jmespath_expression{}; } break; } } } if (state_stack.empty()) { ec = jmespath_errc::syntax_error; return jmespath_expression{}; } while (state_stack.size() > 1) { switch (state_stack.back()) { case expr_state::rhs_expression: state_stack.pop_back(); JSONCONS_ASSERT(!context_stack.empty()); context_stack.pop_back(); break; case expr_state::substitute_variable: { push_token(token{variable_binding_arg, buffer}, resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) { return jmespath_expression{}; } buffer.clear(); state_stack.pop_back(); break; } case expr_state::val_expr: push_token(resources.create_expression(identifier_selector(buffer)), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.pop_back(); break; case expr_state::identifier_or_function_expr: push_token(resources.create_expression(identifier_selector(buffer)), resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} state_stack.pop_back(); break; case expr_state::unquoted_string: state_stack.pop_back(); break; default: ec = jmespath_errc::syntax_error; return jmespath_expression{}; break; } } if (!(state_stack.back() == expr_state::rhs_expression)) { ec = jmespath_errc::unexpected_end_of_input; return jmespath_expression{}; } state_stack.pop_back(); JSONCONS_ASSERT(!context_stack.empty()); context_stack.pop_back(); push_token(end_of_expression_arg, resources, output_stack, ec); if (JSONCONS_UNLIKELY(ec)) {return jmespath_expression{};} JSONCONS_ASSERT(context_stack.empty()); if (output_stack.front().type() != token_kind::literal) { output_stack.insert(output_stack.begin(), token{current_node_arg}); } return jmespath_expression{ std::move(resources), std::move(output_stack) }; } void advance_past_space_character() { switch (*p_) { case ' ':case '\t': ++p_; ++column_; break; case '\r': if (p_+1 < end_input_) { if (*(p_ + 1) == '\n') ++p_; } ++line_; column_ = 1; ++p_; break; case '\n': ++line_; column_ = 1; ++p_; break; default: break; } } void unwind_rparen(std::vector>& output_stack, std::error_code& ec) { auto it = operator_stack_.rbegin(); while (it != operator_stack_.rend() && !(*it).is_lparen()) { output_stack.push_back(std::move(*it)); ++it; } if (it == operator_stack_.rend()) { ec = jmespath_errc::unbalanced_parentheses; return; } ++it; operator_stack_.erase(it.base(),operator_stack_.end()); if (output_stack.back().is_projection()) { output_stack.push_back(token(pipe_arg)); } } void push_token(token&& tok, static_resources& resources, std::vector>& output_stack, std::error_code& ec) { switch (tok.type()) { case token_kind::end_filter: { unwind_rparen(output_stack, ec); std::vector> toks; auto it = output_stack.rbegin(); while (it != output_stack.rend() && (*it).type() != token_kind::begin_filter) { toks.emplace_back(std::move(*it)); ++it; } if (it == output_stack.rend()) { ec = jmespath_errc::unbalanced_braces; return; } if (toks.back().type() != token_kind::literal) { toks.emplace_back(current_node_arg); } std::reverse(toks.begin(), toks.end()); ++it; output_stack.erase(it.base(),output_stack.end()); if (!output_stack.empty() && output_stack.back().is_projection() && (tok.precedence_level() < output_stack.back().precedence_level() || (tok.precedence_level() == output_stack.back().precedence_level() && tok.is_right_associative()))) { output_stack.back().expression_->add_expression(resources.create_expression(filter_expression(std::move(toks)))); } else { output_stack.push_back(resources.create_expression(filter_expression(std::move(toks)))); } break; } case token_kind::end_multi_select_list: { unwind_rparen(output_stack, ec); std::vector>> vals; auto it = output_stack.rbegin(); while (it != output_stack.rend() && (*it).type() != token_kind::begin_multi_select_list) { std::vector> toks; do { toks.emplace_back(std::move(*it)); ++it; } while (it != output_stack.rend() && (*it).type() != token_kind::begin_multi_select_list && (*it).type() != token_kind::separator); if ((*it).type() == token_kind::separator) { ++it; } if (toks.back().type() != token_kind::literal) { toks.emplace_back(current_node_arg); } std::reverse(toks.begin(), toks.end()); vals.emplace_back(std::move(toks)); } if (it == output_stack.rend()) { ec = jmespath_errc::unbalanced_braces; return; } ++it; output_stack.erase(it.base(),output_stack.end()); std::reverse(vals.begin(), vals.end()); if (!output_stack.empty() && output_stack.back().is_projection() && (tok.precedence_level() < output_stack.back().precedence_level() || (tok.precedence_level() == output_stack.back().precedence_level() && tok.is_right_associative()))) { output_stack.back().expression_->add_expression(resources.create_expression(multi_select_list(std::move(vals)))); } else { output_stack.push_back(resources.create_expression(multi_select_list(std::move(vals)))); } break; } case token_kind::end_multi_select_hash: { unwind_rparen(output_stack, ec); std::vector key_toks; auto it = output_stack.rbegin(); while (it != output_stack.rend() && (*it).type() != token_kind::begin_multi_select_hash) { std::vector> toks; do { toks.emplace_back(std::move(*it)); ++it; } while (it != output_stack.rend() && (*it).type() != token_kind::key); JSONCONS_ASSERT((*it).is_key()); auto key = std::move((*it).key_); ++it; if ((*it).type() == token_kind::separator) { ++it; } if (toks.back().type() != token_kind::literal) { toks.emplace_back(current_node_arg); } std::reverse(toks.begin(), toks.end()); key_toks.emplace_back(std::move(key), std::move(toks)); } if (it == output_stack.rend()) { ec = jmespath_errc::unbalanced_braces; return; } std::reverse(key_toks.begin(), key_toks.end()); ++it; output_stack.erase(it.base(),output_stack.end()); if (!output_stack.empty() && output_stack.back().is_projection() && (tok.precedence_level() < output_stack.back().precedence_level() || (tok.precedence_level() == output_stack.back().precedence_level() && tok.is_right_associative()))) { output_stack.back().expression_->add_expression(resources.create_expression(multi_select_hash(std::move(key_toks)))); } else { output_stack.push_back(resources.create_expression(multi_select_hash(std::move(key_toks)))); } break; } case token_kind::end_expression_type: { std::vector> toks; auto it = output_stack.rbegin(); while (it != output_stack.rend() && (*it).type() != token_kind::begin_expression_type) { toks.emplace_back(std::move(*it)); ++it; } if (it == output_stack.rend()) { JSONCONS_THROW(json_runtime_error("Unbalanced braces")); } if (toks.back().type() != token_kind::literal) { toks.emplace_back(current_node_arg); } std::reverse(toks.begin(), toks.end()); output_stack.erase(it.base(),output_stack.end()); output_stack.push_back(resources.create_expression(function_expression(std::move(toks)))); break; } case token_kind::variable: output_stack.push_back(std::move(tok)); break; case token_kind::variable_binding: output_stack.push_back(std::move(tok)); break; case token_kind::literal: if (!output_stack.empty() && output_stack.back().type() == token_kind::current_node) { output_stack.back() = std::move(tok); } else { output_stack.push_back(std::move(tok)); } break; case token_kind::expression: if (!output_stack.empty() && output_stack.back().is_projection() && (tok.precedence_level() < output_stack.back().precedence_level() || (tok.precedence_level() == output_stack.back().precedence_level() && tok.is_right_associative()))) { output_stack.back().expression_->add_expression(tok.expression_); } else { output_stack.push_back(std::move(tok)); } break; case token_kind::rparen: { unwind_rparen(output_stack, ec); break; } case token_kind::end_function: { unwind_rparen(output_stack, ec); std::vector> toks; auto it = output_stack.rbegin(); std::size_t arg_count = 0; while (it != output_stack.rend() && (*it).type() != token_kind::function) { if ((*it).type() == token_kind::argument) { ++arg_count; } toks.emplace_back(std::move(*it)); ++it; } if (it == output_stack.rend()) { ec = jmespath_errc::unbalanced_parentheses; return; } if ((*it).arity() && arg_count != *((*it).arity())) { ec = jmespath_errc::invalid_arity; return; } if (arg_count == 0) { toks.emplace_back(std::move(*it)); ++it; output_stack.erase(it.base(), output_stack.end()); output_stack.push_back(resources.create_expression(function_expression(std::move(toks)))); break; } if (toks.back().type() != token_kind::literal) { toks.emplace_back(current_node_arg); } std::reverse(toks.begin(), toks.end()); toks.push_back(std::move(*it)); ++it; output_stack.erase(it.base(),output_stack.end()); if (!output_stack.empty() && output_stack.back().is_projection() && (tok.precedence_level() < output_stack.back().precedence_level() || (tok.precedence_level() == output_stack.back().precedence_level() && tok.is_right_associative()))) { output_stack.back().expression_->add_expression(resources.create_expression(function_expression(std::move(toks)))); } else { output_stack.push_back(resources.create_expression(function_expression(std::move(toks)))); } break; } case token_kind::end_of_expression: { auto it = operator_stack_.rbegin(); while (it != operator_stack_.rend()) { output_stack.push_back(std::move(*it)); ++it; } operator_stack_.clear(); break; } case token_kind::unary_operator: case token_kind::binary_operator: { if (operator_stack_.empty() || operator_stack_.back().is_lparen()) { operator_stack_.emplace_back(std::move(tok)); } else if (tok.precedence_level() < operator_stack_.back().precedence_level() || (tok.precedence_level() == operator_stack_.back().precedence_level() && tok.is_right_associative())) { operator_stack_.emplace_back(std::move(tok)); } else { auto it = operator_stack_.rbegin(); while (it != operator_stack_.rend() && (*it).is_operator() && (tok.precedence_level() > (*it).precedence_level() || (tok.precedence_level() == (*it).precedence_level() && tok.is_right_associative()))) { output_stack.push_back(std::move(*it)); ++it; } operator_stack_.erase(it.base(),operator_stack_.end()); operator_stack_.emplace_back(std::move(tok)); } break; } case token_kind::separator: { unwind_rparen(output_stack, ec); output_stack.push_back(std::move(tok)); operator_stack_.emplace_back(token(lparen_arg)); break; } case token_kind::begin_filter: output_stack.push_back(std::move(tok)); operator_stack_.emplace_back(token(lparen_arg)); break; case token_kind::begin_multi_select_list: output_stack.push_back(std::move(tok)); operator_stack_.emplace_back(token(lparen_arg)); break; case token_kind::begin_multi_select_hash: output_stack.push_back(std::move(tok)); operator_stack_.emplace_back(token(lparen_arg)); break; case token_kind::function: output_stack.push_back(std::move(tok)); operator_stack_.emplace_back(token(lparen_arg)); break; case token_kind::current_node: output_stack.push_back(std::move(tok)); break; case token_kind::key: case token_kind::pipe: case token_kind::begin_expression_type: output_stack.push_back(std::move(tok)); break; case token_kind::argument: unwind_rparen(output_stack, ec); output_stack.push_back(std::move(tok)); break; case token_kind::lparen: operator_stack_.emplace_back(std::move(tok)); break; default: break; } } uint32_t append_to_codepoint(uint32_t cp, int c, std::error_code& ec) { cp *= 16; if (c >= '0' && c <= '9') { cp += c - '0'; } else if (c >= 'a' && c <= 'f') { cp += c - 'a' + 10; } else if (c >= 'A' && c <= 'F') { cp += c - 'A' + 10; } else { ec = jmespath_errc::invalid_codepoint; } return cp; } }; } // namespace detail template using jmespath_expression = typename jsoncons::jmespath::detail::jmespath_evaluator::jmespath_expression; template Json search(const Json& doc, const typename Json::string_view_type& path) { jsoncons::jmespath::detail::jmespath_evaluator evaluator; std::error_code ec; auto expr = evaluator.compile(path.data(), path.size(), jsoncons::jmespath::custom_functions{}, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(jmespath_error(ec, evaluator.line(), evaluator.column())); } auto result = expr.evaluate(doc, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(jmespath_error(ec)); } return result; } template Json search(const Json& doc, const typename Json::string_view_type& path, std::error_code& ec) { jsoncons::jmespath::detail::jmespath_evaluator evaluator; auto expr = evaluator.compile(path.data(), path.size(), jsoncons::jmespath::custom_functions{}, ec); if (JSONCONS_UNLIKELY(ec)) { return Json::null(); } auto result = expr.evaluate(doc, ec); if (JSONCONS_UNLIKELY(ec)) { return Json::null(); } return result; } template jmespath_expression make_expression(const typename Json::string_view_type& expr, const jsoncons::jmespath::custom_functions& funcs = jsoncons::jmespath::custom_functions()) { jsoncons::jmespath::detail::jmespath_evaluator evaluator{}; std::error_code ec; auto compiled = evaluator.compile(expr.data(), expr.size(), funcs, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(jmespath_error(ec, evaluator.line(), evaluator.column())); } return compiled; } template jmespath_expression make_expression(const typename Json::string_view_type& expr, std::error_code& ec) { jsoncons::jmespath::detail::jmespath_evaluator evaluator{}; return evaluator.compile(expr.data(), expr.size(), jsoncons::jmespath::custom_functions{}, ec); } template jmespath_expression make_expression(const typename Json::string_view_type& expr, const jsoncons::jmespath::custom_functions& funcs, std::error_code& ec) { jsoncons::jmespath::detail::jmespath_evaluator evaluator{}; return evaluator.compile(expr.data(), expr.size(), funcs, ec); } } // namespace jmespath } // namespace jsoncons #endif // JSONCONS_EXT_JMESPATH_JMESPATH_HPP jsoncons-1.3.2/include/jsoncons_ext/jmespath/jmespath_error.hpp000066400000000000000000000161701477700171100250720ustar00rootroot00000000000000/// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JMESPATH_JMESPATH_ERROR_HPP #define JSONCONS_EXT_JMESPATH_JMESPATH_ERROR_HPP #include #include #include #include #include #include namespace jsoncons { namespace jmespath { class jmespath_error : public std::system_error, public virtual json_exception { std::size_t line_number_{0}; std::size_t column_number_{0}; mutable std::string what_; public: jmespath_error(std::error_code ec) : std::system_error(ec) { } jmespath_error(std::error_code ec, const std::string& what_arg) : std::system_error(ec, what_arg) { } jmespath_error(std::error_code ec, std::size_t position) : std::system_error(ec), column_number_(position) { } jmespath_error(std::error_code ec, std::size_t line, std::size_t column) : std::system_error(ec), line_number_(line), column_number_(column) { } jmespath_error(const jmespath_error& other) = default; jmespath_error(jmespath_error&& other) = default; ~jmespath_error() override = default; const char* what() const noexcept override { if (what_.empty()) { JSONCONS_TRY { what_.append(std::system_error::what()); if (line_number_ != 0 && column_number_ != 0) { what_.append(" at line "); what_.append(std::to_string(line_number_)); what_.append(" and column "); what_.append(std::to_string(column_number_)); } else if (column_number_ != 0) { what_.append(" at position "); what_.append(std::to_string(column_number_)); } return what_.c_str(); } JSONCONS_CATCH(...) { return std::system_error::what(); } } else { return what_.c_str(); } } std::size_t line() const noexcept { return line_number_; } std::size_t column() const noexcept { return column_number_; } }; enum class jmespath_errc { success = 0, expected_identifier, expected_index, expected_A_Za_Z_, expected_rbracket, expected_rparen, expected_rbrace, expected_colon, expected_dot, expected_or, expected_and, expected_multi_select_list, invalid_number, invalid_literal, expected_comparator, expected_key, invalid_argument, unknown_function, invalid_type, unexpected_end_of_input, step_cannot_be_zero, syntax_error, invalid_codepoint, illegal_escaped_character, unbalanced_parentheses, unbalanced_braces, invalid_arity, identifier_not_found, expected_index_expression, undefined_variable, unknown_error }; class jmespath_error_category_impl : public std::error_category { public: const char* name() const noexcept override { return "jsoncons/jmespath"; } std::string message(int ev) const override { switch (static_cast(ev)) { case jmespath_errc::expected_identifier: return "Expected identifier"; case jmespath_errc::expected_index: return "Expected index"; case jmespath_errc::expected_A_Za_Z_: return "Expected A-Z, a-z, or _"; case jmespath_errc::expected_rbracket: return "Expected ]"; case jmespath_errc::expected_rparen: return "Expected )"; case jmespath_errc::expected_rbrace: return "Expected }"; case jmespath_errc::expected_colon: return "Expected :"; case jmespath_errc::expected_dot: return "Expected \".\""; case jmespath_errc::expected_or: return "Expected \"||\""; case jmespath_errc::expected_and: return "Expected \"&&\""; case jmespath_errc::expected_multi_select_list: return "Expected multi-select-list"; case jmespath_errc::invalid_number: return "Invalid number"; case jmespath_errc::invalid_literal: return "Invalid literal"; case jmespath_errc::expected_comparator: return "Expected <, <=, ==, >=, > or !="; case jmespath_errc::expected_key: return "Expected key"; case jmespath_errc::invalid_argument: return "Invalid argument type"; case jmespath_errc::unknown_function: return "Unknown function"; case jmespath_errc::invalid_type: return "Invalid type"; case jmespath_errc::unexpected_end_of_input: return "Unexpected end of jmespath input"; case jmespath_errc::step_cannot_be_zero: return "Slice step cannot be zero"; case jmespath_errc::syntax_error: return "Syntax error"; case jmespath_errc::invalid_codepoint: return "Invalid codepoint"; case jmespath_errc::illegal_escaped_character: return "Illegal escaped character"; case jmespath_errc::unbalanced_parentheses: return "Unbalanced parentheses"; case jmespath_errc::unbalanced_braces: return "Unbalanced braces"; case jmespath_errc::invalid_arity: return "Function called with wrong number of arguments"; case jmespath_errc::identifier_not_found: return "Identifier not found"; case jmespath_errc::expected_index_expression: return "Expected index expression"; case jmespath_errc::undefined_variable: return "Undefined variable"; case jmespath_errc::unknown_error: default: return "Unknown jmespath parser error"; } } }; inline const std::error_category& jmespath_error_category() { static jmespath_error_category_impl instance; return instance; } inline std::error_code make_error_code(jmespath_errc result) { return std::error_code(static_cast(result),jmespath_error_category()); } } // namespace jmespath } // namespace jsoncons namespace std { template<> struct is_error_code_enum : public true_type { }; } // namespace std #endif // JSONCONS_EXT_JMESPATH_JMESPATH_ERROR_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonpatch/000077500000000000000000000000001477700171100215065ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons_ext/jsonpatch/jsonpatch.hpp000066400000000000000000000534671477700171100242270ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONPATCH_JSONPATCH_HPP #define JSONCONS_EXT_JSONPATCH_JSONPATCH_HPP #include // std::min #include #include #include #include // std::move #include #include #include #include namespace jsoncons { namespace jsonpatch { namespace detail { template struct jsonpatch_names { static std::basic_string test_name() { static std::basic_string name{'t','e','s','t'}; return name; } static std::basic_string add_name() { static std::basic_string name{'a','d','d'}; return name; } static std::basic_string remove_name() { static std::basic_string name{'r','e','m','o','v','e'}; return name; } static std::basic_string replace_name() { static std::basic_string name{'r','e','p','l','a','c','e'}; return name; } static std::basic_string move_name() { static std::basic_string name{'m','o','v','e'}; return name; } static std::basic_string copy_name() { static std::basic_string name{'c','o','p','y'}; return name; } static std::basic_string op_name() { static std::basic_string name{'o','p'}; return name; } static std::basic_string path_name() { static std::basic_string name{'p','a','t','h'}; return name; } static std::basic_string from_name() { static std::basic_string name{'f','r','o','m'}; return name; } static std::basic_string value_name() { static std::basic_string name{'v','a','l','u','e'}; return name; } static std::basic_string dash_name() { static std::basic_string name{'-'}; return name; } }; template jsonpointer::basic_json_pointer definite_path(const Json& root, jsonpointer::basic_json_pointer& location) { using char_type = typename Json::char_type; using string_type = std::basic_string; auto rit = location.rbegin(); if (rit == location.rend()) { return location; } if (*rit != jsonpatch_names::dash_name()) { return location; } std::vector tokens; for (auto it = location.begin(); it != location.rbegin().base()-1; ++it) { tokens.push_back(*it); } jsonpointer::basic_json_pointer pointer(tokens); std::error_code ec; Json val = jsonpointer::get(root, pointer, ec); if (ec || !val.is_array()) { return location; } string_type last_token; jsoncons::detail::from_integer(val.size(), last_token); tokens.emplace_back(std::move(last_token)); return jsonpointer::basic_json_pointer(std::move(tokens)); } enum class op_type {add,remove,replace}; enum class state_type {begin,abort,commit}; template struct operation_unwinder { using char_type = typename Json::char_type; using string_type = std::basic_string; using json_pointer_type = jsonpointer::basic_json_pointer; struct entry { op_type op; json_pointer_type path; Json value; entry(op_type Op, const json_pointer_type& Path, const Json& Value) : op(Op), path(Path), value(Value) { } entry(const entry&) = default; entry(entry&&) = default; entry& operator=(const entry&) = default; entry& operator=(entry&&) = default; }; Json& target; state_type state; std::vector stack; operation_unwinder(Json& j) : target(j), state(state_type::begin) { } ~operation_unwinder() noexcept { std::error_code ec; if (state != state_type::commit) { for (auto it = stack.rbegin(); it != stack.rend(); ++it) { if ((*it).op == op_type::add) { jsonpointer::add(target,(*it).path,(*it).value,ec); if (JSONCONS_UNLIKELY(ec)) { //std::cout << "add: " << (*it).path << '\n'; break; } } else if ((*it).op == op_type::remove) { jsonpointer::remove(target,(*it).path,ec); if (JSONCONS_UNLIKELY(ec)) { //std::cout << "remove: " << (*it).path << '\n'; break; } } else if ((*it).op == op_type::replace) { jsonpointer::replace(target,(*it).path,(*it).value,ec); if (JSONCONS_UNLIKELY(ec)) { //std::cout << "replace: " << (*it).path << '\n'; break; } } } } } }; template Json from_diff(const Json& source, const Json& target, const typename Json::string_view_type& path) { using char_type = typename Json::char_type; Json result = typename Json::array(); if (source == target) { return result; } if (source.is_array() && target.is_array()) { std::size_t common = (std::min)(source.size(),target.size()); for (std::size_t i = 0; i < common; ++i) { std::basic_string ss(path); ss.push_back('/'); jsoncons::detail::from_integer(i,ss); auto temp_diff = from_diff(source[i],target[i],ss); result.insert(result.array_range().end(),temp_diff.array_range().begin(),temp_diff.array_range().end()); } // Element in source, not in target - remove for (std::size_t i = source.size(); i-- > target.size();) { std::basic_string ss(path); ss.push_back('/'); jsoncons::detail::from_integer(i,ss); Json val(json_object_arg); val.insert_or_assign(jsonpatch_names::op_name(), jsonpatch_names::remove_name()); val.insert_or_assign(jsonpatch_names::path_name(), ss); result.push_back(std::move(val)); } // Element in target, not in source - add, // Fix contributed by Alexander rog13 for (std::size_t i = source.size(); i < target.size(); ++i) { const auto& a = target[i]; std::basic_string ss(path); ss.push_back('/'); jsoncons::detail::from_integer(i,ss); Json val(json_object_arg); val.insert_or_assign(jsonpatch_names::op_name(), jsonpatch_names::add_name()); val.insert_or_assign(jsonpatch_names::path_name(), ss); val.insert_or_assign(jsonpatch_names::value_name(), a); result.push_back(std::move(val)); } } else if (source.is_object() && target.is_object()) { for (const auto& a : source.object_range()) { std::basic_string ss(path); ss.push_back('/'); jsonpointer::escape(a.key(),ss); auto it = target.find(a.key()); if (it != target.object_range().end()) { auto temp_diff = from_diff(a.value(),(*it).value(),ss); result.insert(result.array_range().end(),temp_diff.array_range().begin(),temp_diff.array_range().end()); } else { Json val(json_object_arg); val.insert_or_assign(jsonpatch_names::op_name(), jsonpatch_names::remove_name()); val.insert_or_assign(jsonpatch_names::path_name(), ss); result.push_back(std::move(val)); } } for (const auto& a : target.object_range()) { auto it = source.find(a.key()); if (it == source.object_range().end()) { std::basic_string ss(path); ss.push_back('/'); jsonpointer::escape(a.key(),ss); Json val(json_object_arg); val.insert_or_assign(jsonpatch_names::op_name(), jsonpatch_names::add_name()); val.insert_or_assign(jsonpatch_names::path_name(), ss); val.insert_or_assign(jsonpatch_names::value_name(), a.value()); result.push_back(std::move(val)); } } } else { Json val(json_object_arg); val.insert_or_assign(jsonpatch_names::op_name(), jsonpatch_names::replace_name()); val.insert_or_assign(jsonpatch_names::path_name(), path); val.insert_or_assign(jsonpatch_names::value_name(), target); result.push_back(std::move(val)); } return result; } } // namespace detail template void apply_patch(Json& target, const Json& patch, std::error_code& ec) { if (!patch.is_array()) { ec = jsonpatch_errc::invalid_patch; return; } using char_type = typename Json::char_type; using string_type = std::basic_string; using json_pointer_type = jsonpointer::basic_json_pointer; jsoncons::jsonpatch::detail::operation_unwinder unwinder(target); std::error_code local_ec; // Validate for (const auto& operation : patch.array_range()) { unwinder.state =jsoncons::jsonpatch::detail::state_type::begin; auto it_op = operation.find(detail::jsonpatch_names::op_name()); if (it_op == operation.object_range().end()) { ec = jsonpatch_errc::invalid_patch; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } string_type op = it_op->value().template as(); auto it_path = operation.find(detail::jsonpatch_names::path_name()); if (it_path == operation.object_range().end()) { ec = jsonpatch_errc::invalid_patch; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } string_type path = it_path->value().template as(); auto location = json_pointer_type::parse(path, local_ec); if (local_ec) { ec = jsonpatch_errc::invalid_patch; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } if (op ==jsoncons::jsonpatch::detail::jsonpatch_names::test_name()) { Json val = jsonpointer::get(target,location,local_ec); if (local_ec) { ec = jsonpatch_errc::test_failed; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } auto it_value = operation.find(detail::jsonpatch_names::value_name()); if (it_value == operation.object_range().end()) { ec = jsonpatch_errc::invalid_patch; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } if (val != it_value->value()) { ec = jsonpatch_errc::test_failed; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } } else if (op ==jsoncons::jsonpatch::detail::jsonpatch_names::add_name()) { auto it_value = operation.find(detail::jsonpatch_names::value_name()); if (it_value == operation.object_range().end()) { ec = jsonpatch_errc::invalid_patch; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } Json val = it_value->value(); auto npath = jsonpatch::detail::definite_path(target,location); std::error_code insert_ec; jsonpointer::add_if_absent(target,npath,val,insert_ec); // try insert without replace if (insert_ec) // try a replace { std::error_code select_ec; Json orig_val = jsonpointer::get(target,npath,select_ec); if (select_ec) // shouldn't happen { ec = jsonpatch_errc::add_failed; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } std::error_code replace_ec; jsonpointer::replace(target,npath,val,replace_ec); if (replace_ec) { ec = jsonpatch_errc::add_failed; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } unwinder.stack.emplace_back(detail::op_type::replace,npath,orig_val); } else // insert without replace succeeded { unwinder.stack.emplace_back(detail::op_type::remove,npath,Json::null()); } } else if (op ==jsoncons::jsonpatch::detail::jsonpatch_names::remove_name()) { Json val = jsonpointer::get(target,location,local_ec); if (local_ec) { ec = jsonpatch_errc::remove_failed; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } jsonpointer::remove(target,location,local_ec); if (local_ec) { ec = jsonpatch_errc::remove_failed; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } unwinder.stack.emplace_back(detail::op_type::add, location, val); } else if (op ==jsoncons::jsonpatch::detail::jsonpatch_names::replace_name()) { Json val = jsonpointer::get(target,location,local_ec); if (local_ec) { ec = jsonpatch_errc::replace_failed; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } auto it_value = operation.find(detail::jsonpatch_names::value_name()); if (it_value == operation.object_range().end()) { ec = jsonpatch_errc::invalid_patch; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } jsonpointer::replace(target, location, it_value->value(), local_ec); if (local_ec) { ec = jsonpatch_errc::replace_failed; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } unwinder.stack.emplace_back(detail::op_type::replace,location,val); } else if (op ==jsoncons::jsonpatch::detail::jsonpatch_names::move_name()) { auto it_from = operation.find(detail::jsonpatch_names::from_name()); if (it_from == operation.object_range().end()) { ec = jsonpatch_errc::invalid_patch; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } string_type from = it_from->value().as_string(); auto from_pointer = json_pointer_type::parse(from, local_ec); if (local_ec) { ec = jsonpatch_errc::move_failed; unwinder.state = jsoncons::jsonpatch::detail::state_type::abort; return; } Json val = jsonpointer::get(target, from_pointer, local_ec); if (local_ec) { ec = jsonpatch_errc::move_failed; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } jsonpointer::remove(target, from_pointer, local_ec); if (local_ec) { ec = jsonpatch_errc::move_failed; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } unwinder.stack.emplace_back(detail::op_type::add, from_pointer, val); // add std::error_code insert_ec; auto npath = jsonpatch::detail::definite_path(target,location); jsonpointer::add_if_absent(target,npath,val,insert_ec); // try insert without replace if (insert_ec) // try a replace { std::error_code select_ec; Json orig_val = jsonpointer::get(target,npath,select_ec); if (select_ec) // shouldn't happen { ec = jsonpatch_errc::copy_failed; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } std::error_code replace_ec; jsonpointer::replace(target, npath, val, replace_ec); if (replace_ec) { ec = jsonpatch_errc::copy_failed; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } unwinder.stack.emplace_back(jsoncons::jsonpatch::detail::op_type::replace,npath,orig_val); } else { unwinder.stack.emplace_back(detail::op_type::remove,npath,Json::null()); } } else if (op ==jsoncons::jsonpatch::detail::jsonpatch_names::copy_name()) { auto it_from = operation.find(detail::jsonpatch_names::from_name()); if (it_from == operation.object_range().end()) { ec = jsonpatch_errc::invalid_patch; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } string_type from = it_from->value().as_string(); Json val = jsonpointer::get(target,from,local_ec); if (local_ec) { ec = jsonpatch_errc::copy_failed; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } // add auto npath = jsonpatch::detail::definite_path(target,location); std::error_code insert_ec; jsonpointer::add_if_absent(target,npath,val,insert_ec); // try insert without replace if (insert_ec) // Failed, try a replace { std::error_code select_ec; Json orig_val = jsonpointer::get(target,npath, select_ec); if (select_ec) // shouldn't happen { ec = jsonpatch_errc::copy_failed; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } std::error_code replace_ec; jsonpointer::replace(target, npath, val,replace_ec); if (replace_ec) { ec = jsonpatch_errc::copy_failed; unwinder.state =jsoncons::jsonpatch::detail::state_type::abort; return; } unwinder.stack.emplace_back(jsoncons::jsonpatch::detail::op_type::replace,npath,orig_val); } else { unwinder.stack.emplace_back(detail::op_type::remove,npath,Json::null()); } } } if (unwinder.state ==jsoncons::jsonpatch::detail::state_type::begin) { unwinder.state =jsoncons::jsonpatch::detail::state_type::commit; } } template Json from_diff(const Json& source, const Json& target) { std::basic_string path; return jsoncons::jsonpatch::detail::from_diff(source, target, path); } template void apply_patch(Json& target, const Json& patch) { std::error_code ec; apply_patch(target, patch, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(jsonpatch_error(ec)); } } } // namespace jsonpatch } // namespace jsoncons #endif // JSONCONS_EXT_JSONPATCH_JSONPATCH_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonpatch/jsonpatch_error.hpp000066400000000000000000000071521477700171100254260ustar00rootroot00000000000000/// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONPATCH_JSONPATCH_ERROR_HPP #define JSONCONS_EXT_JSONPATCH_JSONPATCH_ERROR_HPP #include #include #include #include namespace jsoncons { namespace jsonpatch { enum class jsonpatch_errc { success = 0, invalid_patch = 1, test_failed, add_failed, remove_failed, replace_failed, move_failed, copy_failed }; class jsonpatch_error_category_impl : public std::error_category { public: const char* name() const noexcept override { return "jsoncons/jsonpatch"; } std::string message(int ev) const override { switch (static_cast(ev)) { case jsonpatch_errc::invalid_patch: return "Invalid JSON Patch document"; case jsonpatch_errc::test_failed: return "JSON Patch test operation failed"; case jsonpatch_errc::add_failed: return "JSON Patch add operation failed"; case jsonpatch_errc::remove_failed: return "JSON Patch remove operation failed"; case jsonpatch_errc::replace_failed: return "JSON Patch replace operation failed"; case jsonpatch_errc::move_failed: return "JSON Patch move operation failed"; case jsonpatch_errc::copy_failed: return "JSON Patch copy operation failed"; default: return "Unknown JSON Patch error"; } } }; inline const std::error_category& jsonpatch_error_category() { static jsonpatch_error_category_impl instance; return instance; } inline std::error_code make_error_code(jsonpatch_errc result) { return std::error_code(static_cast(result),jsonpatch_error_category()); } } // namespace jsonpatch } // namespace jsoncons namespace std { template<> struct is_error_code_enum : public true_type { }; } // namespace std namespace jsoncons { namespace jsonpatch { // allow to disable exceptions #if !defined(JSONCONS_NO_EXCEPTIONS) #define JSONCONS_THROW(exception) throw exception #define JSONCONS_RETHROW throw #define JSONCONS_TRY try #define JSONCONS_CATCH(exception) catch(exception) #else #define JSONCONS_THROW(exception) std::terminate() #define JSONCONS_RETHROW std::terminate() #define JSONCONS_TRY if (true) #define JSONCONS_CATCH(exception) if (false) #endif class jsonpatch_error : public std::system_error, public virtual json_exception { public: jsonpatch_error(const std::error_code& ec) : std::system_error(ec) { } jsonpatch_error(const jsonpatch_error& other) = default; jsonpatch_error(jsonpatch_error&& other) = default; jsonpatch_error& operator=(const jsonpatch_error& e) = default; jsonpatch_error& operator=(jsonpatch_error&& e) = default; const char* what() const noexcept override { return std::system_error::what(); } }; } // namespace jsonpatch } // namespace jsoncons #endif // JSONCONS_EXT_JSONPATCH_JSONPATCH_ERROR_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonpath/000077500000000000000000000000001477700171100213435ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons_ext/jsonpath/flatten.hpp000066400000000000000000000362741477700171100235250ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONPATH_FLATTEN_HPP #define JSONCONS_EXT_JSONPATH_FLATTEN_HPP #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace jsonpath { template void flatten_(const typename Json::string_type& parent_key, const Json& parent_value, Json& result) { using char_type = typename Json::char_type; using string_type = std::basic_string; switch (parent_value.type()) { case json_type::array_value: { if (parent_value.empty()) { result.try_emplace(parent_key, parent_value); } else { for (std::size_t i = 0; i < parent_value.size(); ++i) { string_type key(parent_key); key.push_back('['); jsoncons::detail::from_integer(i,key); key.push_back(']'); flatten_(key, parent_value.at(i), result); } } break; } case json_type::object_value: { if (parent_value.empty()) { result.try_emplace(parent_key, Json()); } else { for (const auto& item : parent_value.object_range()) { string_type key(parent_key); key.push_back('['); key.push_back('\''); escape_string(item.key().data(), item.key().length(), key); key.push_back('\''); key.push_back(']'); flatten_(key, item.value(), result); } } break; } default: { result[parent_key] = parent_value; break; } } } template Json flatten(const Json& value) { Json result; typename Json::string_type parent_key = {'$'}; flatten_(parent_key, value, result); return result; } enum class unflatten_state { start, expect_lbracket, lbracket, single_quoted_name_state, double_quoted_name_state, index_state, expect_rbracket, double_quoted_string_escape_char, single_quoted_string_escape_char }; template Json unflatten(const Json& value) { using char_type = typename Json::char_type; using string_type = std::basic_string; if (JSONCONS_UNLIKELY(!value.is_object())) { JSONCONS_THROW(jsonpath_error(jsonpath_errc::argument_to_unflatten_invalid)); } Json result; for (const auto& item : value.object_range()) { Json* part = &result; string_type buffer; unflatten_state state = unflatten_state::start; auto it = item.key().begin(); auto last = item.key().end(); for (; it != last; ++it) { switch (state) { case unflatten_state::start: { switch (*it) { case '$': state = unflatten_state::expect_lbracket; break; default: break; } break; } case unflatten_state::expect_lbracket: { switch (*it) { case '[': state = unflatten_state::lbracket; break; default: JSONCONS_THROW(jsonpath_error(jsonpath_errc::invalid_flattened_key)); break; } break; } case unflatten_state::lbracket: { switch (*it) { case '\'': state = unflatten_state::single_quoted_name_state; break; case '\"': state = unflatten_state::double_quoted_name_state; break; case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': buffer.push_back(*it); state = unflatten_state::index_state; break; default: JSONCONS_THROW(jsonpath_error(jsonpath_errc::invalid_flattened_key)); break; } break; } case unflatten_state::single_quoted_name_state: { switch (*it) { case '\'': if (it != last-2) { auto res = part->try_emplace(buffer,Json()); part = &(res.first->value()); } else { auto res = part->try_emplace(buffer,item.value()); part = &(res.first->value()); } buffer.clear(); state = unflatten_state::expect_rbracket; break; case '\\': state = unflatten_state::single_quoted_string_escape_char; break; default: buffer.push_back(*it); break; } break; } case unflatten_state::double_quoted_name_state: { switch (*it) { case '\"': if (it != last-2) { auto res = part->try_emplace(buffer,Json()); part = &(res.first->value()); } else { auto res = part->try_emplace(buffer,item.value()); part = &(res.first->value()); } buffer.clear(); state = unflatten_state::expect_rbracket; break; case '\\': state = unflatten_state::double_quoted_string_escape_char; break; default: buffer.push_back(*it); break; } break; } case unflatten_state::double_quoted_string_escape_char: switch (*it) { case '\"': buffer.push_back('\"'); state = unflatten_state::double_quoted_name_state; break; case '\\': buffer.push_back('\\'); state = unflatten_state::double_quoted_name_state; break; case '/': buffer.push_back('/'); state = unflatten_state::double_quoted_name_state; break; case 'b': buffer.push_back('\b'); state = unflatten_state::double_quoted_name_state; break; case 'f': buffer.push_back('\f'); state = unflatten_state::double_quoted_name_state; break; case 'n': buffer.push_back('\n'); state = unflatten_state::double_quoted_name_state; break; case 'r': buffer.push_back('\r'); state = unflatten_state::double_quoted_name_state; break; case 't': buffer.push_back('\t'); state = unflatten_state::double_quoted_name_state; break; default: break; } break; case unflatten_state::single_quoted_string_escape_char: switch (*it) { case '\'': buffer.push_back('\''); state = unflatten_state::single_quoted_name_state; break; case '\\': buffer.push_back('\\'); state = unflatten_state::double_quoted_name_state; break; case '/': buffer.push_back('/'); state = unflatten_state::double_quoted_name_state; break; case 'b': buffer.push_back('\b'); state = unflatten_state::double_quoted_name_state; break; case 'f': buffer.push_back('\f'); state = unflatten_state::double_quoted_name_state; break; case 'n': buffer.push_back('\n'); state = unflatten_state::double_quoted_name_state; break; case 'r': buffer.push_back('\r'); state = unflatten_state::double_quoted_name_state; break; case 't': buffer.push_back('\t'); state = unflatten_state::double_quoted_name_state; break; default: break; } break; case unflatten_state::index_state: { switch (*it) { case ']': { std::size_t n{0}; auto r = jsoncons::detail::to_integer(buffer.data(), buffer.size(), n); if (r) { if (!part->is_array()) { *part = Json(json_array_arg, semantic_tag::none, value.get_allocator()); } if (it != last-1) { if (n+1 > part->size()) { Json& ref = part->emplace_back(); part = std::addressof(ref); } else { part = &part->at(n); } } else { Json& ref = part->emplace_back(item.value()); part = std::addressof(ref); } } buffer.clear(); state = unflatten_state::expect_lbracket; break; } case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': buffer.push_back(*it); break; default: JSONCONS_THROW(jsonpath_error(jsonpath_errc::invalid_flattened_key)); break; } break; } case unflatten_state::expect_rbracket: { switch (*it) { case ']': state = unflatten_state::expect_lbracket; break; default: JSONCONS_THROW(jsonpath_error(jsonpath_errc::invalid_flattened_key)); break; } break; } default: JSONCONS_UNREACHABLE(); break; } } } return result; } } // namespace jsonpath } // namespace jsoncons #endif // JSONCONS_EXT_JSONPATH_FLATTEN_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonpath/json_location.hpp000066400000000000000000001100111477700171100247070ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONPATH_JSON_LOCATION_HPP #define JSONCONS_EXT_JSONPATH_JSON_LOCATION_HPP #include // std::reverse #include #include #include #include #include // std::is_const #include // std::move #include #include #include #include #include #include #include namespace jsoncons { namespace jsonpath { template class basic_path_element { public: using char_type = CharT; using allocator_type = Allocator; using char_allocator_type = typename std::allocator_traits:: template rebind_alloc; using string_type = std::basic_string,char_allocator_type>; private: bool has_name_; string_type name_; std::size_t index_{0}; public: basic_path_element(const char_type* name, std::size_t length, const Allocator& alloc = Allocator()) : has_name_(true), name_(name, length, alloc) { } explicit basic_path_element(const string_type& name) : has_name_(true), name_(name) { } explicit basic_path_element(string_type&& name) : has_name_(true), name_(std::move(name)) { } basic_path_element(std::size_t index, const Allocator& alloc = Allocator()) : has_name_(false), name_(alloc), index_(index) { } basic_path_element(const basic_path_element& other) = default; basic_path_element(basic_path_element&& other) = default; ~basic_path_element() = default; basic_path_element& operator=(const basic_path_element& other) = default; basic_path_element& operator=(basic_path_element&& other) = default; bool has_name() const { return has_name_; } bool has_index() const { return !has_name_; } const string_type& name() const { return name_; } std::size_t index() const { return index_; } int compare(const basic_path_element& other) const { int diff = 0; if (has_name_ != other.has_name_) { diff = static_cast(has_name_) - static_cast(other.has_name_); } else { if (has_name_) { diff = name_.compare(other.name_); } else if (index_ < other.index_) { diff = -1; } else if (index_ > other.index_) { diff = 1; } else { diff = 0; } } return diff; } }; // parser namespace detail { enum class json_location_state { start, relative_location, single_quoted_string, double_quoted_string, unquoted_string, selector, digit, expect_rbracket, quoted_string_escape_char }; enum class selector_separator_kind{bracket,dot}; template class json_location_parser { public: using allocator_type = Allocator; using char_type = CharT; using string_type = std::basic_string; using string_view_type = jsoncons::basic_string_view; using path_element_type = basic_path_element; using path_element_allocator_type = typename std::allocator_traits:: template rebind_alloc; using path_type = std::vector; private: allocator_type alloc_; std::size_t line_{1}; std::size_t column_{1}; const char_type* end_input_{nullptr}; const char_type* p_{nullptr}; public: json_location_parser(const allocator_type& alloc = allocator_type()) : alloc_(alloc) { } json_location_parser(std::size_t line, std::size_t column, const allocator_type& alloc = allocator_type()) : alloc_(alloc), line_(line), column_(column) { } std::size_t line() const { return line_; } std::size_t column() const { return column_; } path_type parse(const string_view_type& path) { std::error_code ec; auto result = parse(path, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(jsonpath_error(ec, line_, column_)); } return result; } path_type parse(const string_view_type& path, std::error_code& ec) { std::vector elements; string_type buffer(alloc_); end_input_ = path.data() + path.length(); p_ = path.data(); selector_separator_kind separator_kind = selector_separator_kind::bracket; json_location_state state = json_location_state::start; while (p_ < end_input_) { switch (state) { case json_location_state::start: { switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '$': case '@': { state = json_location_state::relative_location; ++p_; ++column_; break; } default: { ec = jsonpath_errc::expected_root_or_current_node; return path_type{}; } } break; } case json_location_state::relative_location: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '[': separator_kind = selector_separator_kind::bracket; state = json_location_state::selector; ++p_; ++column_; break; case '.': separator_kind = selector_separator_kind::dot; state = json_location_state::selector; ++p_; ++column_; break; default: ec = jsonpath_errc::expected_lbracket_or_dot; return path_type(); }; break; case json_location_state::selector: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '\'': state = json_location_state::single_quoted_string; ++p_; ++column_; break; case '\"': state = json_location_state::double_quoted_string; ++p_; ++column_; break; case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': state = json_location_state::digit; break; case '-': ec = jsonpath_errc::expected_single_quote_or_digit; return path_type(); default: if (separator_kind == selector_separator_kind::dot) { state = json_location_state::unquoted_string; } else { ec = jsonpath_errc::expected_single_quote_or_digit; return path_type(); } break; } break; case json_location_state::single_quoted_string: switch (*p_) { case '\'': elements.emplace_back(buffer); buffer.clear(); if (separator_kind == selector_separator_kind::bracket) { state = json_location_state::expect_rbracket; } else { state = json_location_state::relative_location; } ++p_; ++column_; break; case '\\': state = json_location_state::quoted_string_escape_char; ++p_; ++column_; break; default: buffer.push_back(*p_); ++p_; ++column_; break; }; break; case json_location_state::double_quoted_string: switch (*p_) { case '\"': elements.emplace_back(buffer); buffer.clear(); if (separator_kind == selector_separator_kind::bracket) { state = json_location_state::expect_rbracket; } else { state = json_location_state::relative_location; } ++p_; ++column_; break; case '\\': state = json_location_state::quoted_string_escape_char; ++p_; ++column_; break; default: buffer.push_back(*p_); ++p_; ++column_; break; }; break; case json_location_state::unquoted_string: switch (*p_) { case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'g':case 'h':case 'i':case 'j':case 'k':case 'l':case 'm':case 'n':case 'o':case 'p':case 'q':case 'r':case 's':case 't':case 'u':case 'v':case 'w':case 'x':case 'y':case 'z': case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':case 'G':case 'H':case 'I':case 'J':case 'K':case 'L':case 'M':case 'N':case 'O':case 'P':case 'Q':case 'R':case 'S':case 'T':case 'U':case 'V':case 'W':case 'X':case 'Y':case 'Z': case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': case '_': buffer.push_back(*p_); ++p_; ++column_; break; case '\\': state = json_location_state::quoted_string_escape_char; ++p_; ++column_; break; default: if (typename std::make_unsigned::type(*p_) > 127) { buffer.push_back(*p_); ++p_; ++column_; } else { elements.emplace_back(buffer); buffer.clear(); advance_past_space_character(); state = json_location_state::relative_location; } break; }; break; case json_location_state::expect_rbracket: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ']': state = json_location_state::relative_location; ++p_; ++column_; break; default: ec = jsonpath_errc::expected_rbracket; return path_type(alloc_); } break; case json_location_state::digit: switch(*p_) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': buffer.push_back(*p_); ++p_; ++column_; break; default: std::size_t n{0}; auto r = jsoncons::detail::to_integer(buffer.data(), buffer.size(), n); if (!r) { ec = jsonpath_errc::invalid_number; return path_type(alloc_); } elements.emplace_back(n); buffer.clear(); if (separator_kind == selector_separator_kind::bracket) { state = json_location_state::expect_rbracket; } else { state = json_location_state::relative_location; } break; } break; case json_location_state::quoted_string_escape_char: switch (*p_) { case '\"': buffer.push_back('\"'); ++p_; ++column_; state = json_location_state::single_quoted_string; break; case '\'': buffer.push_back('\''); ++p_; ++column_; state = json_location_state::single_quoted_string; break; case '\\': buffer.push_back('\\'); ++p_; ++column_; state = json_location_state::single_quoted_string; break; case '/': buffer.push_back('/'); ++p_; ++column_; state = json_location_state::single_quoted_string; break; case 'b': buffer.push_back('\b'); ++p_; ++column_; state = json_location_state::single_quoted_string; break; case 'f': buffer.push_back('\f'); ++p_; ++column_; state = json_location_state::single_quoted_string; break; case 'n': buffer.push_back('\n'); ++p_; ++column_; state = json_location_state::single_quoted_string; break; case 'r': buffer.push_back('\r'); ++p_; ++column_; state = json_location_state::single_quoted_string; break; case 't': buffer.push_back('\t'); ++p_; ++column_; state = json_location_state::single_quoted_string; break; case 'u': ++p_; ++column_; state = json_location_state::single_quoted_string; break; default: ec = jsonpath_errc::illegal_escaped_character; return path_type(alloc_); } break; default: ++p_; ++column_; break; } } if (state == json_location_state::unquoted_string) { elements.emplace_back(buffer); } else if (state == json_location_state::digit) { std::size_t n{ 0 }; auto r = jsoncons::detail::to_integer(buffer.data(), buffer.size(), n); if (!r) { ec = jsonpath_errc::invalid_number; return path_type(alloc_); } elements.emplace_back(n); } else if (state != json_location_state::relative_location) { ec = jsonpath_errc::unexpected_eof; return path_type(); } return path_type(std::move(elements)); } void advance_past_space_character() { switch (*p_) { case ' ':case '\t': ++p_; ++column_; break; case '\r': if ((p_+1 < end_input_) && (*(p_+1) == '\n')) { ++p_; } ++line_; column_ = 1; ++p_; break; case '\n': ++line_; column_ = 1; ++p_; break; default: break; } } }; } // namespace detail template > class basic_json_location { public: using char_type = CharT; using allocator_type = Allocator; using string_view_type = jsoncons::basic_string_view>; using value_type = basic_path_element; using const_iterator = typename std::vector::const_iterator; using iterator = const_iterator; private: using path_element_allocator_type = typename std::allocator_traits:: template rebind_alloc; std::vector elements_; public: basic_json_location(const allocator_type& alloc=Allocator()) : elements_(alloc) { } explicit basic_json_location(const basic_path_node& path, const allocator_type& alloc=Allocator()) : elements_(alloc) { auto p_node = std::addressof(path); while (p_node != nullptr) { switch (p_node->node_kind()) { case path_node_kind::root: break; case path_node_kind::name: elements_.emplace_back(p_node->name().data(), p_node->name().size()); break; case path_node_kind::index: elements_.emplace_back(p_node->index()); break; } p_node = p_node->parent(); } std::reverse(elements_.begin(), elements_.end()); } basic_json_location(const basic_json_location&) = default; basic_json_location(basic_json_location&&) = default; explicit basic_json_location(std::vector&& elements) : elements_(std::move(elements)) { } ~basic_json_location() = default; basic_json_location& operator=(const basic_json_location&) = default; basic_json_location& operator=(basic_json_location&&) = default; // Iterators const_iterator begin() const { return elements_.begin(); } const_iterator end() const { return elements_.end(); } // Accessors bool empty() const { return elements_.empty(); } std::size_t size() const { return elements_.size(); } const value_type& operator[](std::size_t index) const { return elements_[index]; } int compare(const basic_json_location& other) const { if (this == &other) { return 0; } auto it1 = elements_.begin(); auto it2 = other.elements_.begin(); while (it1 != elements_.end() && it2 != other.elements_.end()) { int diff = it1->compare(*it2); if (diff != 0) { return diff; } ++it1; ++it2; } if (elements_.size() < other.elements_.size()) { return -1; } if (elements_.size() > other.elements_.size()) { return 1; } return 0; } // Modifiers void clear() { elements_.clear(); } basic_json_location& append(const string_view_type& s) { elements_.emplace_back(s.data(), s.size()); return *this; } template typename std::enable_if::value, basic_json_location&>::type append(IntegerType val) { elements_.emplace_back(static_cast(val)); return *this; } basic_json_location& operator/=(const string_view_type& s) { elements_.emplace_back(s.data(), s.size()); return *this; } template typename std::enable_if::value, basic_json_location&>::type operator/=(IntegerType val) { elements_.emplace_back(static_cast(val)); return *this; } friend bool operator==(const basic_json_location& lhs, const basic_json_location& rhs) { return lhs.compare(rhs) == 0; } friend bool operator!=(const basic_json_location& lhs, const basic_json_location& rhs) { return !(lhs == rhs); } friend bool operator<(const basic_json_location& lhs, const basic_json_location& rhs) { return lhs.compare(rhs) < 0; } static basic_json_location parse(const jsoncons::basic_string_view& normalized_path) { jsonpath::detail::json_location_parser> parser; std::vector location = parser.parse(normalized_path); return basic_json_location(std::move(location)); } static basic_json_location parse(const jsoncons::basic_string_view& normalized_path, std::error_code ec) { jsonpath::detail::json_location_parser> parser; std::vector location = parser.parse(normalized_path, ec); if (JSONCONS_UNLIKELY(ec)) { return basic_json_location(); } return basic_json_location(std::move(location)); } }; template std::size_t remove(Json& root, const basic_json_location& location) { std::size_t count = 0; Json* p_current = std::addressof(root); std::size_t last = location.size() == 0 ? 0 : location.size() - 1; for (std::size_t i = 0; i < location.size(); ++i) { const auto& element = location[i]; if (element.has_name()) { if (p_current->is_object()) { auto it = p_current->find(element.name()); if (it != p_current->object_range().end()) { if (i < last) { p_current = std::addressof((*it).value()); } else { p_current->erase(it); count = 1; } } else { break; } } else { break; } } else // if (element.has_index()) { if (p_current->is_array() && element.index() < p_current->size()) { if (i < last) { p_current = std::addressof(p_current->at(element.index())); } else { p_current->erase(p_current->array_range().begin()+element.index()); count = 1; } } else { break; } } } return count; } template std::pair get(Json& root, const basic_json_location& location) { Json* p_current = std::addressof(root); bool found = false; std::size_t last = location.size() == 0 ? 0 : location.size() - 1; for (std::size_t i = 0; i < location.size(); ++i) { const auto& element = location[i]; if (element.has_name()) { if (p_current->is_object()) { auto it = p_current->find(element.name()); if (it != p_current->object_range().end()) { p_current = std::addressof((*it).value()); if (i == last) { found = true; } } else { break; } } else { break; } } else // if (element.has_index()) { if (p_current->is_array() && element.index() < p_current->size()) { p_current = std::addressof(p_current->at(element.index())); if (i == last) { found = true; } } else { break; } } } return std::make_pair(p_current,found); } template > std::basic_string, Allocator> to_basic_string(const basic_json_location& location, const Allocator& alloc = Allocator()) { std::basic_string, Allocator> buffer(alloc); buffer.push_back('$'); for (const auto& element : location) { if (element.has_name()) { buffer.push_back('['); buffer.push_back('\''); jsoncons::jsonpath::escape_string(element.name().data(), element.name().size(), buffer); buffer.push_back('\''); buffer.push_back(']'); } else { buffer.push_back('['); jsoncons::detail::from_integer(element.index(), buffer); buffer.push_back(']'); } } return buffer; } template std::pair replace(Json& root, const basic_json_location& location, const Json& value, bool create_if_missing=false) { Json* p_current = std::addressof(root); bool found = false; std::size_t last = location.size() == 0 ? 0 : location.size() - 1; for (std::size_t i = 0; i < location.size(); ++i) { const auto& element = location[i]; if (element.has_name() && p_current->is_object()) { auto it = p_current->find(element.name()); if (it != p_current->object_range().end()) { p_current = std::addressof((*it).value()); if (i == last) { *p_current = std::move(value); found = true; } } else { if (create_if_missing) { if (i == last) { auto result = p_current->try_emplace(element.name(), value); p_current = std::addressof(result.first->value()); found = true; } else { auto result = p_current->try_emplace(element.name(), Json{}); p_current = std::addressof(result.first->value()); } } } } else if (element.has_index() && p_current->is_array()) { if (element.index() < p_current->size()) { p_current = std::addressof(p_current->at(element.index())); if (i == last) { *p_current = value; found = true; } } else { break; } } else { break; } } if (found) { return std::make_pair(p_current,true); } return std::make_pair(p_current, false); } using json_location = basic_json_location; using wjson_location = basic_json_location; using path_element = basic_path_element>; using wpath_element = basic_path_element>; inline std::string to_string(const json_location& location) { return to_basic_string(location); } inline std::wstring to_wstring(const wjson_location& location) { return to_basic_string(location); } } // namespace jsonpath } // namespace jsoncons #endif // JSONCONS_EXT_JSONPATH_JSON_LOCATION_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonpath/json_query.hpp000066400000000000000000000267031477700171100242620ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONPATH_JSON_QUERY_HPP #define JSONCONS_EXT_JSONPATH_JSON_QUERY_HPP #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace jsonpath { template struct legacy_jsonpath_traits { using char_type = typename Json::char_type; using string_type = typename Json::string_type; using string_view_type = typename Json::string_view_type; using element_type = Json; using value_type = typename std::remove_cv::type; using reference = JsonReference; using const_reference = const value_type&; using pointer = typename std::conditional::type>::value,typename Json::const_pointer,typename Json::pointer>::type; using allocator_type = typename value_type::allocator_type; using evaluator_type = typename jsoncons::jsonpath::detail::jsonpath_evaluator; using path_node_type = basic_path_node; using path_expression_type = jsoncons::jsonpath::detail::path_expression; using path_pointer = const path_node_type*; }; template Json json_query(const Json& root, const typename Json::string_view_type& path, result_options options = result_options(), const custom_functions& functions = custom_functions()) { auto expr = make_expression(path, functions); return expr.evaluate(root, options); } template typename std::enable_if::value,void>::type json_query(const Json& root, const typename Json::string_view_type& path, Callback callback, result_options options = result_options(), const custom_functions& functions = custom_functions()) { auto expr = make_expression(path, functions); expr.evaluate(root, callback, options); } template Json json_query(const allocator_set& alloc_set, const Json& root, const typename Json::string_view_type& path, result_options options = result_options(), const custom_functions& functions = custom_functions()) { auto expr = make_expression(alloc_set, path, functions); return expr.evaluate(root, options); } template typename std::enable_if::value,void>::type json_query(const allocator_set& alloc_set, const Json& root, const typename Json::string_view_type& path, Callback callback, result_options options = result_options(), const custom_functions& functions = custom_functions()) { auto expr = make_expression(alloc_set, path, functions); expr.evaluate(root, callback, options); } template typename std::enable_if::value,void>::type json_replace(Json& root, const typename Json::string_view_type& path, T&& new_value, const custom_functions& funcs = custom_functions()) { using jsonpath_traits_type = jsoncons::jsonpath::legacy_jsonpath_traits; using value_type = typename jsonpath_traits_type::value_type; using reference = typename jsonpath_traits_type::reference; using evaluator_type = typename jsonpath_traits_type::evaluator_type; using path_expression_type = typename jsonpath_traits_type::path_expression_type; using path_node_type = typename jsonpath_traits_type::path_node_type; auto resources = jsoncons::make_unique>(funcs); evaluator_type evaluator; path_expression_type expr = evaluator.compile(*resources, path); jsoncons::jsonpath::detail::eval_context context; auto callback = [&new_value](const path_node_type&, reference v) { v = std::forward(new_value); }; result_options options = result_options::nodups | result_options::path | result_options::sort_descending; expr.evaluate(context, root, path_node_type{}, root, callback, options); } template typename std::enable_if::value,void>::type json_replace(const allocator_set& alloc_set, Json& root, const typename Json::string_view_type& path, T&& new_value, const custom_functions& funcs = custom_functions()) { using jsonpath_traits_type = jsoncons::jsonpath::legacy_jsonpath_traits; using value_type = typename jsonpath_traits_type::value_type; using reference = typename jsonpath_traits_type::reference; using evaluator_type = typename jsonpath_traits_type::evaluator_type; using path_expression_type = typename jsonpath_traits_type::path_expression_type; using path_node_type = typename jsonpath_traits_type::path_node_type; auto resources = jsoncons::make_unique>(funcs, alloc_set.get_allocator()); evaluator_type evaluator{alloc_set.get_allocator()}; path_expression_type expr = evaluator.compile(*resources, path); jsoncons::jsonpath::detail::eval_context context{alloc_set.get_allocator()}; auto callback = [&new_value](const path_node_type&, reference v) { v = Json(std::forward(new_value), semantic_tag::none); }; result_options options = result_options::nodups | result_options::path | result_options::sort_descending; expr.evaluate(context, root, path_node_type{}, root, callback, options); } template typename std::enable_if::value,void>::type json_replace(Json& root, const typename Json::string_view_type& path , BinaryCallback callback, const custom_functions& funcs = custom_functions()) { using jsonpath_traits_type = jsoncons::jsonpath::legacy_jsonpath_traits; using value_type = typename jsonpath_traits_type::value_type; using reference = typename jsonpath_traits_type::reference; using evaluator_type = typename jsonpath_traits_type::evaluator_type; using path_expression_type = typename jsonpath_traits_type::path_expression_type; using path_node_type = typename jsonpath_traits_type::path_node_type; auto resources = jsoncons::make_unique>(funcs); evaluator_type evaluator; path_expression_type expr = evaluator.compile(*resources, path); jsoncons::jsonpath::detail::eval_context context; auto f = [&callback](const path_node_type& path, reference val) { callback(to_basic_string(path), val); }; result_options options = result_options::nodups | result_options::path | result_options::sort_descending; expr.evaluate(context, root, path_node_type{}, root, f, options); } template typename std::enable_if::value,void>::type json_replace(const allocator_set& alloc_set, Json& root, const typename Json::string_view_type& path , BinaryCallback callback, const custom_functions& funcs = custom_functions()) { using jsonpath_traits_type = jsoncons::jsonpath::legacy_jsonpath_traits; using value_type = typename jsonpath_traits_type::value_type; using reference = typename jsonpath_traits_type::reference; using evaluator_type = typename jsonpath_traits_type::evaluator_type; using path_expression_type = typename jsonpath_traits_type::path_expression_type; using path_node_type = typename jsonpath_traits_type::path_node_type; auto resources = jsoncons::make_unique>(funcs, alloc_set.get_allocator()); evaluator_type evaluator{alloc_set.get_allocator()}; path_expression_type expr = evaluator.compile(*resources, path); jsoncons::jsonpath::detail::eval_context context{alloc_set.get_allocator()}; auto f = [&callback](const path_node_type& path, reference val) { callback(to_basic_string(path), val); }; result_options options = result_options::nodups | result_options::path | result_options::sort_descending; expr.evaluate(context, root, path_node_type{}, root, f, options); } // Legacy replace function template typename std::enable_if::value,void>::type json_replace(Json& root, const typename Json::string_view_type& path , UnaryCallback callback) { using jsonpath_traits_type = jsoncons::jsonpath::legacy_jsonpath_traits; using value_type = typename jsonpath_traits_type::value_type; using reference = typename jsonpath_traits_type::reference; using evaluator_type = typename jsonpath_traits_type::evaluator_type; using path_expression_type = typename jsonpath_traits_type::path_expression_type; using path_node_type = typename jsonpath_traits_type::path_node_type; auto resources = jsoncons::make_unique>(); evaluator_type evaluator; path_expression_type expr = evaluator.compile(*resources, path); jsoncons::jsonpath::detail::eval_context context; auto f = [callback](const path_node_type&, reference v) { v = callback(v); }; result_options options = result_options::nodups | result_options::path | result_options::sort_descending; expr.evaluate(context, root, path_node_type{}, root, f, options); } } // namespace jsonpath } // namespace jsoncons #endif // JSONCONS_EXT_JSONPATH_JSON_QUERY_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonpath/jsonpath.hpp000066400000000000000000000010201477700171100236730ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONPATH_JSONPATH_HPP #define JSONCONS_EXT_JSONPATH_JSONPATH_HPP #include #include #include #endif // JSONCONS_EXT_JSONPATH_JSONPATH_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonpath/jsonpath_error.hpp000066400000000000000000000227031477700171100251170ustar00rootroot00000000000000/// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONPATH_JSONPATH_ERROR_HPP #define JSONCONS_EXT_JSONPATH_JSONPATH_ERROR_HPP #include #include #include #include #include #include namespace jsoncons { namespace jsonpath { enum class jsonpath_errc { success = 0, expected_root_or_current_node, expected_lbracket_or_dot, expected_single_quote_or_digit, expected_root_or_function, expected_current_node, expected_rparen, expected_rbracket, expected_separator, expected_forward_slash, expected_slice_start, expected_slice_end, expected_slice_step, expected_bracket_specifier_or_union, unexpected_operator, invalid_function_name, invalid_argument, invalid_arity, function_name_not_found, parse_error_in_filter, argument_parse_error, unidentified_error, unexpected_eof, expected_colon_dot_left_bracket_comma_or_rbracket, argument_to_unflatten_invalid, invalid_flattened_key, step_cannot_be_zero, invalid_number, illegal_escaped_character, invalid_codepoint, unknown_function, invalid_type, unbalanced_parentheses, syntax_error, expected_comparator, expected_or, expected_and, expected_comma_or_rparen, expected_comma_or_rbracket, expected_relative_path }; class jsonpath_error_category_impl : public std::error_category { public: const char* name() const noexcept override { return "jsoncons/jsonpath"; } std::string message(int ev) const override { switch (static_cast(ev)) { case jsonpath_errc::expected_root_or_current_node: return "Expected '$' or '@'"; case jsonpath_errc::expected_lbracket_or_dot: return "Expected '[' or '.'"; case jsonpath_errc::expected_single_quote_or_digit: return "Expected '\'' or digit"; case jsonpath_errc::expected_root_or_function: return "Expected '$' or function expression"; case jsonpath_errc::expected_current_node: return "Expected @"; case jsonpath_errc::expected_rbracket: return "Expected ]"; case jsonpath_errc::expected_rparen: return "Expected )"; case jsonpath_errc::expected_slice_start: return "Expected slice start"; case jsonpath_errc::expected_slice_end: return "Expected slice end"; case jsonpath_errc::expected_slice_step: return "Expected slice step"; case jsonpath_errc::expected_separator: return "Expected dot or left bracket separator"; case jsonpath_errc::expected_forward_slash: return "Invalid path filter, expected '/'"; case jsonpath_errc::expected_bracket_specifier_or_union: return "Expected index, single or double quoted name, expression, filter, absolute ('$') path or relative ('@') path"; case jsonpath_errc::invalid_function_name: return "Invalid function name"; case jsonpath_errc::invalid_argument: return "Invalid argument type"; case jsonpath_errc::invalid_arity: return "Incorrect number of arguments"; case jsonpath_errc::function_name_not_found: return "Function name not found"; case jsonpath_errc::parse_error_in_filter: return "Could not parse JSON expression in a JSONPath filter"; case jsonpath_errc::argument_parse_error: return "Could not parse JSON expression passed to JSONPath function"; case jsonpath_errc::unidentified_error: return "Unidentified error"; case jsonpath_errc::unexpected_eof: return "Unexpected EOF while parsing jsonpath expression"; case jsonpath_errc::expected_colon_dot_left_bracket_comma_or_rbracket: return "Expected ':', '.', '[', ',', or ']'"; case jsonpath_errc::argument_to_unflatten_invalid: return "Argument to unflatten must be an object"; case jsonpath_errc::invalid_flattened_key: return "Flattened key is invalid"; case jsonpath_errc::step_cannot_be_zero: return "Slice step cannot be zero"; case jsonpath_errc::invalid_number: return "Invalid number"; case jsonpath_errc::illegal_escaped_character: return "Illegal escaped character"; case jsonpath_errc::invalid_codepoint: return "Invalid codepoint"; case jsonpath_errc::unknown_function: return "Unknown function"; case jsonpath_errc::invalid_type: return "Invalid type"; case jsonpath_errc::unbalanced_parentheses: return "Unbalanced parentheses"; case jsonpath_errc::syntax_error: return "Syntax error"; case jsonpath_errc::expected_comparator: return "Expected comparator"; case jsonpath_errc::expected_or: return "Expected operator '||'"; case jsonpath_errc::expected_and: return "Expected operator '&&'"; case jsonpath_errc::expected_comma_or_rparen: return "Expected comma or right parenthesis"; case jsonpath_errc::expected_comma_or_rbracket: return "Expected comma or right bracket"; case jsonpath_errc::expected_relative_path: return "Expected unquoted string, or single or double quoted string, or index or '*'"; default: return "Unknown jsonpath parser error"; } } }; inline const std::error_category& jsonpath_error_category() { static jsonpath_error_category_impl instance; return instance; } inline std::error_code make_error_code(jsonpath_errc result) { return std::error_code(static_cast(result),jsonpath_error_category()); } } // namespace jsonpath } // namespace jsoncons namespace std { template<> struct is_error_code_enum : public true_type { }; } // namespace std namespace jsoncons { namespace jsonpath { class jsonpath_error : public std::system_error, public virtual json_exception { std::size_t line_number_{0}; std::size_t column_number_{0}; mutable std::string what_; public: jsonpath_error(std::error_code ec) : std::system_error(ec) { } jsonpath_error(std::error_code ec, const std::string& what_arg) : std::system_error(ec, what_arg) { } jsonpath_error(std::error_code ec, std::size_t position) : std::system_error(ec), column_number_(position) { } jsonpath_error(std::error_code ec, std::size_t line, std::size_t column) : std::system_error(ec), line_number_(line), column_number_(column) { } jsonpath_error(const jsonpath_error& other) = default; jsonpath_error(jsonpath_error&& other) = default; ~jsonpath_error() override = default; const char* what() const noexcept override { if (what_.empty()) { JSONCONS_TRY { what_.append(std::system_error::what()); if (line_number_ != 0 && column_number_ != 0) { what_.append(" at line "); what_.append(std::to_string(line_number_)); what_.append(" and column "); what_.append(std::to_string(column_number_)); } else if (column_number_ != 0) { what_.append(" at position "); what_.append(std::to_string(column_number_)); } return what_.c_str(); } JSONCONS_CATCH(...) { return std::system_error::what(); } } else { return what_.c_str(); } } std::size_t line() const noexcept { return line_number_; } std::size_t column() const noexcept { return column_number_; } }; } // namespace jsonpath } // namespace jsoncons #endif // JSONCONS_EXT_JSONPATH_JSONPATH_ERROR_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonpath/jsonpath_expression.hpp000066400000000000000000000306371477700171100261720ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONPATH_JSONPATH_EXPRESSION_HPP #define JSONCONS_EXT_JSONPATH_JSONPATH_EXPRESSION_HPP #include // std::reverse #include #include #include #include // std::is_const #include // std::move #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace jsonpath { template > class jsonpath_expression { public: using allocator_type = typename jsonpath_traits::allocator_type; using char_type = typename jsonpath_traits::char_type; using string_type = typename jsonpath_traits::string_type; using string_view_type = typename jsonpath_traits::string_view_type; using value_type = typename jsonpath_traits::value_type; using reference = typename jsonpath_traits::reference; using const_reference = typename jsonpath_traits::const_reference; using static_resources_type = jsoncons::jsonpath::detail::static_resources; using path_expression_type = jsoncons::jsonpath::detail::path_expression; using const_path_expression_type = jsoncons::jsonpath::detail::path_expression; using path_node_type = basic_path_node; private: allocator_type alloc_; std::unique_ptr static_resources_; const_path_expression_type const_expr_; path_expression_type expr_; public: jsonpath_expression(const allocator_set& alloc_set, std::unique_ptr&& resources, const_path_expression_type&& const_expr, path_expression_type&& expr) : alloc_(alloc_set.get_allocator()), static_resources_(std::move(resources)), const_expr_(std::move(const_expr)), expr_(std::move(expr)) { } jsonpath_expression(const jsonpath_expression&) = delete; jsonpath_expression(jsonpath_expression&&) = default; ~jsonpath_expression() = default; jsonpath_expression& operator=(const jsonpath_expression&) = delete; jsonpath_expression& operator=(jsonpath_expression&&) = default; template typename std::enable_if::value,void>::type evaluate(const_reference root, BinaryCallback callback, result_options options = result_options()) const { jsoncons::jsonpath::detail::eval_context context{alloc_}; auto f = [&callback](const path_node_type& path, const_reference val) { callback(to_basic_string(path), val); }; const_expr_.evaluate(context, root, path_node_type{}, root, f, options | result_options::path); } value_type evaluate(const_reference root, result_options options = result_options()) const { if ((options & result_options::path) == result_options::path) { jsoncons::jsonpath::detail::eval_context context{ alloc_ }; value_type result(json_array_arg, semantic_tag::none, alloc_); auto callback = [&result](const path_node_type& p, const_reference) { result.emplace_back(to_basic_string(p)); }; const_expr_.evaluate(context, root, path_node_type{}, root, callback, options); return result; } jsoncons::jsonpath::detail::eval_context context{ alloc_ }; return const_expr_.evaluate(context, root, path_node_type{}, root, options); } value_type select(const_reference root, result_options options = result_options()) const { if ((options & result_options::path) == result_options::path) { jsoncons::jsonpath::detail::eval_context context{ alloc_ }; value_type result(json_array_arg, semantic_tag::none, alloc_); auto callback = [&result](const path_node_type& p, const_reference) { result.emplace_back(to_basic_string(p)); }; const_expr_.evaluate(context, root, path_node_type{}, root, callback, options); return result; } jsoncons::jsonpath::detail::eval_context context{ alloc_ }; return const_expr_.evaluate(context, root, path_node_type{}, root, options); } template typename std::enable_if::value,void>::type select(const_reference root, BinaryCallback callback, result_options options = result_options()) const { jsoncons::jsonpath::detail::eval_context context{alloc_}; const_expr_.evaluate(context, root, path_node_type{}, root, callback, options | result_options::path); } template typename std::enable_if::value,void>::type update(reference root, BinaryCallback callback) const { jsoncons::jsonpath::detail::eval_context context{alloc_}; result_options options = result_options::nodups | result_options::path | result_options::sort_descending; expr_.evaluate(context, root, path_node_type{}, root, callback, options); } std::vector> select_paths(const_reference root, result_options options = result_options::nodups | result_options::sort) const { std::vector> result; options = options | result_options::path; auto callback = [&result](const path_node_type& path, const_reference) { result.emplace_back(path); }; jsoncons::jsonpath::detail::eval_context context{alloc_}; const_expr_.evaluate(context, root, path_node_type{}, root, callback, options); return result; } }; template jsonpath_expression make_expression(const typename Json::string_view_type& path, const jsoncons::jsonpath::custom_functions::value_type>& funcs = jsoncons::jsonpath::custom_functions::value_type>()) { using value_type = typename jsonpath_traits::value_type; using reference = typename jsonpath_traits::reference; using const_reference = typename jsonpath_traits::const_reference; using static_resources_type = jsoncons::jsonpath::detail::static_resources; using evaluator_type = typename jsoncons::jsonpath::detail::jsonpath_evaluator; using const_evaluator_type = typename jsoncons::jsonpath::detail::jsonpath_evaluator; auto resources = jsoncons::make_unique(funcs); const_evaluator_type const_evaluator; auto const_expr = const_evaluator.compile(*resources, path); evaluator_type evaluator; auto expr = evaluator.compile(*resources, path); return jsonpath_expression(jsoncons::combine_allocators(), std::move(resources), std::move(const_expr), std::move(expr)); } template jsonpath_expression make_expression(const typename Json::string_view_type& expr, std::error_code& ec) { return make_expression(jsoncons::combine_allocators(), expr, custom_functions(), ec); } template jsonpath_expression make_expression(const allocator_set& alloc_set, const typename Json::string_view_type& expr, std::error_code& ec) { return make_expression(alloc_set, expr, custom_functions(), ec); } template jsonpath_expression make_expression(const allocator_set& alloc_set, const typename Json::string_view_type& path, const custom_functions& funcs = custom_functions()) { using value_type = typename jsonpath_traits::value_type; using reference = typename jsonpath_traits::reference; using const_reference = typename jsonpath_traits::const_reference; using static_resources_type = jsoncons::jsonpath::detail::static_resources; using evaluator_type = typename jsoncons::jsonpath::detail::jsonpath_evaluator; using const_evaluator_type = typename jsoncons::jsonpath::detail::jsonpath_evaluator; auto resources = jsoncons::make_unique(funcs, alloc_set.get_allocator()); const_evaluator_type const_evaluator{alloc_set.get_allocator()}; auto const_expr = const_evaluator.compile(*resources, path); evaluator_type evaluator{alloc_set.get_allocator()}; auto expr = evaluator.compile(*resources, path); return jsonpath_expression(alloc_set, std::move(resources), std::move(const_expr), std::move(expr)); } template jsonpath_expression make_expression(const allocator_set& alloc_set, const typename Json::string_view_type& path, const jsoncons::jsonpath::custom_functions::value_type>& funcs, std::error_code& ec) { using value_type = typename jsonpath_traits::value_type; using reference = typename jsonpath_traits::reference; using const_reference = typename jsonpath_traits::const_reference; using static_resources_type = jsoncons::jsonpath::detail::static_resources; using evaluator_type = typename jsoncons::jsonpath::detail::jsonpath_evaluator; using const_evaluator_type = typename jsoncons::jsonpath::detail::jsonpath_evaluator; auto resources = jsoncons::make_unique(funcs); const_evaluator_type const_evaluator{alloc_set.get_allocator()}; auto const_expr = const_evaluator.compile(*resources, path, ec); evaluator_type evaluator{alloc_set.get_allocator()}; auto expr = evaluator.compile(*resources, path, ec); return jsonpath_expression(alloc_set, std::move(resources), std::move(const_expr), std::move(expr)); } template std::size_t remove(Json& root, const jsoncons::basic_string_view& path_string) { std::size_t count = 0; auto expr = jsonpath::make_expression(path_string); std::vector locations = expr.select_paths(root, jsonpath::result_options::nodups | jsonpath::result_options::sort_descending); for (const auto& location : locations) { std::size_t n = jsonpath::remove(root, location); count += n; } return count; } } // namespace jsonpath } // namespace jsoncons #endif // JSONCONS_EXT_JSONPATH_JSONPATH_EXPRESSION_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonpath/jsonpath_parser.hpp000066400000000000000000003560601477700171100252700ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONPATH_JSONPATH_PARSER_HPP #define JSONCONS_EXT_JSONPATH_JSONPATH_PARSER_HPP #include // std::reverse #include #include #include #include #include // std::is_const #include // std::move #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace jsonpath { namespace detail { enum class path_state { start, root_or_current_node, expect_function_expr, relative_path, relative_location, parent_operator, ancestor_depth, filter_expression, expression_rhs, recursive_descent_or_expression_lhs, path_or_literal_or_function, json_text_or_function, json_text_or_function_name, json_text_string, json_value, json_text, identifier_or_function_expr, name_or_lbracket, unquoted_string, anything, number, function_expression, argument, zero_or_one_arguments, one_or_more_arguments, identifier, single_quoted_string, double_quoted_string, bracketed_unquoted_name_or_union, union_expression, identifier_or_union, bracket_specifier_or_union, bracketed_wildcard, index_or_slice, wildcard_or_union, union_element, index_or_slice_or_union, integer, digit, slice_expression_stop, slice_expression_step, comma_or_rbracket, expect_rparen, expect_rbracket, quoted_string_escape_char, escape_u1, escape_u2, escape_u3, escape_u4, escape_expect_surrogate_pair1, escape_expect_surrogate_pair2, escape_u5, escape_u6, escape_u7, escape_u8, expression, comparator_expression, eq_or_regex, expect_regex, regex, regex_options, regex_pattern, cmp_lt_or_lte, cmp_gt_or_gte, cmp_ne, expect_or, expect_and }; template class jsonpath_evaluator : public ser_context { public: using allocator_type = typename Json::allocator_type; using char_type = typename Json::char_type; using string_type = typename Json::string_type; using string_view_type = typename Json::string_view_type; using path_value_pair_type = path_value_pair; using value_type = Json; using reference = JsonReference; using pointer = typename path_value_pair_type::value_pointer; using token_type = token; using path_expression_type = path_expression; using token_evaluator_type = token_evaluator; using path_node_type = basic_path_node; using selector_type = jsonpath_selector; private: allocator_type alloc_; std::size_t line_{1}; std::size_t column_{1}; const char_type* begin_input_{nullptr}; const char_type* end_input_{nullptr}; const char_type* p_{nullptr}; using argument_type = std::vector; std::vector function_stack_; std::vector state_stack_; std::vector output_stack_; std::vector operator_stack_; public: jsonpath_evaluator(const allocator_type& alloc = allocator_type()) : alloc_(alloc) { } jsonpath_evaluator(std::size_t line, std::size_t column, const allocator_type& alloc = allocator_type()) : alloc_(alloc), line_(line), column_(column) { } std::size_t line() const final { return line_; } std::size_t column() const final { return column_; } path_expression_type compile(static_resources& resources, const string_view_type& path) { std::error_code ec; auto result = compile(resources, path, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(jsonpath_error(ec, line_, column_)); } return result; } path_expression_type compile(static_resources& resources, const string_view_type& path, std::error_code& ec) { std::size_t selector_id = 0; string_type buffer(alloc_); string_type buffer2(alloc_); uint32_t cp = 0; uint32_t cp2 = 0; begin_input_ = path.data(); end_input_ = path.data() + path.length(); p_ = begin_input_; slice slic; bool paths_required = false; int ancestor_depth = 0; state_stack_.emplace_back(path_state::start); while (p_ < end_input_ && !state_stack_.empty()) { switch (state_stack_.back()) { case path_state::start: { switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '$': case '@': { push_token(resources, token_type(resources.new_selector(current_node_selector())), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.emplace_back(path_state::relative_location); ++p_; ++column_; break; } default: { state_stack_.emplace_back(path_state::relative_location); state_stack_.emplace_back(path_state::expect_function_expr); state_stack_.emplace_back(path_state::unquoted_string); break; } } break; } case path_state::root_or_current_node: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '$': push_token(resources, token_type(root_node_arg), ec); push_token(resources, token_type(resources.new_selector(root_selector(selector_id++))), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.pop_back(); ++p_; ++column_; break; case '@': push_token(resources, token_type(current_node_arg), ec); // ISSUE push_token(resources, token_type(resources.new_selector(current_node_selector())), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.pop_back(); ++p_; ++column_; break; default: ec = jsonpath_errc::syntax_error; return path_expression_type(alloc_); } break; case path_state::recursive_descent_or_expression_lhs: switch (*p_) { case '.': push_token(resources, token_type(resources.new_selector(recursive_selector())), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} ++p_; ++column_; state_stack_.back() = path_state::name_or_lbracket; break; default: state_stack_.back() = path_state::relative_path; break; } break; case path_state::name_or_lbracket: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '[': // [ can follow .. state_stack_.back() = path_state::bracket_specifier_or_union; ++p_; ++column_; break; default: buffer.clear(); state_stack_.back() = path_state::relative_path; break; } break; case path_state::json_text: { //std::cout << "literal: " << buffer << "\n"; push_token(resources, token_type(literal_arg, Json(buffer,semantic_tag::none,alloc_)), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} buffer.clear(); state_stack_.pop_back(); // json_value break; } case path_state::path_or_literal_or_function: { switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '$': case '@': state_stack_.back() = path_state::relative_location; state_stack_.push_back(path_state::root_or_current_node); break; case '(': { ++p_; ++column_; push_token(resources, lparen_arg, ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.back() = path_state::expect_rparen; state_stack_.emplace_back(path_state::expression_rhs); state_stack_.emplace_back(path_state::path_or_literal_or_function); break; } case '\'': state_stack_.back() = path_state::json_text; state_stack_.emplace_back(path_state::single_quoted_string); ++p_; ++column_; break; case '\"': state_stack_.back() = path_state::json_text; state_stack_.emplace_back(path_state::double_quoted_string); ++p_; ++column_; break; case '!': { ++p_; ++column_; push_token(resources, token_type(resources.get_unary_not()), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} break; } case '-': { ++p_; ++column_; push_token(resources, token_type(resources.get_unary_minus()), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} break; } case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': { state_stack_.back() = path_state::json_value; state_stack_.emplace_back(path_state::number); break; } default: { state_stack_.back() = path_state::json_text_or_function_name; break; } } break; } case path_state::json_text_or_function: { switch(*p_) { case '(': { auto f = resources.get_function(buffer, ec); if (JSONCONS_UNLIKELY(ec)) { return path_expression_type(alloc_); } buffer.clear(); push_token(resources, current_node_arg, ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} push_token(resources, token_type(f), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.back() = path_state::function_expression; state_stack_.emplace_back(path_state::zero_or_one_arguments); ++p_; ++column_; break; } default: { json_decoder decoder(alloc_); basic_json_parser parser; parser.update(buffer.data(),buffer.size()); parser.parse_some(decoder, ec); if (JSONCONS_UNLIKELY(ec)) { return path_expression_type(alloc_); } parser.finish_parse(decoder, ec); if (JSONCONS_UNLIKELY(ec)) { return path_expression_type(alloc_); } push_token(resources, token_type(literal_arg, decoder.get_result()), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} buffer.clear(); state_stack_.pop_back(); break; } } break; } case path_state::json_value: { json_decoder decoder(alloc_); basic_json_parser parser; parser.update(buffer.data(),buffer.size()); parser.parse_some(decoder, ec); if (JSONCONS_UNLIKELY(ec)) { return path_expression_type(alloc_); } parser.finish_parse(decoder, ec); if (JSONCONS_UNLIKELY(ec)) { return path_expression_type(alloc_); } push_token(resources, token_type(literal_arg, decoder.get_result()), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} buffer.clear(); state_stack_.pop_back(); break; } case path_state::json_text_or_function_name: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '{': case '[': { json_decoder decoder(alloc_); basic_json_parser parser; parser.update(p_,end_input_ - p_); parser.parse_some(decoder, ec); if (JSONCONS_UNLIKELY(ec)) { return path_expression_type(alloc_); } parser.finish_parse(decoder, ec); if (JSONCONS_UNLIKELY(ec)) { return path_expression_type(alloc_); } push_token(resources, token_type(literal_arg, decoder.get_result()), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} buffer.clear(); state_stack_.pop_back(); p_ = parser.current(); column_ = column_ + parser.column() - 1; break; } case '-':case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': state_stack_.back() = path_state::json_text_or_function; state_stack_.emplace_back(path_state::number); buffer.push_back(*p_); ++p_; ++column_; break; case '\"': state_stack_.back() = path_state::json_text_or_function; state_stack_.emplace_back(path_state::json_text_string); buffer.push_back(*p_); ++p_; ++column_; break; default: state_stack_.back() = path_state::json_text_or_function; state_stack_.emplace_back(path_state::unquoted_string); buffer.push_back(*p_); ++p_; ++column_; break; }; break; case path_state::number: switch (*p_) { case '-':case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': case 'e':case 'E':case '.': buffer.push_back(*p_); ++p_; ++column_; break; default: state_stack_.pop_back(); // number break; }; break; case path_state::json_text_string: switch (*p_) { case '\\': buffer.push_back(*p_); ++p_; ++column_; if (p_ == end_input_) { ec = jsonpath_errc::unexpected_eof; return path_expression_type(alloc_); } buffer.push_back(*p_); ++p_; ++column_; break; case '\"': buffer.push_back(*p_); state_stack_.pop_back(); ++p_; ++column_; break; default: buffer.push_back(*p_); ++p_; ++column_; break; }; break; case path_state::relative_path: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '*': push_token(resources, token_type(resources.new_selector(wildcard_selector())), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.pop_back(); ++p_; ++column_; break; case '\'': state_stack_.back() = path_state::identifier; state_stack_.emplace_back(path_state::single_quoted_string); ++p_; ++column_; break; case '\"': state_stack_.back() = path_state::identifier; state_stack_.emplace_back(path_state::double_quoted_string); ++p_; ++column_; break; case '[': case '.': ec = jsonpath_errc::expected_relative_path; return path_expression_type(alloc_); default: buffer.clear(); state_stack_.back() = path_state::identifier_or_function_expr; state_stack_.emplace_back(path_state::unquoted_string); break; } break; case path_state::identifier_or_function_expr: { switch(*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '(': { auto f = resources.get_function(buffer, ec); if (JSONCONS_UNLIKELY(ec)) { return path_expression_type(alloc_); } buffer.clear(); push_token(resources, current_node_arg, ec); push_token(resources, token_type(f), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.back() = path_state::function_expression; state_stack_.emplace_back(path_state::zero_or_one_arguments); ++p_; ++column_; break; } default: { push_token(resources, token_type(resources.new_selector(identifier_selector(buffer))), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} buffer.clear(); state_stack_.pop_back(); break; } } break; } case path_state::expect_function_expr: { switch(*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '(': { auto f = resources.get_function(buffer, ec); if (JSONCONS_UNLIKELY(ec)) { return path_expression_type(alloc_); } buffer.clear(); push_token(resources, current_node_arg, ec); push_token(resources, token_type(f), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.back() = path_state::function_expression; state_stack_.emplace_back(path_state::zero_or_one_arguments); ++p_; ++column_; break; } default: { ec = jsonpath_errc::expected_root_or_function; return path_expression_type(alloc_); } } break; } case path_state::function_expression: { switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ',': push_token(resources, token_type(current_node_arg), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} push_token(resources, token_type(begin_expression_arg), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.emplace_back(path_state::argument); state_stack_.emplace_back(path_state::expression_rhs); state_stack_.emplace_back(path_state::path_or_literal_or_function); ++p_; ++column_; break; case ')': { push_token(resources, token_type(end_function_arg), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.pop_back(); ++p_; ++column_; break; } default: ec = jsonpath_errc::syntax_error; return path_expression_type(alloc_); } break; } case path_state::zero_or_one_arguments: { switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ')': state_stack_.pop_back(); break; default: push_token(resources, token_type(begin_expression_arg), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.back() = path_state::one_or_more_arguments; state_stack_.emplace_back(path_state::argument); state_stack_.emplace_back(path_state::expression_rhs); state_stack_.emplace_back(path_state::path_or_literal_or_function); break; } break; } case path_state::one_or_more_arguments: { switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ')': state_stack_.pop_back(); break; case ',': push_token(resources, token_type(begin_expression_arg), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.emplace_back(path_state::argument); state_stack_.emplace_back(path_state::expression_rhs); state_stack_.emplace_back(path_state::path_or_literal_or_function); ++p_; ++column_; break; } break; } case path_state::argument: { switch(*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ',': case ')': { push_token(resources, token_type(end_argument_expression_arg), ec); push_token(resources, argument_arg, ec); //push_token(resources, argument_arg, ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.pop_back(); break; } default: ec = jsonpath_errc::expected_comma_or_rparen; return path_expression_type(alloc_); } break; } case path_state::unquoted_string: switch (*p_) { case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'g':case 'h':case 'i':case 'j':case 'k':case 'l':case 'm':case 'n':case 'o':case 'p':case 'q':case 'r':case 's':case 't':case 'u':case 'v':case 'w':case 'x':case 'y':case 'z': case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':case 'G':case 'H':case 'I':case 'J':case 'K':case 'L':case 'M':case 'N':case 'O':case 'P':case 'Q':case 'R':case 'S':case 'T':case 'U':case 'V':case 'W':case 'X':case 'Y':case 'Z': case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': case '_': buffer.push_back(*p_); ++p_; ++column_; break; default: if (typename std::make_unsigned::type(*p_) > 127) { buffer.push_back(*p_); ++p_; ++column_; } else { state_stack_.pop_back(); // unquoted_string } break; }; break; case path_state::relative_location: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '.': state_stack_.emplace_back(path_state::recursive_descent_or_expression_lhs); ++p_; ++column_; break; case '[': state_stack_.emplace_back(path_state::bracket_specifier_or_union); ++p_; ++column_; break; case '^': ancestor_depth = 0; state_stack_.emplace_back(path_state::parent_operator); state_stack_.emplace_back(path_state::ancestor_depth); break; default: state_stack_.pop_back(); break; }; break; case path_state::parent_operator: { push_token(resources, token_type(resources.new_selector(parent_node_selector(ancestor_depth))), ec); paths_required = true; ancestor_depth = 0; ++p_; ++column_; state_stack_.pop_back(); break; } case path_state::ancestor_depth: { switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '^': { ++ancestor_depth; ++p_; ++column_; break; } default: { state_stack_.pop_back(); break; } } break; } case path_state::expression_rhs: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '.': state_stack_.emplace_back(path_state::recursive_descent_or_expression_lhs); ++p_; ++column_; break; case '[': state_stack_.emplace_back(path_state::bracket_specifier_or_union); ++p_; ++column_; break; case ')': { state_stack_.pop_back(); break; } case '|': ++p_; ++column_; state_stack_.emplace_back(path_state::path_or_literal_or_function); state_stack_.emplace_back(path_state::expect_or); break; case '&': ++p_; ++column_; state_stack_.emplace_back(path_state::path_or_literal_or_function); state_stack_.emplace_back(path_state::expect_and); break; case '<': case '>': { state_stack_.emplace_back(path_state::comparator_expression); break; } case '=': { state_stack_.emplace_back(path_state::eq_or_regex); ++p_; ++column_; break; } case '!': { ++p_; ++column_; state_stack_.emplace_back(path_state::path_or_literal_or_function); state_stack_.emplace_back(path_state::cmp_ne); break; } case '+': state_stack_.emplace_back(path_state::path_or_literal_or_function); push_token(resources, token_type(resources.get_plus_operator()), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} ++p_; ++column_; break; case '-': state_stack_.emplace_back(path_state::path_or_literal_or_function); push_token(resources, token_type(resources.get_minus_operator()), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} ++p_; ++column_; break; case '*': state_stack_.emplace_back(path_state::path_or_literal_or_function); push_token(resources, token_type(resources.get_mult_operator()), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} ++p_; ++column_; break; case '/': state_stack_.emplace_back(path_state::path_or_literal_or_function); push_token(resources, token_type(resources.get_div_operator()), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} ++p_; ++column_; break; case '%': state_stack_.emplace_back(path_state::path_or_literal_or_function); push_token(resources, token_type(resources.get_modulus_operator()), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} ++p_; ++column_; break; case ']': case ',': state_stack_.pop_back(); break; default: ec = jsonpath_errc::expected_separator; return path_expression_type(alloc_); }; break; case path_state::expect_or: { switch (*p_) { case '|': push_token(resources, token_type(resources.get_or_operator()), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.pop_back(); ++p_; ++column_; break; default: ec = jsonpath_errc::expected_or; return path_expression_type(alloc_); } break; } case path_state::expect_and: { switch(*p_) { case '&': push_token(resources, token_type(resources.get_and_operator()), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.pop_back(); // expect_and ++p_; ++column_; break; default: ec = jsonpath_errc::expected_and; return path_expression_type(alloc_); } break; } case path_state::comparator_expression: switch(*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '<': ++p_; ++column_; state_stack_.back() = path_state::path_or_literal_or_function; state_stack_.emplace_back(path_state::cmp_lt_or_lte); break; case '>': ++p_; ++column_; state_stack_.back() = path_state::path_or_literal_or_function; state_stack_.emplace_back(path_state::cmp_gt_or_gte); break; default: if (state_stack_.size() > 1) { state_stack_.pop_back(); } else { ec = jsonpath_errc::syntax_error; return path_expression_type(alloc_); } break; } break; case path_state::eq_or_regex: switch(*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '=': { push_token(resources, token_type(resources.get_eq_operator()), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.back() = path_state::path_or_literal_or_function; ++p_; ++column_; break; } case '~': { ++p_; ++column_; state_stack_.emplace_back(path_state::expect_regex); break; } default: if (state_stack_.size() > 1) { state_stack_.pop_back(); } else { ec = jsonpath_errc::syntax_error; return path_expression_type(alloc_); } break; } break; case path_state::expect_regex: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '/': state_stack_.back() = path_state::regex; state_stack_.emplace_back(path_state::regex_options); state_stack_.emplace_back(path_state::regex_pattern); ++p_; ++column_; break; default: ec = jsonpath_errc::expected_forward_slash; return path_expression_type(alloc_); }; break; case path_state::regex: { std::regex::flag_type options = std::regex_constants::ECMAScript; if (buffer2.find('i') != string_type::npos) { options |= std::regex_constants::icase; } std::basic_regex pattern(buffer, options); push_token(resources, resources.get_regex_operator(std::move(pattern)), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} buffer.clear(); buffer2.clear(); state_stack_.pop_back(); break; } case path_state::regex_pattern: { switch (*p_) { case '/': { state_stack_.pop_back(); ++p_; ++column_; } break; default: buffer.push_back(*p_); ++p_; ++column_; break; } break; } case path_state::regex_options: { if (*p_ == 'i') { buffer2.push_back(*p_); ++p_; ++column_; } else { state_stack_.pop_back(); } break; } case path_state::cmp_lt_or_lte: { switch(*p_) { case '=': push_token(resources, token_type(resources.get_lte_operator()), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.pop_back(); ++p_; ++column_; break; default: push_token(resources, token_type(resources.get_lt_operator()), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.pop_back(); break; } break; } case path_state::cmp_gt_or_gte: { switch(*p_) { case '=': push_token(resources, token_type(resources.get_gte_operator()), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.pop_back(); ++p_; ++column_; break; default: //std::cout << "Parse: gt_operator\n"; push_token(resources, token_type(resources.get_gt_operator()), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.pop_back(); break; } break; } case path_state::cmp_ne: { switch(*p_) { case '=': push_token(resources, token_type(resources.get_ne_operator()), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.pop_back(); ++p_; ++column_; break; default: ec = jsonpath_errc::expected_comparator; return path_expression_type(alloc_); } break; } case path_state::identifier: push_token(resources, token_type(resources.new_selector(identifier_selector(buffer))), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} buffer.clear(); state_stack_.pop_back(); break; case path_state::single_quoted_string: switch (*p_) { case '\'': state_stack_.pop_back(); ++p_; ++column_; break; case '\\': state_stack_.emplace_back(path_state::quoted_string_escape_char); ++p_; ++column_; break; default: buffer.push_back(*p_); ++p_; ++column_; break; }; break; case path_state::double_quoted_string: switch (*p_) { case '\"': state_stack_.pop_back(); ++p_; ++column_; break; case '\\': state_stack_.emplace_back(path_state::quoted_string_escape_char); ++p_; ++column_; break; default: buffer.push_back(*p_); ++p_; ++column_; break; }; break; case path_state::comma_or_rbracket: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ',': state_stack_.back() = path_state::bracket_specifier_or_union; ++p_; ++column_; break; case ']': state_stack_.pop_back(); ++p_; ++column_; break; default: ec = jsonpath_errc::expected_comma_or_rbracket; return path_expression_type(alloc_); } break; case path_state::expect_rbracket: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ']': state_stack_.pop_back(); ++p_; ++column_; break; default: ec = jsonpath_errc::expected_rbracket; return path_expression_type(alloc_); } break; case path_state::expect_rparen: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ')': ++p_; ++column_; push_token(resources, rparen_arg, ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.back() = path_state::expression_rhs; break; default: ec = jsonpath_errc::expected_rparen; return path_expression_type(alloc_); } break; case path_state::bracket_specifier_or_union: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '(': { push_token(resources, token_type(begin_union_arg), ec); push_token(resources, token_type(begin_expression_arg), ec); push_token(resources, lparen_arg, ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.back() = path_state::union_expression; // union state_stack_.emplace_back(path_state::expression); state_stack_.emplace_back(path_state::expect_rparen); state_stack_.emplace_back(path_state::expression_rhs); state_stack_.emplace_back(path_state::path_or_literal_or_function); ++p_; ++column_; break; } case '?': { push_token(resources, token_type(begin_union_arg), ec); push_token(resources, token_type(begin_filter_arg), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.back() = path_state::union_expression; // union state_stack_.emplace_back(path_state::filter_expression); state_stack_.emplace_back(path_state::expression_rhs); state_stack_.emplace_back(path_state::path_or_literal_or_function); ++p_; ++column_; break; } case '*': state_stack_.back() = path_state::wildcard_or_union; ++p_; ++column_; break; case '\'': state_stack_.back() = path_state::identifier_or_union; state_stack_.push_back(path_state::single_quoted_string); ++p_; ++column_; break; case '\"': state_stack_.back() = path_state::identifier_or_union; state_stack_.push_back(path_state::double_quoted_string); ++p_; ++column_; break; case ':': // slice_expression state_stack_.back() = path_state::index_or_slice_or_union; break; case '-':case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': state_stack_.back() = path_state::index_or_slice_or_union; state_stack_.emplace_back(path_state::integer); break; case '$': push_token(resources, token_type(begin_union_arg), ec); push_token(resources, root_node_arg, ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.back() = path_state::union_expression; // union state_stack_.emplace_back(path_state::relative_location); ++p_; ++column_; break; case '@': push_token(resources, token_type(begin_union_arg), ec); push_token(resources, token_type(current_node_arg), ec); // ISSUE push_token(resources, token_type(resources.new_selector(current_node_selector())), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.back() = path_state::union_expression; // union state_stack_.emplace_back(path_state::relative_location); ++p_; ++column_; break; default: ec = jsonpath_errc::expected_bracket_specifier_or_union; return path_expression_type(alloc_); } break; case path_state::union_element: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ':': // slice_expression state_stack_.back() = path_state::index_or_slice; break; case '-':case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': state_stack_.back() = path_state::index_or_slice; state_stack_.emplace_back(path_state::integer); break; case '(': { push_token(resources, token_type(begin_expression_arg), ec); push_token(resources, lparen_arg, ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.back() = path_state::expression; state_stack_.emplace_back(path_state::expect_rparen); state_stack_.emplace_back(path_state::expression_rhs); state_stack_.emplace_back(path_state::path_or_literal_or_function); ++p_; ++column_; break; } case '?': { push_token(resources, token_type(begin_filter_arg), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.back() = path_state::filter_expression; state_stack_.emplace_back(path_state::expression_rhs); state_stack_.emplace_back(path_state::path_or_literal_or_function); ++p_; ++column_; break; } case '*': push_token(resources, token_type(resources.new_selector(wildcard_selector())), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.back() = path_state::relative_location; ++p_; ++column_; break; case '$': push_token(resources, token_type(root_node_arg), ec); push_token(resources, token_type(resources.new_selector(root_selector(selector_id++))), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.back() = path_state::relative_location; ++p_; ++column_; break; case '@': push_token(resources, token_type(current_node_arg), ec); // ISSUE push_token(resources, token_type(resources.new_selector(current_node_selector())), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.back() = path_state::relative_location; ++p_; ++column_; break; case '\'': state_stack_.back() = path_state::identifier; state_stack_.push_back(path_state::single_quoted_string); ++p_; ++column_; break; case '\"': state_stack_.back() = path_state::identifier; state_stack_.push_back(path_state::double_quoted_string); ++p_; ++column_; break; default: ec = jsonpath_errc::expected_bracket_specifier_or_union; return path_expression_type(alloc_); } break; case path_state::integer: switch(*p_) { case '-': buffer.push_back(*p_); state_stack_.back() = path_state::digit; ++p_; ++column_; break; default: state_stack_.back() = path_state::digit; break; } break; case path_state::digit: switch(*p_) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': buffer.push_back(*p_); ++p_; ++column_; break; default: state_stack_.pop_back(); // digit break; } break; case path_state::index_or_slice_or_union: switch(*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ']': { if (buffer.empty()) { ec = jsonpath_errc::invalid_number; return path_expression_type(alloc_); } int64_t n{0}; auto r = jsoncons::detail::to_integer(buffer.data(), buffer.size(), n); if (!r) { ec = jsonpath_errc::invalid_number; return path_expression_type(alloc_); } push_token(resources, token_type(resources.new_selector(index_selector(n))), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} buffer.clear(); state_stack_.pop_back(); // index_or_slice_or_union ++p_; ++column_; break; } case ',': { push_token(resources, token_type(begin_union_arg), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} if (buffer.empty()) { ec = jsonpath_errc::invalid_number; return path_expression_type(alloc_); } int64_t n{0}; auto r = jsoncons::detail::to_integer(buffer.data(), buffer.size(), n); if (!r) { ec = jsonpath_errc::invalid_number; return path_expression_type(alloc_); } push_token(resources, token_type(resources.new_selector(index_selector(n))), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} buffer.clear(); push_token(resources, token_type(separator_arg), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} buffer.clear(); state_stack_.back() = path_state::union_expression; // union state_stack_.emplace_back(path_state::union_element); ++p_; ++column_; break; } case ':': { if (!buffer.empty()) { int64_t n{0}; auto r = jsoncons::detail::to_integer(buffer.data(), buffer.size(), n); if (!r) { ec = jsonpath_errc::invalid_number; return path_expression_type(alloc_); } slic.start_ = n; buffer.clear(); } push_token(resources, token_type(begin_union_arg), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.back() = path_state::union_expression; // union state_stack_.emplace_back(path_state::slice_expression_stop); state_stack_.emplace_back(path_state::integer); ++p_; ++column_; break; } default: ec = jsonpath_errc::expected_rbracket; return path_expression_type(alloc_); } break; case path_state::slice_expression_stop: { if (!buffer.empty()) { int64_t n{0}; auto r = jsoncons::detail::to_integer(buffer.data(), buffer.size(), n); if (!r) { ec = jsonpath_errc::invalid_number; return path_expression_type(alloc_); } slic.stop_ = jsoncons::optional(n); buffer.clear(); } switch(*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ']': case ',': push_token(resources, token_type(resources.new_selector(slice_selector(slic))), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} slic = slice{}; state_stack_.pop_back(); // bracket_specifier2 break; case ':': state_stack_.back() = path_state::slice_expression_step; state_stack_.emplace_back(path_state::integer); ++p_; ++column_; break; default: ec = jsonpath_errc::expected_rbracket; return path_expression_type(alloc_); } break; } case path_state::slice_expression_step: { if (!buffer.empty()) { int64_t n{0}; auto r = jsoncons::detail::to_integer(buffer.data(), buffer.size(), n); if (!r) { ec = jsonpath_errc::invalid_number; return path_expression_type(alloc_); } if (n == 0) { ec = jsonpath_errc::step_cannot_be_zero; return path_expression_type(alloc_); } slic.step_ = n; buffer.clear(); } switch(*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ']': case ',': push_token(resources, token_type(resources.new_selector(slice_selector(slic))), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} buffer.clear(); slic = slice{}; state_stack_.pop_back(); // slice_expression_step break; default: ec = jsonpath_errc::expected_rbracket; return path_expression_type(alloc_); } break; } case path_state::bracketed_unquoted_name_or_union: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ']': push_token(resources, token_type(resources.new_selector(identifier_selector(buffer))), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} buffer.clear(); state_stack_.pop_back(); ++p_; ++column_; break; case '.': push_token(resources, token_type(begin_union_arg), ec); push_token(resources, token_type(resources.new_selector(identifier_selector(buffer))), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} buffer.clear(); state_stack_.back() = path_state::union_expression; // union state_stack_.emplace_back(path_state::relative_path); ++p_; ++column_; break; case '[': push_token(resources, token_type(begin_union_arg), ec); push_token(resources, token_type(resources.new_selector(identifier_selector(buffer))), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.back() = path_state::union_expression; // union state_stack_.emplace_back(path_state::relative_path); ++p_; ++column_; break; case ',': push_token(resources, token_type(begin_union_arg), ec); push_token(resources, token_type(resources.new_selector(identifier_selector(buffer))), ec); push_token(resources, token_type(separator_arg), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} buffer.clear(); state_stack_.back() = path_state::union_expression; // union state_stack_.emplace_back(path_state::relative_path); ++p_; ++column_; break; default: buffer.push_back(*p_); ++p_; ++column_; break; } break; case path_state::union_expression: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '.': state_stack_.emplace_back(path_state::relative_path); ++p_; ++column_; break; case '[': state_stack_.emplace_back(path_state::bracket_specifier_or_union); ++p_; ++column_; break; case ',': push_token(resources, token_type(separator_arg), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.emplace_back(path_state::union_element); ++p_; ++column_; break; case ']': push_token(resources, token_type(end_union_arg), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.pop_back(); ++p_; ++column_; break; default: ec = jsonpath_errc::expected_rbracket; return path_expression_type(alloc_); } break; case path_state::identifier_or_union: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ']': push_token(resources, token_type(resources.new_selector(identifier_selector(buffer))), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} buffer.clear(); state_stack_.pop_back(); ++p_; ++column_; break; case ',': push_token(resources, token_type(begin_union_arg), ec); push_token(resources, token_type(resources.new_selector(identifier_selector(buffer))), ec); push_token(resources, token_type(separator_arg), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} buffer.clear(); state_stack_.back() = path_state::union_expression; // union state_stack_.emplace_back(path_state::union_element); ++p_; ++column_; break; default: ec = jsonpath_errc::expected_rbracket; return path_expression_type(alloc_); } break; case path_state::bracketed_wildcard: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case '[': case ']': case ',': case '.': push_token(resources, token_type(resources.new_selector(wildcard_selector())), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} buffer.clear(); state_stack_.pop_back(); break; default: ec = jsonpath_errc::expected_rbracket; return path_expression_type(alloc_); } break; case path_state::index_or_slice: switch(*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ',': case ']': { if (buffer.empty()) { ec = jsonpath_errc::invalid_number; return path_expression_type(alloc_); } int64_t n{0}; auto r = jsoncons::detail::to_integer(buffer.data(), buffer.size(), n); if (!r) { ec = jsonpath_errc::invalid_number; return path_expression_type(alloc_); } push_token(resources, token_type(resources.new_selector(index_selector(n))), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} buffer.clear(); state_stack_.pop_back(); // bracket_specifier break; } case ':': { if (!buffer.empty()) { int64_t n{0}; auto r = jsoncons::detail::to_integer(buffer.data(), buffer.size(), n); if (!r) { ec = jsonpath_errc::invalid_number; return path_expression_type(alloc_); } slic.start_ = n; buffer.clear(); } state_stack_.back() = path_state::slice_expression_stop; state_stack_.emplace_back(path_state::integer); ++p_; ++column_; break; } default: ec = jsonpath_errc::expected_rbracket; return path_expression_type(alloc_); } break; case path_state::wildcard_or_union: switch (*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ']': push_token(resources, token_type(resources.new_selector(wildcard_selector())), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} buffer.clear(); state_stack_.pop_back(); ++p_; ++column_; break; case ',': push_token(resources, token_type(begin_union_arg), ec); push_token(resources, token_type(resources.new_selector(wildcard_selector())), ec); push_token(resources, token_type(separator_arg), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} buffer.clear(); state_stack_.back() = path_state::union_expression; // union state_stack_.emplace_back(path_state::union_element); ++p_; ++column_; break; default: ec = jsonpath_errc::expected_rbracket; return path_expression_type(alloc_); } break; case path_state::quoted_string_escape_char: switch (*p_) { case '\"': buffer.push_back('\"'); ++p_; ++column_; state_stack_.pop_back(); break; case '\'': buffer.push_back('\''); ++p_; ++column_; state_stack_.pop_back(); break; case '\\': buffer.push_back('\\'); ++p_; ++column_; state_stack_.pop_back(); break; case '/': buffer.push_back('/'); ++p_; ++column_; state_stack_.pop_back(); break; case 'b': buffer.push_back('\b'); ++p_; ++column_; state_stack_.pop_back(); break; case 'f': buffer.push_back('\f'); ++p_; ++column_; state_stack_.pop_back(); break; case 'n': buffer.push_back('\n'); ++p_; ++column_; state_stack_.pop_back(); break; case 'r': buffer.push_back('\r'); ++p_; ++column_; state_stack_.pop_back(); break; case 't': buffer.push_back('\t'); ++p_; ++column_; state_stack_.pop_back(); break; case 'u': ++p_; ++column_; state_stack_.back() = path_state::escape_u1; break; default: ec = jsonpath_errc::illegal_escaped_character; return path_expression_type(alloc_); } break; case path_state::escape_u1: cp = append_to_codepoint(0, *p_, ec); if (JSONCONS_UNLIKELY(ec)) { return path_expression_type(alloc_); } ++p_; ++column_; state_stack_.back() = path_state::escape_u2; break; case path_state::escape_u2: cp = append_to_codepoint(cp, *p_, ec); if (JSONCONS_UNLIKELY(ec)) { return path_expression_type(alloc_); } ++p_; ++column_; state_stack_.back() = path_state::escape_u3; break; case path_state::escape_u3: cp = append_to_codepoint(cp, *p_, ec); if (JSONCONS_UNLIKELY(ec)) { return path_expression_type(alloc_); } ++p_; ++column_; state_stack_.back() = path_state::escape_u4; break; case path_state::escape_u4: cp = append_to_codepoint(cp, *p_, ec); if (JSONCONS_UNLIKELY(ec)) { return path_expression_type(alloc_); } if (unicode_traits::is_high_surrogate(cp)) { ++p_; ++column_; state_stack_.back() = path_state::escape_expect_surrogate_pair1; } else { unicode_traits::convert(&cp, 1, buffer); ++p_; ++column_; state_stack_.pop_back(); } break; case path_state::escape_expect_surrogate_pair1: switch (*p_) { case '\\': ++p_; ++column_; state_stack_.back() = path_state::escape_expect_surrogate_pair2; break; default: ec = jsonpath_errc::invalid_codepoint; return path_expression_type(alloc_); } break; case path_state::escape_expect_surrogate_pair2: switch (*p_) { case 'u': ++p_; ++column_; state_stack_.back() = path_state::escape_u5; break; default: ec = jsonpath_errc::invalid_codepoint; return path_expression_type(alloc_); } break; case path_state::escape_u5: cp2 = append_to_codepoint(0, *p_, ec); if (JSONCONS_UNLIKELY(ec)) { return path_expression_type(alloc_); } ++p_; ++column_; state_stack_.back() = path_state::escape_u6; break; case path_state::escape_u6: cp2 = append_to_codepoint(cp2, *p_, ec); if (JSONCONS_UNLIKELY(ec)) { return path_expression_type(alloc_); } ++p_; ++column_; state_stack_.back() = path_state::escape_u7; break; case path_state::escape_u7: cp2 = append_to_codepoint(cp2, *p_, ec); if (JSONCONS_UNLIKELY(ec)) { return path_expression_type(alloc_); } ++p_; ++column_; state_stack_.back() = path_state::escape_u8; break; case path_state::escape_u8: { cp2 = append_to_codepoint(cp2, *p_, ec); if (JSONCONS_UNLIKELY(ec)) { return path_expression_type(alloc_); } uint32_t codepoint = 0x10000 + ((cp & 0x3FF) << 10) + (cp2 & 0x3FF); unicode_traits::convert(&codepoint, 1, buffer); state_stack_.pop_back(); ++p_; ++column_; break; } case path_state::filter_expression: { switch(*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ',': case ']': { push_token(resources, token_type(end_filter_arg), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.pop_back(); break; } default: ec = jsonpath_errc::expected_comma_or_rbracket; return path_expression_type(alloc_); } break; } case path_state::expression: { switch(*p_) { case ' ':case '\t':case '\r':case '\n': advance_past_space_character(); break; case ',': case ']': { push_token(resources, token_type(end_index_expression_arg), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} state_stack_.pop_back(); break; } default: ec = jsonpath_errc::expected_comma_or_rbracket; return path_expression_type(alloc_); } break; } default: ++p_; ++column_; break; } } if (state_stack_.empty()) { ec = jsonpath_errc::syntax_error; return path_expression_type(alloc_); } while (state_stack_.size() > 1) { switch (state_stack_.back()) { case path_state::name_or_lbracket: state_stack_.back() = path_state::relative_path; break; case path_state::relative_path: state_stack_.back() = path_state::identifier_or_function_expr; state_stack_.emplace_back(path_state::unquoted_string); break; case path_state::identifier_or_function_expr: if (!buffer.empty()) // Can't be quoted string { push_token(resources, token_type(resources.new_selector(identifier_selector(buffer))), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} } state_stack_.pop_back(); break; case path_state::unquoted_string: state_stack_.pop_back(); // unquoted_string break; case path_state::relative_location: state_stack_.pop_back(); break; case path_state::identifier: if (!buffer.empty()) // Can't be quoted string { push_token(resources, token_type(resources.new_selector(identifier_selector(buffer))), ec); if (JSONCONS_UNLIKELY(ec)) {return path_expression_type(alloc_);} } state_stack_.pop_back(); break; case path_state::parent_operator: { push_token(resources, token_type(resources.new_selector(parent_node_selector(ancestor_depth))), ec); if (JSONCONS_UNLIKELY(ec)) { return path_expression_type(alloc_); } paths_required = true; state_stack_.pop_back(); break; } case path_state::ancestor_depth: state_stack_.pop_back(); break; default: ec = jsonpath_errc::syntax_error; return path_expression_type(alloc_); } } if (state_stack_.size() > 2) { ec = jsonpath_errc::unexpected_eof; return path_expression_type(alloc_); } //std::cout << "\nTokens\n\n"; //for (const auto& tok : output_stack_) //{ // std::cout << tok.to_string(0) << "\n"; //} //std::cout << "\n"; if (output_stack_.empty() || !operator_stack_.empty()) { ec = jsonpath_errc::unexpected_eof; return path_expression_type(alloc_); } return path_expression_type(output_stack_.back().selector_, paths_required, alloc_); } void advance_past_space_character() { switch (*p_) { case ' ':case '\t': ++p_; ++column_; break; case '\r': if (p_+1 < end_input_ && *(p_+1) == '\n') { ++p_; } ++line_; column_ = 1; ++p_; break; case '\n': ++line_; column_ = 1; ++p_; break; default: break; } } void unwind_rparen(std::error_code& ec) { auto it = operator_stack_.rbegin(); while (it != operator_stack_.rend() && !(*it).is_lparen()) { output_stack_.emplace_back(std::move(*it)); ++it; } if (it == operator_stack_.rend()) { ec = jsonpath_errc::unbalanced_parentheses; return; } ++it; operator_stack_.erase(it.base(),operator_stack_.end()); } void push_token(jsoncons::jsonpath::detail::static_resources& resources, token_type&& tok, std::error_code& ec) { //std::cout << tok.to_string(0) << "\n"; switch (tok.token_kind()) { case jsonpath_token_kind::begin_filter: output_stack_.emplace_back(std::move(tok)); operator_stack_.emplace_back(token_type(lparen_arg)); break; case jsonpath_token_kind::end_filter: { //std::cout << "push_token end_filter 1\n"; //for (const auto& tok2 : output_stack_) //{ // std::cout << tok2.to_string(0) << "\n"; //} //std::cout << "\n\n"; unwind_rparen(ec); if (JSONCONS_UNLIKELY(ec)) { return; } std::vector toks; auto it = output_stack_.rbegin(); while (it != output_stack_.rend() && (*it).token_kind() != jsonpath_token_kind::begin_filter) { toks.emplace_back(std::move(*it)); ++it; } if (it == output_stack_.rend()) { ec = jsonpath_errc::unbalanced_parentheses; return; } std::reverse(toks.begin(), toks.end()); ++it; output_stack_.erase(it.base(),output_stack_.end()); if (!output_stack_.empty() && output_stack_.back().is_path()) { output_stack_.back().selector_->append_selector(resources.new_selector(filter_selector(token_evaluator_type(std::move(toks))))); } else { output_stack_.emplace_back(token_type(resources.new_selector(filter_selector(token_evaluator_type(std::move(toks)))))); } //std::cout << "push_token end_filter 2\n"; //for (const auto& tok2 : output_stack_) //{ // std::cout << tok2.to_string(0) << "\n"; //} //std::cout << "\n\n"; break; } case jsonpath_token_kind::begin_expression: //std::cout << "begin_expression\n"; output_stack_.emplace_back(std::move(tok)); operator_stack_.emplace_back(token_type(lparen_arg)); break; case jsonpath_token_kind::end_index_expression: { //std::cout << "jsonpath_token_kind::end_index_expression\n"; //for (const auto& t : output_stack_) //{ // std::cout << t.to_string(0) << "\n"; //} //std::cout << "/jsonpath_token_kind::end_index_expression\n"; unwind_rparen(ec); if (JSONCONS_UNLIKELY(ec)) { return; } std::vector toks; auto it = output_stack_.rbegin(); while (it != output_stack_.rend() && (*it).token_kind() != jsonpath_token_kind::begin_expression) { toks.emplace_back(std::move(*it)); ++it; } if (it == output_stack_.rend()) { ec = jsonpath_errc::unbalanced_parentheses; return; } std::reverse(toks.begin(), toks.end()); ++it; output_stack_.erase(it.base(),output_stack_.end()); if (!output_stack_.empty() && output_stack_.back().is_path()) { output_stack_.back().selector_->append_selector(resources.new_selector(index_expression_selector(token_evaluator_type(std::move(toks))))); } else { output_stack_.emplace_back(token_type(resources.new_selector(index_expression_selector(token_evaluator_type(std::move(toks)))))); } break; } case jsonpath_token_kind::end_argument_expression: { //std::cout << "jsonpath_token_kind::end_index_expression\n"; //for (const auto& t : output_stack_) //{ // std::cout << t.to_string(0) << "\n"; //} //std::cout << "/jsonpath_token_kind::end_index_expression\n"; unwind_rparen(ec); if (JSONCONS_UNLIKELY(ec)) { return; } std::vector toks; auto it = output_stack_.rbegin(); while (it != output_stack_.rend() && (*it).token_kind() != jsonpath_token_kind::begin_expression) { toks.emplace_back(std::move(*it)); ++it; } if (it == output_stack_.rend()) { ec = jsonpath_errc::unbalanced_parentheses; return; } std::reverse(toks.begin(), toks.end()); ++it; output_stack_.erase(it.base(),output_stack_.end()); output_stack_.emplace_back(token_type(jsoncons::make_unique(std::move(toks)))); break; } case jsonpath_token_kind::selector: { if (!output_stack_.empty() && output_stack_.back().is_path()) { output_stack_.back().selector_->append_selector(std::move(tok.selector_)); } else { output_stack_.emplace_back(std::move(tok)); } break; } case jsonpath_token_kind::separator: output_stack_.emplace_back(std::move(tok)); break; case jsonpath_token_kind::begin_union: output_stack_.emplace_back(std::move(tok)); break; case jsonpath_token_kind::end_union: { std::vector expressions; auto it = output_stack_.rbegin(); while (it != output_stack_.rend() && (*it).token_kind() != jsonpath_token_kind::begin_union) { if ((*it).token_kind() == jsonpath_token_kind::selector) { expressions.emplace_back(std::move((*it).selector_)); } do { ++it; } while (it != output_stack_.rend() && (*it).token_kind() != jsonpath_token_kind::begin_union && (*it).token_kind() != jsonpath_token_kind::separator); if ((*it).token_kind() == jsonpath_token_kind::separator) { ++it; } } if (it == output_stack_.rend()) { ec = jsonpath_errc::unbalanced_parentheses; return; } std::reverse(expressions.begin(), expressions.end()); ++it; output_stack_.erase(it.base(),output_stack_.end()); if (!output_stack_.empty() && output_stack_.back().is_path()) { output_stack_.back().selector_->append_selector(resources.new_selector(union_selector(std::move(expressions)))); } else { output_stack_.emplace_back(token_type(resources.new_selector(union_selector(std::move(expressions))))); } break; } case jsonpath_token_kind::lparen: operator_stack_.emplace_back(std::move(tok)); break; case jsonpath_token_kind::rparen: { unwind_rparen(ec); break; } case jsonpath_token_kind::end_function: { //std::cout << "jsonpath_token_kind::end_function\n"; unwind_rparen(ec); if (JSONCONS_UNLIKELY(ec)) { return; } std::vector toks; auto it = output_stack_.rbegin(); std::size_t arg_count = 0; while (it != output_stack_.rend() && (*it).token_kind() != jsonpath_token_kind::function) { if ((*it).token_kind() == jsonpath_token_kind::argument) { ++arg_count; } toks.emplace_back(std::move(*it)); ++it; } if (it == output_stack_.rend()) { ec = jsonpath_errc::unbalanced_parentheses; return; } std::reverse(toks.begin(), toks.end()); if ((*it).arity() && arg_count != *((*it).arity())) { ec = jsonpath_errc::invalid_arity; return; } toks.push_back(std::move(*it)); ++it; output_stack_.erase(it.base(),output_stack_.end()); if (!output_stack_.empty() && output_stack_.back().is_path()) { output_stack_.back().selector_->append_selector(resources.new_selector(function_selector(token_evaluator_type(std::move(toks))))); } else { output_stack_.emplace_back(token_type(resources.new_selector(function_selector(std::move(toks))))); } break; } case jsonpath_token_kind::literal: if (!output_stack_.empty() && (output_stack_.back().token_kind() == jsonpath_token_kind::current_node || output_stack_.back().token_kind() == jsonpath_token_kind::root_node)) { output_stack_.back() = std::move(tok); } else { output_stack_.emplace_back(std::move(tok)); } break; case jsonpath_token_kind::function: output_stack_.emplace_back(std::move(tok)); operator_stack_.emplace_back(token_type(lparen_arg)); break; case jsonpath_token_kind::argument: output_stack_.emplace_back(std::move(tok)); break; case jsonpath_token_kind::root_node: case jsonpath_token_kind::current_node: output_stack_.emplace_back(std::move(tok)); break; case jsonpath_token_kind::unary_operator: case jsonpath_token_kind::binary_operator: { if (operator_stack_.empty() || operator_stack_.back().is_lparen()) { operator_stack_.emplace_back(std::move(tok)); } else if (tok.precedence_level() < operator_stack_.back().precedence_level() || (tok.precedence_level() == operator_stack_.back().precedence_level() && tok.is_right_associative())) { operator_stack_.emplace_back(std::move(tok)); } else { auto it = operator_stack_.rbegin(); while (it != operator_stack_.rend() && (*it).is_operator() && (tok.precedence_level() > (*it).precedence_level() || (tok.precedence_level() == (*it).precedence_level() && tok.is_right_associative()))) { output_stack_.emplace_back(std::move(*it)); ++it; } operator_stack_.erase(it.base(),operator_stack_.end()); operator_stack_.emplace_back(std::move(tok)); } break; } default: break; } //std::cout << " " << "Output Stack\n"; //for (auto&& t : output_stack_) //{ // std::cout << t.to_string(2) << "\n"; //} //if (!operator_stack_.empty()) //{ // std::cout << " " << "Operator Stack\n"; // for (auto&& t : operator_stack_) // { // std::cout << t.to_string(2) << "\n"; // } //} } uint32_t append_to_codepoint(uint32_t cp, int c, std::error_code& ec) { cp *= 16; if (c >= '0' && c <= '9') { cp += c - '0'; } else if (c >= 'a' && c <= 'f') { cp += c - 'a' + 10; } else if (c >= 'A' && c <= 'F') { cp += c - 'A' + 10; } else { ec = jsonpath_errc::invalid_codepoint; } return cp; } }; } // namespace detail } // namespace jsonpath } // namespace jsoncons #endif // JSONCONS_EXT_JSONPATH_JSONPATH_PARSER_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonpath/jsonpath_selector.hpp000066400000000000000000001370401477700171100256070ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONPATH_JSONPATH_SELECTOR_HPP #define JSONCONS_EXT_JSONPATH_JSONPATH_SELECTOR_HPP #include #include #include #include #include #include // std::move #include #include #include #include #include namespace jsoncons { namespace jsonpath { namespace detail { struct slice { jsoncons::optional start_; jsoncons::optional stop_; int64_t step_; slice() : step_(1) { } slice(const jsoncons::optional& start, const jsoncons::optional& end, int64_t step) : start_(start), stop_(end), step_(step) { } slice(const slice& other) = default; slice(slice&& other) = default; slice& operator=(const slice& other) = default; slice& operator=(slice&& other) = default; ~slice() = default; int64_t get_start(std::size_t size) const { if (start_) { auto len = *start_ >= 0 ? *start_ : (static_cast(size) + *start_); return len <= static_cast(size) ? len : static_cast(size); } if (step_ >= 0) { return 0; } return static_cast(size); } int64_t get_stop(std::size_t size) const { if (stop_) { auto len = *stop_ >= 0 ? *stop_ : (static_cast(size) + *stop_); return len <= static_cast(size) ? len : static_cast(size); } return step_ >= 0 ? static_cast(size) : -1; } int64_t step() const { return step_; // Allow negative } }; template class json_array_receiver : public node_receiver { public: using reference = JsonReference; using char_type = typename Json::char_type; using string_type = typename Json::string_type; using path_node_type = basic_path_node; Json* val; json_array_receiver(Json* ptr) : val(ptr) { } void add(const path_node_type&, reference value) override { val->emplace_back(value); } }; template struct path_generator { using char_type = typename Json::char_type; using string_view_type = typename Json::string_view_type; using string_type = typename Json::string_type; using path_node_type = basic_path_node; static const path_node_type& generate(eval_context& context, const path_node_type& last, std::size_t index, result_options options) { const result_options require_path = result_options::path | result_options::nodups | result_options::sort; if ((options & require_path) != result_options()) { return *context.create_path_node(&last, index); } return last; } static const path_node_type& generate(eval_context& context, const path_node_type& last, const string_view_type& identifier, result_options options) { const result_options require_path = result_options::path | result_options::nodups | result_options::sort; if ((options & require_path) != result_options()) { return *context.create_path_node(&last, identifier); } return last; } }; template class base_selector : public jsonpath_selector { using supertype = jsonpath_selector; supertype* tail_{nullptr}; public: using char_type = typename Json::char_type; using string_type = typename Json::string_type; using value_type = typename supertype::value_type; using reference = typename supertype::reference; using pointer = typename supertype::pointer; using path_value_pair_type = typename supertype::path_value_pair_type; using path_node_type = typename supertype::path_node_type; using node_receiver_type = typename supertype::node_receiver_type; using selector_type = typename supertype::selector_type; base_selector() : supertype(true, 11) { } base_selector(bool is_path, std::size_t precedence_level) : supertype(is_path, precedence_level) { } void append_selector(selector_type* expr) override { if (!tail_) { tail_ = expr; } else { tail_->append_selector(expr); } } void tail_select(eval_context& context, reference root, const path_node_type& last, reference current, node_receiver_type& receiver, result_options options) const { if (!tail_) { receiver.add(last, current); } else { tail_->select(context, root, last, current, receiver, options); } } reference evaluate_tail(eval_context& context, reference root, const path_node_type& last, reference current, result_options options, std::error_code& ec) const { if (!tail_) { return current; } return tail_->evaluate(context, root, last, current, options, ec); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } if (tail_) { s.append(tail_->to_string(level)); } return s; } }; template class identifier_selector final : public base_selector { using supertype = base_selector; using path_generator_type = path_generator; public: using char_type = typename Json::char_type; using string_type = typename Json::string_type; using string_view_type = typename Json::string_view_type; using value_type = typename supertype::value_type; using reference = typename supertype::reference; using pointer = typename supertype::pointer; using path_value_pair_type = typename supertype::path_value_pair_type; using path_node_type = typename supertype::path_node_type; using node_receiver_type = typename supertype::node_receiver_type; private: string_type identifier_; public: identifier_selector(const string_type& identifier) : base_selector(), identifier_(identifier) { } void select(eval_context& context, reference root, const path_node_type& last, reference current, node_receiver_type& receiver, result_options options) const override { if (current.is_object()) { auto it = current.find(identifier_); if (it != current.object_range().end()) { this->tail_select(context, root, path_generator_type::generate(context, last, identifier_, options), (*it).value(), receiver, options); } } else if (current.is_array()) { int64_t n{0}; auto r = jsoncons::detail::decimal_to_integer(identifier_.data(), identifier_.size(), n); if (r) { auto index = (n >= 0) ? static_cast(n) : static_cast(static_cast(current.size()) + n); if (index < current.size()) { this->tail_select(context, root, path_generator_type::generate(context, last, index, options), current[index], receiver, options); } } else if (identifier_ == context.length_label() && current.size() >= 0) { pointer ptr = context.create_json(current.size(), semantic_tag::none, context.get_allocator()); this->tail_select(context, root, path_generator_type::generate(context, last, identifier_, options), *ptr, receiver, options); } } else if (current.is_string() && identifier_ == context.length_label()) { string_view_type sv = current.as_string_view(); std::size_t count = unicode_traits::count_codepoints(sv.data(), sv.size()); pointer ptr = context.create_json(count, semantic_tag::none, context.get_allocator()); this->tail_select(context, root, path_generator_type::generate(context, last, identifier_, options), *ptr, receiver, options); } //std::cout << "end identifier_selector\n"; } reference evaluate(eval_context& context, reference root, const path_node_type& last, reference current, result_options options, std::error_code& ec) const override { if (current.is_object()) { auto it = current.find(identifier_); if (it != current.object_range().end()) { return this->evaluate_tail(context, root, path_generator_type::generate(context, last, identifier_, options), (*it).value(), options, ec); } return context.null_value(); } if (current.is_array()) { int64_t n{0}; auto r = jsoncons::detail::decimal_to_integer(identifier_.data(), identifier_.size(), n); if (r) { auto index = (n >= 0) ? static_cast(n) : static_cast(static_cast(current.size()) + n); if (index < current.size()) { return this->evaluate_tail(context, root, path_generator_type::generate(context, last, index, options), current[index], options, ec); } return context.null_value(); } if (identifier_ == context.length_label() && current.size() > 0) { pointer ptr = context.create_json(current.size(), semantic_tag::none, context.get_allocator()); return this->evaluate_tail(context, root, path_generator_type::generate(context, last, identifier_, options), *ptr, options, ec); } return context.null_value(); } if (current.is_string() && identifier_ == context.length_label()) { string_view_type sv = current.as_string_view(); std::size_t count = unicode_traits::count_codepoints(sv.data(), sv.size()); pointer ptr = context.create_json(count, semantic_tag::none, context.get_allocator()); return this->evaluate_tail(context, root, path_generator_type::generate(context, last, identifier_, options), *ptr, options, ec); } return context.null_value(); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("identifier selector "); unicode_traits::convert(identifier_.data(),identifier_.size(),s); s.append(base_selector::to_string(level+1)); //s.append("\n"); return s; } }; template class root_selector final : public base_selector { using supertype = base_selector; using path_generator_type = path_generator; std::size_t id_; public: using value_type = typename supertype::value_type; using reference = typename supertype::reference; using pointer = typename supertype::pointer; using path_value_pair_type = typename supertype::path_value_pair_type; using path_node_type = typename supertype::path_node_type; using node_receiver_type = typename supertype::node_receiver_type; root_selector(std::size_t id) : base_selector(), id_(id) { } root_selector(const root_selector&) = default; root_selector(root_selector&&) = default; root_selector& operator=(const root_selector&) = default; root_selector& operator=(root_selector&&) = default; ~root_selector() = default; void select(eval_context& context, reference root, const path_node_type& last, reference, node_receiver_type& receiver, result_options options) const override { this->tail_select(context, root, last, root, receiver, options); } reference evaluate(eval_context& context, reference root, const path_node_type& last, reference, result_options options, std::error_code& ec) const override { if (context.is_cached(id_)) { return context.get_from_cache(id_); } auto& ref = this->evaluate_tail(context, root, last, root, options, ec); if (!ec) { context.add_to_cache(id_, ref); } return ref; } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("root_selector "); s.append(base_selector::to_string(level+1)); return s; } }; template class current_node_selector final : public base_selector { using supertype = base_selector; public: using value_type = typename supertype::value_type; using reference = typename supertype::reference; using pointer = typename supertype::pointer; using path_value_pair_type = typename supertype::path_value_pair_type; using path_node_type = typename supertype::path_node_type; using path_generator_type = path_generator; using node_receiver_type = typename supertype::node_receiver_type; current_node_selector() = default; current_node_selector(const current_node_selector&) = default; current_node_selector(current_node_selector&&) = default; ~current_node_selector() = default; current_node_selector& operator=(const current_node_selector&) = default; current_node_selector& operator=(current_node_selector&&) = default; void select(eval_context& context, reference root, const path_node_type& last, reference current, node_receiver_type& receiver, result_options options) const override { this->tail_select(context, root, last, current, receiver, options); } reference evaluate(eval_context& context, reference root, const path_node_type& last, reference current, result_options options, std::error_code& ec) const override { //std::cout << "current_node_selector: " << current << "\n"; return this->evaluate_tail(context, root, last, current, options, ec); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("current_node_selector"); s.append(base_selector::to_string(level+1)); return s; } }; template class parent_node_selector final : public base_selector { using supertype = base_selector; using allocator_type = typename Json::allocator_type; int ancestor_depth_; public: using char_type = typename Json::char_type; using value_type = typename supertype::value_type; using reference = typename supertype::reference; using pointer = typename supertype::pointer; using path_value_pair_type = typename supertype::path_value_pair_type; using path_node_type = typename supertype::path_node_type; using path_generator_type = path_generator; using node_receiver_type = typename supertype::node_receiver_type; parent_node_selector(int ancestor_depth) : ancestor_depth_(ancestor_depth) { } parent_node_selector(const parent_node_selector&) = default; parent_node_selector(parent_node_selector&&) = default; ~parent_node_selector() = default; parent_node_selector& operator=(const parent_node_selector&) = default; parent_node_selector& operator=(parent_node_selector&&) = default; void select(eval_context& context, reference root, const path_node_type& last, reference, node_receiver_type& receiver, result_options options) const override { const path_node_type* ancestor = std::addressof(last); int index = 0; while (ancestor != nullptr && index < ancestor_depth_) { ancestor = ancestor->parent(); ++index; } if (ancestor != nullptr) { pointer ptr = jsoncons::jsonpath::select(root,*ancestor); if (ptr != nullptr) { this->tail_select(context, root, *ancestor, *ptr, receiver, options); } } } reference evaluate(eval_context& context, reference root, const path_node_type& last, reference, result_options options, std::error_code& ec) const override { const path_node_type* ancestor = std::addressof(last); int index = 0; while (ancestor != nullptr && index < ancestor_depth_) { ancestor = ancestor->parent(); ++index; } if (ancestor != nullptr) { pointer ptr = jsoncons::jsonpath::select(root, *ancestor); if (ptr != nullptr) { return this->evaluate_tail(context, root, *ancestor, *ptr, options, ec); } return context.null_value(); } return context.null_value(); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("parent_node_selector"); s.append(base_selector::to_string(level+1)); return s; } }; template class index_selector final : public base_selector { using supertype = base_selector; int64_t index_; public: using value_type = typename supertype::value_type; using reference = typename supertype::reference; using pointer = typename supertype::pointer; using path_value_pair_type = typename supertype::path_value_pair_type; using path_node_type = typename supertype::path_node_type; using path_generator_type = path_generator; using node_receiver_type = typename supertype::node_receiver_type; index_selector(int64_t index) : base_selector(), index_(index) { } void select(eval_context& context, reference root, const path_node_type& last, reference current, node_receiver_type& receiver, result_options options) const override { if (current.is_array()) { auto slen = static_cast(current.size()); if (index_ >= 0 && index_ < slen) { auto i = static_cast(index_); this->tail_select(context, root, path_generator_type::generate(context, last, i, options), current.at(i), receiver, options); } else { int64_t index = slen + index_; if (index >= 0 && index < slen) { auto i = static_cast(index); this->tail_select(context, root, path_generator_type::generate(context, last, i, options), current.at(i), receiver, options); } } } } reference evaluate(eval_context& context, reference root, const path_node_type& last, reference current, result_options options, std::error_code& ec) const override { if (current.is_array()) { auto slen = static_cast(current.size()); if (index_ >= 0 && index_ < slen) { auto i = static_cast(index_); return this->evaluate_tail(context, root, path_generator_type::generate(context, last, i, options), current.at(i), options, ec); } int64_t index = slen + index_; if (index >= 0 && index < slen) { auto i = static_cast(index); return this->evaluate_tail(context, root, path_generator_type::generate(context, last, i, options), current.at(i), options, ec); } return context.null_value(); } return context.null_value(); } }; template class wildcard_selector final : public base_selector { using supertype = base_selector; public: using value_type = typename supertype::value_type; using reference = typename supertype::reference; using pointer = typename supertype::pointer; using path_value_pair_type = typename supertype::path_value_pair_type; using path_node_type = typename supertype::path_node_type; using path_generator_type = path_generator; using node_receiver_type = typename supertype::node_receiver_type; wildcard_selector() : base_selector() { } void select(eval_context& context, reference root, const path_node_type& last, reference current, node_receiver_type& receiver, result_options options) const override { if (current.is_array()) { for (std::size_t i = 0; i < current.size(); ++i) { this->tail_select(context, root, path_generator_type::generate(context, last, i, options), current[i], receiver, options); } } else if (current.is_object()) { for (auto& member : current.object_range()) { this->tail_select(context, root, path_generator_type::generate(context, last, member.key(), options), member.value(), receiver, options); } } //std::cout << "end wildcard_selector\n"; } reference evaluate(eval_context& context, reference root, const path_node_type& last, reference current, result_options options, std::error_code&) const override { auto jptr = context.create_json(json_array_arg, semantic_tag::none, context.get_allocator()); json_array_receiver receiver(jptr); select(context, root, last, current, receiver, options); return *jptr; } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("wildcard selector"); s.append(base_selector::to_string(level)); return s; } }; template class recursive_selector final : public base_selector { using supertype = base_selector; public: using value_type = typename supertype::value_type; using reference = typename supertype::reference; using pointer = typename supertype::pointer; using path_value_pair_type = typename supertype::path_value_pair_type; using path_node_type = typename supertype::path_node_type; using path_generator_type = path_generator; using node_receiver_type = typename supertype::node_receiver_type; recursive_selector() : base_selector() { } void select(eval_context& context, reference root, const path_node_type& last, reference current, node_receiver_type& receiver, result_options options) const override { if (current.is_array()) { this->tail_select(context, root, last, current, receiver, options); for (std::size_t i = 0; i < current.size(); ++i) { select(context, root, path_generator_type::generate(context, last, i, options), current[i], receiver, options); } } else if (current.is_object()) { this->tail_select(context, root, last, current, receiver, options); for (auto& item : current.object_range()) { select(context, root, path_generator_type::generate(context, last, item.key(), options), item.value(), receiver, options); } } //std::cout << "end wildcard_selector\n"; } reference evaluate(eval_context& context, reference root, const path_node_type& last, reference current, result_options options, std::error_code&) const override { auto jptr = context.create_json(json_array_arg, semantic_tag::none, context.get_allocator()); json_array_receiver receiver(jptr); select(context, root, last, current, receiver, options); if (jptr->empty()) { return context.null_value(); } return jptr->size() == 1 ? (*jptr)[0] : *jptr; } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("wildcard selector"); s.append(base_selector::to_string(level)); return s; } }; template class union_selector final : public jsonpath_selector { using supertype = jsonpath_selector; public: using char_type = typename Json::char_type; using value_type = typename supertype::value_type; using reference = typename supertype::reference; using pointer = typename supertype::pointer; using path_value_pair_type = typename supertype::path_value_pair_type; using path_node_type = typename supertype::path_node_type; using path_expression_type = path_expression; using path_generator_type = path_generator; using node_receiver_type = typename supertype::node_receiver_type; using selector_type = typename supertype::selector_type; private: std::vector selectors_; selector_type* tail_{nullptr}; public: union_selector(std::vector&& selectors) : supertype(true, 11), selectors_(std::move(selectors)) { } void append_selector(selector_type* tail) override { if (tail_ == nullptr) { tail_ = tail; for (auto& selector : selectors_) { selector->append_selector(tail); } } else { tail_->append_selector(tail); } } void select(eval_context& context, reference root, const path_node_type& last, reference current, node_receiver_type& receiver, result_options options) const override { for (auto& selector : selectors_) { selector->select(context, root, last, current, receiver, options); } } reference evaluate(eval_context& context, reference root, const path_node_type& last, reference current, result_options options, std::error_code&) const override { auto jptr = context.create_json(json_array_arg, semantic_tag::none, context.get_allocator()); json_array_receiver receiver(jptr); select(context,root,last,current,receiver,options); return *jptr; } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("union selector "); for (auto& selector : selectors_) { s.append(selector->to_string(level+1)); //s.push_back('\n'); } return s; } }; template class filter_selector final : public base_selector { using supertype = base_selector; token_evaluator expr_; public: using value_type = typename supertype::value_type; using reference = typename supertype::reference; using pointer = typename supertype::pointer; using path_value_pair_type = typename supertype::path_value_pair_type; using path_node_type = typename supertype::path_node_type; using path_generator_type = path_generator; using node_receiver_type = typename supertype::node_receiver_type; filter_selector(token_evaluator&& expr) : base_selector(), expr_(std::move(expr)) { } void select(eval_context& context, reference root, const path_node_type& last, reference current, node_receiver_type& receiver, result_options options) const override { if (current.is_array()) { for (std::size_t i = 0; i < current.size(); ++i) { std::error_code ec; value_type r = expr_.evaluate(context, root, current[i], options, ec); bool t = ec ? false : detail::is_true(r); if (t) { this->tail_select(context, root, path_generator_type::generate(context, last, i, options), current[i], receiver, options); } } } else if (current.is_object()) { for (auto& member : current.object_range()) { std::error_code ec; value_type r = expr_.evaluate(context, root, member.value(), options, ec); bool t = ec ? false : detail::is_true(r); if (t) { this->tail_select(context, root, path_generator_type::generate(context, last, member.key(), options), member.value(), receiver, options); } } } } reference evaluate(eval_context& context, reference root, const path_node_type& last, reference current, result_options options, std::error_code&) const override { auto jptr = context.create_json(json_array_arg, semantic_tag::none, context.get_allocator()); json_array_receiver receiver(jptr); select(context, root, last, current, receiver, options); return *jptr; } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("filter selector "); s.append(expr_.to_string(level+1)); return s; } }; template class index_expression_selector final : public base_selector { using supertype = base_selector; using allocator_type = typename Json::allocator_type; using string_type = typename Json::string_type; token_evaluator expr_; public: using value_type = typename supertype::value_type; using reference = typename supertype::reference; using pointer = typename supertype::pointer; using path_value_pair_type = typename supertype::path_value_pair_type; using path_node_type = typename supertype::path_node_type; using path_generator_type = path_generator; using node_receiver_type = typename supertype::node_receiver_type; index_expression_selector(token_evaluator&& expr) : base_selector(), expr_(std::move(expr)) { } void select(eval_context& context, reference root, const path_node_type& last, reference current, node_receiver_type& receiver, result_options options) const override { std::error_code ec; value_type j = expr_.evaluate(context, root, current, options, ec); if (!ec) { if (j.template is() && current.is_array()) { std::size_t start = j.template as(); this->tail_select(context, root, path_generator_type::generate(context, last, start, options), current.at(start), receiver, options); } else if (j.is_string() && current.is_object()) { auto sv = j.as_string_view(); this->tail_select(context, root, path_generator_type::generate(context, last, sv, options), current.at(j.as_string_view()), receiver, options); } } } reference evaluate(eval_context& context, reference root, const path_node_type& last, reference current, result_options options, std::error_code& ec) const override { //std::cout << "index_expression_selector current: " << current << "\n"; value_type j = expr_.evaluate(context, root, current, options, ec); if (!ec) { if (j.template is() && current.is_array()) { std::size_t start = j.template as(); return this->evaluate_tail(context, root, last, current.at(start), options, ec); } if (j.is_string() && current.is_object()) { return this->evaluate_tail(context, root, last, current.at(j.as_string_view()), options, ec); } return context.null_value(); } return context.null_value(); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("bracket expression selector "); s.append(expr_.to_string(level+1)); s.append(base_selector::to_string(level+1)); return s; } }; template class slice_selector final : public base_selector { using supertype = base_selector; using path_generator_type = path_generator; slice slice_; public: using value_type = typename supertype::value_type; using reference = typename supertype::reference; using pointer = typename supertype::pointer; using path_value_pair_type = typename supertype::path_value_pair_type; using path_node_type = typename supertype::path_node_type; using node_receiver_type = typename supertype::node_receiver_type; slice_selector(const slice& slic) : base_selector(), slice_(slic) { } void select(eval_context& context, reference root, const path_node_type& last, reference current, node_receiver_type& receiver, result_options options) const override { if (current.is_array()) { auto start = slice_.get_start(current.size()); auto end = slice_.get_stop(current.size()); auto step = slice_.step(); if (step > 0) { if (start < 0) { start = 0; } if (end > static_cast(current.size())) { end = current.size(); } for (int64_t i = start; i < end; i += step) { auto j = static_cast(i); this->tail_select(context, root, path_generator_type::generate(context, last, j, options), current[j], receiver, options); } } else if (step < 0) { if (start >= static_cast(current.size())) { start = static_cast(current.size()) - 1; } if (end < -1) { end = -1; } for (int64_t i = start; i > end; i += step) { auto j = static_cast(i); if (j < current.size()) { this->tail_select(context, root, path_generator_type::generate(context, last,j,options), current[j], receiver, options); } } } } } reference evaluate(eval_context& context, reference root, const path_node_type& last, reference current, result_options options, std::error_code&) const override { auto jptr = context.create_json(json_array_arg, semantic_tag::none, context.get_allocator()); json_array_receiver accum(jptr); select(context, root, last, current, accum, options); return *jptr; } }; template class function_selector final : public base_selector { using supertype = base_selector; token_evaluator expr_; public: using value_type = typename supertype::value_type; using reference = typename supertype::reference; using pointer = typename supertype::pointer; using path_value_pair_type = typename supertype::path_value_pair_type; using path_node_type = typename supertype::path_node_type; using path_generator_type = path_generator; using node_receiver_type = typename supertype::node_receiver_type; function_selector(token_evaluator&& expr) : base_selector(), expr_(std::move(expr)) { } void select(eval_context& context, reference root, const path_node_type& last, reference current, node_receiver_type& receiver, result_options options) const override { std::error_code ec; value_type ref = expr_.evaluate(context, root, current, options, ec); if (!ec) { this->tail_select(context, root, last, *context.create_json(std::move(ref)), receiver, options); } } reference evaluate(eval_context& context, reference root, const path_node_type& last, reference current, result_options options, std::error_code& ec) const override { value_type ref = expr_.evaluate(context, root, current, options, ec); if (!ec) { return this->evaluate_tail(context, root, last, *context.create_json(std::move(ref)), options, ec); } return context.null_value(); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("function_selector "); s.append(expr_.to_string(level+1)); return s; } }; } // namespace detail } // namespace jsonpath } // namespace jsoncons #endif // JSONCONS_EXT_JSONPATH_JSONPATH_SELECTOR_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonpath/jsonpath_utilities.hpp000066400000000000000000000043061477700171100260000ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONPATH_JSONPATH_UTILITIES_HPP #define JSONCONS_EXT_JSONPATH_JSONPATH_UTILITIES_HPP #include namespace jsoncons { namespace jsonpath { template std::size_t escape_string(const CharT* s, std::size_t length, Sink& sink) { std::size_t count = 0; const CharT* begin = s; const CharT* end = s + length; for (const CharT* it = begin; it != end; ++it) { CharT c = *it; switch (c) { case '\\': sink.push_back('\\'); sink.push_back('\\'); count += 2; break; case '\'': sink.push_back('\\'); sink.push_back('\''); count += 2; break; case '\b': sink.push_back('\\'); sink.push_back('b'); count += 2; break; case '\f': sink.push_back('\\'); sink.push_back('f'); count += 2; break; case '\n': sink.push_back('\\'); sink.push_back('n'); count += 2; break; case '\r': sink.push_back('\\'); sink.push_back('r'); count += 2; break; case '\t': sink.push_back('\\'); sink.push_back('t'); count += 2; break; default: sink.push_back(c); ++count; break; } } return count; } } // namespace jsonpath } // namespace jsoncons #endif // JSONCONS_EXT_JSONPATH_JSONPATH_UTILITIES_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonpath/path_node.hpp000066400000000000000000000237171477700171100240270ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONPATH_PATH_NODE_HPP #define JSONCONS_EXT_JSONPATH_PATH_NODE_HPP #include // std::reverse #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace jsonpath { enum class path_node_kind { root, name, index }; template class basic_path_node { public: using string_view_type = jsoncons::basic_string_view; using char_type = CharT; private: const basic_path_node* parent_{nullptr}; std::size_t size_{1}; path_node_kind node_kind_; string_view_type name_; std::size_t index_{0}; public: basic_path_node() noexcept : node_kind_(path_node_kind::root) { } basic_path_node(const basic_path_node* parent, string_view_type name) : parent_(parent), size_(parent == nullptr ? 1 : parent->size()+1), node_kind_(path_node_kind::name), name_(name) { } basic_path_node(const basic_path_node* parent, std::size_t index) : parent_(parent), size_(parent == nullptr ? 1 : parent->size()+1), node_kind_(path_node_kind::index), index_(index) { } basic_path_node(const basic_path_node& other) = default; basic_path_node(basic_path_node&& other) = default; ~basic_path_node() = default; basic_path_node& operator=(const basic_path_node& other) = default; basic_path_node& operator=(basic_path_node&& other) = default; const basic_path_node* parent() const { return parent_;} path_node_kind node_kind() const { return node_kind_; } string_view_type name() const { return name_; } std::size_t size() const { return size_; } std::size_t index() const { return index_; } void swap(basic_path_node& node) noexcept { std::swap(parent_, node.parent_); std::swap(node_kind_, node.node_kind_); std::swap(name_, node.name_); std::swap(index_, node.index_); } private: std::size_t node_hash() const { std::size_t h = node_kind_ == path_node_kind::index ? std::hash{}(index_) : std::hash{}(name_); return h; } int compare_node(const basic_path_node& other) const { int diff = 0; if (node_kind_ != other.node_kind_) { diff = static_cast(node_kind_) - static_cast(other.node_kind_); } else { switch (node_kind_) { case path_node_kind::root: case path_node_kind::name: diff = name_.compare(other.name_); break; case path_node_kind::index: diff = index_ < other.index_ ? -1 : index_ > other.index_ ? 1 : 0; break; default: break; } } return diff; } friend bool operator<(const basic_path_node& lhs, const basic_path_node& rhs) { std::size_t len = (std::min)(lhs.size(),rhs.size()); const basic_path_node* p_lhs = std::addressof(lhs); const basic_path_node* p_rhs = std::addressof(rhs); bool is_less = false; while (p_lhs->size() > len) { p_lhs = p_lhs->parent_; is_less = false; } while (p_rhs->size() > len) { p_rhs = p_rhs->parent_; is_less = true; } while (p_lhs != nullptr) { int diff = 0; if (p_lhs->node_kind_ != p_rhs->node_kind_) { diff = static_cast(p_lhs->node_kind_) - static_cast(p_rhs->node_kind_); } else { switch (p_lhs->node_kind_) { case path_node_kind::root: case path_node_kind::name: diff = p_lhs->name_.compare(p_rhs->name_); break; case path_node_kind::index: diff = static_cast(p_lhs->index_) - static_cast(p_rhs->index_); break; default: break; } } if (diff < 0) { is_less = true; } else if (diff > 0) { is_less = false; } p_lhs = p_lhs->parent_; p_rhs = p_rhs->parent_; } return is_less; } friend bool operator==(const basic_path_node& lhs, const basic_path_node& rhs) { if (lhs.size() != rhs.size()) { return false; } const basic_path_node* p_lhs = std::addressof(lhs); const basic_path_node* p_rhs = std::addressof(rhs); bool is_equal = true; while (p_lhs != nullptr && is_equal) { if (p_lhs->node_kind_ != p_rhs->node_kind_) { is_equal = false; } else { switch (p_lhs->node_kind_) { case path_node_kind::root: case path_node_kind::name: is_equal = p_lhs->name_ == p_rhs->name_; break; case path_node_kind::index: is_equal = p_lhs->index_ == p_rhs->index_; break; default: break; } } p_lhs = p_lhs->parent_; p_rhs = p_rhs->parent_; } return is_equal; } }; template Json* select(Json& root, const basic_path_node& path) { using path_node_type = basic_path_node; std::vector nodes(path.size(), nullptr); std::size_t len = nodes.size(); const path_node_type* p = std::addressof(path); while (p != nullptr) { nodes[--len] = p; p = p->parent(); } Json* current = std::addressof(root); for (auto node : nodes) { if (node->node_kind() == path_node_kind::index) { if (current->type() != json_type::array_value || node->index() >= current->size()) { return nullptr; } current = std::addressof(current->at(node->index())); } else if (node->node_kind() == path_node_kind::name) { if (current->type() != json_type::object_value) { return nullptr; } auto it = current->find(node->name()); if (it == current->object_range().end()) { return nullptr; } current = std::addressof((*it).value()); } } return current; } template > std::basic_string,Allocator> to_basic_string(const basic_path_node& path, const Allocator& alloc=Allocator()) { std::basic_string,Allocator> buffer(alloc); using path_node_type = basic_path_node; std::vector nodes(path.size(), nullptr); std::size_t len = nodes.size(); const path_node_type* p = std::addressof(path); while (p != nullptr) { nodes[--len] = p; p = p->parent(); } for (auto node : nodes) { switch (node->node_kind()) { case path_node_kind::root: buffer.push_back('$'); break; case path_node_kind::name: buffer.push_back('['); buffer.push_back('\''); jsoncons::jsonpath::escape_string(node->name().data(), node->name().size(), buffer); buffer.push_back('\''); buffer.push_back(']'); break; case path_node_kind::index: buffer.push_back('['); jsoncons::detail::from_integer(node->index(), buffer); buffer.push_back(']'); break; } } return buffer; } using path_node = basic_path_node; using wpath_node = basic_path_node; inline std::string to_string(const path_node& path) { return to_basic_string(path); } inline std::wstring to_wstring(const wpath_node& path) { return to_basic_string(path); } } // namespace jsonpath } // namespace jsoncons #endif // JSONCONS_EXT_JSONPATH_PATH_NODE_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonpath/token_evaluator.hpp000066400000000000000000003361121477700171100252640ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONPATH_TOKEN_EVALUATOR_HPP #define JSONCONS_EXT_JSONPATH_TOKEN_EVALUATOR_HPP #include #include #include #include #include #include // std::basic_string #include #include #include // std::unordered_map #include // std::move #include // std::vector #include #include #include #include #include #include #include #include #if defined(JSONCONS_HAS_STD_REGEX) #include #endif namespace jsoncons { namespace jsonpath { template struct jsonpath_traits { using allocator_type = typename Json::allocator_type; using char_type = typename Json::char_type; using string_type = typename Json::string_type; using string_view_type = typename Json::string_view_type; using value_type = typename std::remove_const::type; using pointer = value_type*; using const_pointer = const value_type*; using reference = value_type&; using const_reference = const value_type&; }; struct reference_arg_t { explicit reference_arg_t() = default; }; constexpr reference_arg_t reference_arg{}; struct const_reference_arg_t { explicit const_reference_arg_t() = default; }; constexpr const_reference_arg_t const_reference_arg{}; struct literal_arg_t { explicit literal_arg_t() = default; }; constexpr literal_arg_t literal_arg{}; struct end_of_expression_arg_t { explicit end_of_expression_arg_t() = default; }; constexpr end_of_expression_arg_t end_of_expression_arg{}; struct separator_arg_t { explicit separator_arg_t() = default; }; constexpr separator_arg_t separator_arg{}; struct lparen_arg_t { explicit lparen_arg_t() = default; }; constexpr lparen_arg_t lparen_arg{}; struct rparen_arg_t { explicit rparen_arg_t() = default; }; constexpr rparen_arg_t rparen_arg{}; struct begin_union_arg_t { explicit begin_union_arg_t() = default; }; constexpr begin_union_arg_t begin_union_arg{}; struct end_union_arg_t { explicit end_union_arg_t() = default; }; constexpr end_union_arg_t end_union_arg{}; struct begin_filter_arg_t { explicit begin_filter_arg_t() = default; }; constexpr begin_filter_arg_t begin_filter_arg{}; struct end_filter_arg_t { explicit end_filter_arg_t() = default; }; constexpr end_filter_arg_t end_filter_arg{}; struct begin_expression_arg_t { explicit begin_expression_arg_t() = default; }; constexpr begin_expression_arg_t begin_expression_arg{}; struct end_index_expression_arg_t { explicit end_index_expression_arg_t() = default; }; constexpr end_index_expression_arg_t end_index_expression_arg{}; struct end_argument_expression_arg_t { explicit end_argument_expression_arg_t() = default; }; constexpr end_argument_expression_arg_t end_argument_expression_arg{}; struct current_node_arg_t { explicit current_node_arg_t() = default; }; constexpr current_node_arg_t current_node_arg{}; struct root_node_arg_t { explicit root_node_arg_t() = default; }; constexpr root_node_arg_t root_node_arg{}; struct end_function_arg_t { explicit end_function_arg_t() = default; }; constexpr end_function_arg_t end_function_arg{}; struct argument_arg_t { explicit argument_arg_t() = default; }; constexpr argument_arg_t argument_arg{}; enum class result_options {value=0, nodups=1, sort=2, sort_descending=4, path=8}; inline result_options operator~(result_options a) { return static_cast(~static_cast(a)); } inline result_options operator&(result_options a, result_options b) { return static_cast(static_cast(a) & static_cast(b)); } inline result_options operator^(result_options a, result_options b) { return static_cast(static_cast(a) ^ static_cast(b)); } inline result_options operator|(result_options a, result_options b) { return static_cast(static_cast(a) | static_cast(b)); } inline result_options operator&=(result_options& a, result_options b) { a = a & b; return a; } inline result_options operator^=(result_options& a, result_options b) { a = a ^ b; return a; } inline result_options operator|=(result_options& a, result_options b) { a = a | b; return a; } template class parameter; template class value_or_pointer { public: friend class parameter; using value_type = Json; using reference = JsonReference; using pointer = typename std::conditional::type>::value,typename Json::const_pointer,typename Json::pointer>::type; private: bool is_value_; union { value_type val_; pointer ptr_; }; public: value_or_pointer(value_type&& val) : is_value_(true), val_(std::move(val)) { } value_or_pointer(pointer ptr) : is_value_(false), ptr_(std::move(ptr)) { } value_or_pointer(const value_or_pointer& other) = delete; value_or_pointer(value_or_pointer&& other) noexcept : is_value_(other.is_value_) { if (is_value_) { new(&val_)value_type(std::move(other.val_)); } else { ptr_ = other.ptr_; } } ~value_or_pointer() noexcept { if (is_value_) { val_.~value_type(); } } value_or_pointer& operator=(const value_or_pointer& other) noexcept = delete; value_or_pointer& operator=(value_or_pointer&& other) noexcept { if (is_value_) { val_.~value_type(); } is_value_ = other.is_value_; if (is_value_) { new(&val_)value_type(std::move(other.val_)); } else { ptr_ = other.ptr_; } return *this; } reference value() { return is_value_ ? val_ : *ptr_; } pointer ptr() { return is_value_ ? &val_ : ptr_; } }; template class parameter { using value_type = Json; using reference = const Json&; using pointer = const Json*; private: value_or_pointer data_{nullptr}; public: template parameter(value_or_pointer&& data) noexcept { data_.is_value_ = data.is_value_; if (data.is_value_) { data_.val_ = std::move(data.val_); } else { data_.ptr_ = data.ptr_; } } parameter(const parameter& other) = default; parameter(parameter&& other) = default; ~parameter() = default; parameter& operator=(const parameter& other) = default; parameter& operator=(parameter&& other) = default; const Json& value() const { return data_.is_value_ ? data_.val_ : *data_.ptr_; } }; template class custom_function { public: using value_type = Json; using char_type = typename Json::char_type; using parameter_type = parameter; using function_type = std::function, std::error_code& ec)>; using string_type = typename Json::string_type; string_type function_name_; optional arity_; function_type f_; custom_function(const custom_function&) = default; custom_function(custom_function&&) = default; custom_function(const string_type& function_name, const optional& arity, const function_type& f) : function_name_(function_name), arity_(arity), f_(f) { } custom_function(string_type&& function_name, optional&& arity, function_type&& f) : function_name_(std::move(function_name)), arity_(arity), f_(std::move(f)) { } ~custom_function() = default; custom_function& operator=(const custom_function&) = default; custom_function& operator=(custom_function&&) = default; const string_type& name() const { return function_name_; } optional arity() const { return arity_; } const function_type& function() const { return f_; } }; template class custom_functions { using char_type = typename Json::char_type; using string_type = typename Json::string_type; using value_type = Json; using parameter_type = parameter; using function_type = std::function, std::error_code& ec)>; using const_iterator = typename std::vector>::const_iterator; std::vector> functions_; public: void register_function(const string_type& name, jsoncons::optional arity, const function_type& f) { functions_.emplace_back(name, arity, f); } const_iterator begin() const { return functions_.begin(); } const_iterator end() const { return functions_.end(); } }; namespace detail { template struct unary_operator { using const_reference = typename jsonpath_traits::const_reference; std::size_t precedence_level_; bool is_right_associative_; unary_operator(std::size_t precedence_level, bool is_right_associative) : precedence_level_(precedence_level), is_right_associative_(is_right_associative) { } unary_operator(const unary_operator& other) = default; unary_operator(unary_operator&& other) = default; virtual ~unary_operator() = default; unary_operator& operator=(const unary_operator& other) = default; unary_operator& operator=(unary_operator&& other) = default; std::size_t precedence_level() const { return precedence_level_; } bool is_right_associative() const { return is_right_associative_; } virtual Json evaluate(const_reference, std::error_code&) const = 0; }; template bool is_false(const Json& val) { return ((val.is_array() && val.empty()) || (val.is_object() && val.empty()) || (val.is_string() && val.as_string_view().empty()) || (val.is_bool() && !val.as_bool()) || val.is_null()); } template bool is_true(const Json& val) { return !is_false(val); } template class unary_not_operator final : public unary_operator { public: using const_reference = typename jsonpath_traits::const_reference; unary_not_operator() : unary_operator(1, true) {} Json evaluate(const_reference val, std::error_code&) const override { return is_false(val) ? Json(true, semantic_tag::none) : Json(false, semantic_tag::none); } }; template class unary_minus_operator final : public unary_operator { public: using const_reference = typename jsonpath_traits::const_reference; unary_minus_operator() : unary_operator(1, true) {} Json evaluate(const_reference val, std::error_code&) const override { if (val.is_int64()) { return Json(-val.template as(), semantic_tag::none); } if (val.is_double()) { return Json(-val.as_double(), semantic_tag::none); } return Json::null(); } }; template class regex_operator final : public unary_operator { using const_reference = typename jsonpath_traits::const_reference; using char_type = typename Json::char_type; using string_type = typename Json::string_type; std::basic_regex pattern_; public: regex_operator(std::basic_regex&& pattern) : unary_operator(2, true), pattern_(std::move(pattern)) { } Json evaluate(const_reference val, std::error_code&) const override { if (!val.is_string()) { return Json::null(); } return std::regex_search(val.as_string(), pattern_) ? Json(true, semantic_tag::none) : Json(false, semantic_tag::none); } }; template struct binary_operator { using const_reference = typename jsonpath_traits::const_reference; std::size_t precedence_level_; bool is_right_associative_; binary_operator(std::size_t precedence_level, bool is_right_associative = false) : precedence_level_(precedence_level), is_right_associative_(is_right_associative) { } virtual ~binary_operator() = default; std::size_t precedence_level() const { return precedence_level_; } bool is_right_associative() const { return is_right_associative_; } virtual Json evaluate(const_reference lhs, const_reference rhs, std::error_code&) const = 0; virtual std::string to_string(int) const { return "binary operator"; } }; // Implementations template class or_operator final : public binary_operator { using const_reference = typename jsonpath_traits::const_reference; public: or_operator() : binary_operator(9) { } Json evaluate(const_reference lhs, const_reference rhs, std::error_code&) const override { if (lhs.is_null() && rhs.is_null()) { return Json::null(); } if (!is_false(lhs)) { return lhs; } return rhs; } std::string to_string(int level) const override { std::string s; if (level > 0) { //s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("or operator"); return s; } }; template class and_operator final : public binary_operator { using const_reference = typename jsonpath_traits::const_reference; public: and_operator() : binary_operator(8) { } Json evaluate(const_reference lhs, const_reference rhs, std::error_code&) const override { if (is_true(lhs)) { return rhs; } return lhs; } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("and operator"); return s; } }; template class eq_operator final : public binary_operator { using const_reference = typename jsonpath_traits::const_reference; public: eq_operator() : binary_operator(6) { } Json evaluate(const_reference lhs, const_reference rhs, std::error_code&) const override { return lhs == rhs ? Json(true, semantic_tag::none) : Json(false, semantic_tag::none); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("equal operator"); return s; } }; template class ne_operator final : public binary_operator { using const_reference = typename jsonpath_traits::const_reference; public: ne_operator() : binary_operator(6) { } Json evaluate(const_reference lhs, const_reference rhs, std::error_code&) const override { return lhs != rhs ? Json(true, semantic_tag::none) : Json(false, semantic_tag::none); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("not equal operator"); return s; } }; template class lt_operator final : public binary_operator { using const_reference = typename jsonpath_traits::const_reference; public: lt_operator() : binary_operator(5) { } Json evaluate(const_reference lhs, const_reference rhs, std::error_code&) const override { if (lhs.is_number() && rhs.is_number()) { return lhs < rhs ? Json(true, semantic_tag::none) : Json(false, semantic_tag::none); } if (lhs.is_string() && rhs.is_string()) { return lhs < rhs ? Json(true, semantic_tag::none) : Json(false, semantic_tag::none); } return Json::null(); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("less than operator"); return s; } }; template class lte_operator final : public binary_operator { using const_reference = typename jsonpath_traits::const_reference; public: lte_operator() : binary_operator(5) { } Json evaluate(const_reference lhs, const_reference rhs, std::error_code&) const override { if (lhs.is_number() && rhs.is_number()) { return lhs <= rhs ? Json(true, semantic_tag::none) : Json(false, semantic_tag::none); } if (lhs.is_string() && rhs.is_string()) { return lhs <= rhs ? Json(true, semantic_tag::none) : Json(false, semantic_tag::none); } return Json::null(); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("less than or equal operator"); return s; } }; template class gt_operator final : public binary_operator { using const_reference = typename jsonpath_traits::const_reference; public: gt_operator() : binary_operator(5) { } Json evaluate(const_reference lhs, const_reference rhs, std::error_code&) const override { //std::cout << "operator> lhs: " << lhs << ", rhs: " << rhs << "\n"; if (lhs.is_number() && rhs.is_number()) { return lhs > rhs ? Json(true, semantic_tag::none) : Json(false, semantic_tag::none); } if (lhs.is_string() && rhs.is_string()) { return lhs > rhs ? Json(true, semantic_tag::none) : Json(false, semantic_tag::none); } return Json::null(); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("greater than operator"); return s; } }; template class gte_operator final : public binary_operator { using const_reference = typename jsonpath_traits::const_reference; public: gte_operator() : binary_operator(5) { } Json evaluate(const_reference lhs, const_reference rhs, std::error_code&) const override { if (lhs.is_number() && rhs.is_number()) { return lhs >= rhs ? Json(true, semantic_tag::none) : Json(false, semantic_tag::none); } if (lhs.is_string() && rhs.is_string()) { return lhs >= rhs ? Json(true, semantic_tag::none) : Json(false, semantic_tag::none); } return Json::null(); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("greater than or equal operator"); return s; } }; template class plus_operator final : public binary_operator { using const_reference = typename jsonpath_traits::const_reference; public: plus_operator() : binary_operator(4) { } Json evaluate(const_reference lhs, const_reference rhs, std::error_code&) const override { if (!(lhs.is_number() && rhs.is_number())) { return Json::null(); } if (lhs.is_int64() && rhs.is_int64()) { return Json(((lhs.template as() + rhs.template as())), semantic_tag::none); } if (lhs.is_uint64() && rhs.is_uint64()) { return Json((lhs.template as() + rhs.template as()), semantic_tag::none); } return Json((lhs.as_double() + rhs.as_double()), semantic_tag::none); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("plus operator"); return s; } }; template class minus_operator final : public binary_operator { using const_reference = typename jsonpath_traits::const_reference; public: minus_operator() : binary_operator(4) { } Json evaluate(const_reference lhs, const_reference rhs, std::error_code&) const override { if (!(lhs.is_number() && rhs.is_number())) { return Json::null(); } if (lhs.is_int64() && rhs.is_int64()) { return Json(((lhs.template as() - rhs.template as())), semantic_tag::none); } if (lhs.is_uint64() && rhs.is_uint64()) { return Json((lhs.template as() - rhs.template as()), semantic_tag::none); } return Json((lhs.as_double() - rhs.as_double()), semantic_tag::none); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("minus operator"); return s; } }; template class mult_operator final : public binary_operator { using const_reference = typename jsonpath_traits::const_reference; public: mult_operator() : binary_operator(3) { } Json evaluate(const_reference lhs, const_reference rhs, std::error_code&) const override { if (!(lhs.is_number() && rhs.is_number())) { return Json::null(); } if (lhs.is_int64() && rhs.is_int64()) { return Json(((lhs.template as() * rhs.template as())), semantic_tag::none); } if (lhs.is_uint64() && rhs.is_uint64()) { return Json((lhs.template as() * rhs.template as()), semantic_tag::none); } return Json((lhs.as_double() * rhs.as_double()), semantic_tag::none); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("multiply operator"); return s; } }; template class div_operator final : public binary_operator { using const_reference = typename jsonpath_traits::const_reference; public: div_operator() : binary_operator(3) { } Json evaluate(const_reference lhs, const_reference rhs, std::error_code&) const override { //std::cout << "operator/ lhs: " << lhs << ", rhs: " << rhs << "\n"; if (!(lhs.is_number() && rhs.is_number())) { return Json::null(); } if (lhs.is_int64() && rhs.is_int64()) { return Json(((lhs.template as() / rhs.template as())), semantic_tag::none); } if (lhs.is_uint64() && rhs.is_uint64()) { return Json((lhs.template as() / rhs.template as()), semantic_tag::none); } return Json((lhs.as_double() / rhs.as_double()), semantic_tag::none); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("divide operator"); return s; } }; template class modulus_operator final : public binary_operator { using const_reference = typename jsonpath_traits::const_reference; public: modulus_operator() : binary_operator(3) { } Json evaluate(const_reference lhs, const_reference rhs, std::error_code&) const override { //std::cout << "operator/ lhs: " << lhs << ", rhs: " << rhs << "\n"; if (!(lhs.is_number() && rhs.is_number())) { return Json::null(); } if (lhs.is_int64() && rhs.is_int64()) { return Json(((lhs.template as() % rhs.template as())), semantic_tag::none); } if (lhs.is_uint64() && rhs.is_uint64()) { return Json((lhs.template as() % rhs.template as()), semantic_tag::none); } return Json(fmod(lhs.as_double(), rhs.as_double()), semantic_tag::none); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("modulus operator"); return s; } }; // function_base template class function_base { jsoncons::optional arg_count_; public: using value_type = Json; using parameter_type = parameter; function_base(jsoncons::optional arg_count) : arg_count_(arg_count) { } function_base(const function_base&) = default; function_base(function_base&&) = default; virtual ~function_base() = default; function_base& operator=(const function_base&) = default; function_base& operator=(function_base&&) = default; jsoncons::optional arity() const { return arg_count_; } virtual value_type evaluate(const std::vector& args, std::error_code& ec) const = 0; virtual std::string to_string(int level) const { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("function"); return s; } }; template class decorator_function : public function_base { public: using value_type = Json; using parameter_type = parameter; using string_view_type = typename Json::string_view_type; using function_type = std::function, std::error_code& ec)>; private: function_type f_; public: decorator_function(jsoncons::optional arity, const function_type& f) : function_base(arity), f_(f) { } value_type evaluate(const std::vector& args, std::error_code& ec) const override { return f_(args, ec); } }; template class contains_function : public function_base { public: using value_type = Json; using parameter_type = parameter; using string_view_type = typename Json::string_view_type; contains_function() : function_base(2) { } value_type evaluate(const std::vector& args, std::error_code& ec) const override { if (args.size() != *this->arity()) { ec = jsonpath_errc::invalid_arity; return value_type::null(); } auto arg0= args[0].value(); auto arg1= args[1].value(); switch (arg0.type()) { case json_type::array_value: for (auto& j : arg0.array_range()) { if (j == arg1) { return value_type(true, semantic_tag::none); } } return value_type(false, semantic_tag::none); case json_type::string_value: { if (!arg1.is_string()) { ec = jsonpath_errc::invalid_type; return value_type::null(); } auto sv0 = arg0.template as(); auto sv1 = arg1.template as(); return sv0.find(sv1) != string_view_type::npos ? value_type(true, semantic_tag::none) : value_type(false, semantic_tag::none); } default: { ec = jsonpath_errc::invalid_type; return value_type::null(); } } } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("contains function"); return s; } }; template class ends_with_function : public function_base { public: using value_type = Json; using parameter_type = parameter; using string_view_type = typename Json::string_view_type; ends_with_function() : function_base(2) { } value_type evaluate(const std::vector& args, std::error_code& ec) const override { if (args.size() != *this->arity()) { ec = jsonpath_errc::invalid_arity; return value_type::null(); } auto arg0= args[0].value(); if (!arg0.is_string()) { ec = jsonpath_errc::invalid_type; return value_type::null(); } auto arg1= args[1].value(); if (!arg1.is_string()) { ec = jsonpath_errc::invalid_type; return value_type::null(); } auto sv0 = arg0.template as(); auto sv1 = arg1.template as(); if (sv1.length() <= sv0.length() && sv1 == sv0.substr(sv0.length() - sv1.length())) { return value_type(true, semantic_tag::none); } return value_type(false, semantic_tag::none); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("ends_with function"); return s; } }; template class starts_with_function : public function_base { public: using value_type = Json; using parameter_type = parameter; using string_view_type = typename Json::string_view_type; starts_with_function() : function_base(2) { } value_type evaluate(const std::vector& args, std::error_code& ec) const override { if (args.size() != *this->arity()) { ec = jsonpath_errc::invalid_arity; return value_type::null(); } auto arg0= args[0].value(); if (!arg0.is_string()) { ec = jsonpath_errc::invalid_type; return value_type::null(); } auto arg1= args[1].value(); if (!arg1.is_string()) { ec = jsonpath_errc::invalid_type; return value_type::null(); } auto sv0 = arg0.template as(); auto sv1 = arg1.template as(); if (sv1.length() <= sv0.length() && sv1 == sv0.substr(0, sv1.length())) { return value_type(true, semantic_tag::none); } return value_type(false, semantic_tag::none); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("starts_with function"); return s; } }; template class sum_function : public function_base { public: using value_type = Json; using parameter_type = parameter; sum_function() : function_base(1) { } value_type evaluate(const std::vector& args, std::error_code& ec) const override { if (args.size() != *this->arity()) { ec = jsonpath_errc::invalid_arity; return value_type::null(); } auto arg0= args[0].value(); if (!arg0.is_array()) { //std::cout << "arg: " << arg0 << "\n"; ec = jsonpath_errc::invalid_type; return value_type::null(); } //std::cout << "sum function arg: " << arg0 << "\n"; double sum = 0; for (auto& j : arg0.array_range()) { if (!j.is_number()) { ec = jsonpath_errc::invalid_type; return value_type::null(); } sum += j.template as(); } return value_type(sum, semantic_tag::none); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("sum function"); return s; } }; #if defined(JSONCONS_HAS_STD_REGEX) template class tokenize_function : public function_base { using allocator_type = typename Json::allocator_type; allocator_type alloc_; public: using value_type = Json; using parameter_type = parameter; using char_type = typename Json::char_type; using string_type = typename Json::string_type; using string_view_type = typename Json::string_view_type; tokenize_function(const allocator_type& alloc) : function_base(2), alloc_(alloc) { } value_type evaluate(const std::vector& args, std::error_code& ec) const override { if (args.size() != *this->arity()) { ec = jsonpath_errc::invalid_arity; return value_type::null(); } if (!args[0].value().is_string() || !args[1].value().is_string()) { //std::cout << "arg: " << arg0 << "\n"; ec = jsonpath_errc::invalid_type; return value_type::null(); } auto arg0 = args[0].value().template as(); auto arg1 = args[1].value().template as(); auto s0 = string_type(arg0.begin(), arg0.end(), alloc_); auto s1 = string_type(arg1.begin(), arg1.end(), alloc_); std::regex::flag_type options = std::regex_constants::ECMAScript; std::basic_regex pieces_regex(s1, options); std::regex_token_iterator rit ( s0.begin(), s0.end(), pieces_regex, -1); std::regex_token_iterator rend; value_type j(json_array_arg, semantic_tag::none, alloc_); while (rit != rend) { auto s = (*rit).str(); j.emplace_back(s.c_str(), semantic_tag::none); ++rit; } return j; } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("tokenize function"); return s; } }; #endif // defined(JSONCONS_HAS_STD_REGEX) template class ceil_function : public function_base { public: using value_type = Json; using parameter_type = parameter; ceil_function() : function_base(1) { } value_type evaluate(const std::vector& args, std::error_code& ec) const override { if (args.size() != *this->arity()) { ec = jsonpath_errc::invalid_arity; return value_type::null(); } auto arg0= args[0].value(); switch (arg0.type()) { case json_type::uint64_value: case json_type::int64_value: { return value_type(arg0.template as(), semantic_tag::none); } case json_type::double_value: { return value_type(std::ceil(arg0.template as()), semantic_tag::none); } default: ec = jsonpath_errc::invalid_type; return value_type::null(); } } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("ceil function"); return s; } }; template class floor_function : public function_base { public: using value_type = Json; using parameter_type = parameter; floor_function() : function_base(1) { } value_type evaluate(const std::vector& args, std::error_code& ec) const override { if (args.size() != *this->arity()) { ec = jsonpath_errc::invalid_arity; return value_type::null(); } auto arg0= args[0].value(); switch (arg0.type()) { case json_type::uint64_value: case json_type::int64_value: { return value_type(arg0.template as(), semantic_tag::none); } case json_type::double_value: { return value_type(std::floor(arg0.template as()), semantic_tag::none); } default: ec = jsonpath_errc::invalid_type; return value_type::null(); } } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("floor function"); return s; } }; template class to_number_function : public function_base { public: using value_type = Json; using parameter_type = parameter; to_number_function() : function_base(1) { } value_type evaluate(const std::vector& args, std::error_code& ec) const override { if (args.size() != *this->arity()) { ec = jsonpath_errc::invalid_arity; return value_type::null(); } auto arg0= args[0].value(); switch (arg0.type()) { case json_type::int64_value: case json_type::uint64_value: case json_type::double_value: return arg0; case json_type::string_value: { auto sv = arg0.as_string_view(); uint64_t un{0}; auto result1 = jsoncons::detail::to_integer(sv.data(), sv.length(), un); if (result1) { return value_type(un, semantic_tag::none); } int64_t sn{0}; auto result2 = jsoncons::detail::to_integer(sv.data(), sv.length(), sn); if (result2) { return value_type(sn, semantic_tag::none); } const jsoncons::detail::chars_to to_double; try { auto s = arg0.as_string(); double d = to_double(s.c_str(), s.length()); return value_type(d, semantic_tag::none); } catch (const std::exception&) { return value_type::null(); } } default: ec = jsonpath_errc::invalid_type; return value_type::null(); } } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("to_number function"); return s; } }; template class prod_function : public function_base { public: using value_type = Json; using parameter_type = parameter; prod_function() : function_base(1) { } value_type evaluate(const std::vector& args, std::error_code& ec) const override { if (args.size() != *this->arity()) { ec = jsonpath_errc::invalid_arity; return value_type::null(); } auto arg0= args[0].value(); if (!arg0.is_array() || arg0.empty()) { //std::cout << "arg: " << arg0 << "\n"; ec = jsonpath_errc::invalid_type; return value_type::null(); } double prod = 1; for (auto& j : arg0.array_range()) { if (!j.is_number()) { ec = jsonpath_errc::invalid_type; return value_type::null(); } prod *= j.template as(); } return value_type(prod, semantic_tag::none); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("prod function"); return s; } }; template class avg_function : public function_base { public: using value_type = Json; using parameter_type = parameter; avg_function() : function_base(1) { } value_type evaluate(const std::vector& args, std::error_code& ec) const override { if (args.size() != *this->arity()) { ec = jsonpath_errc::invalid_arity; return value_type::null(); } auto arg0= args[0].value(); if (!arg0.is_array()) { ec = jsonpath_errc::invalid_type; return value_type::null(); } if (arg0.empty()) { return value_type::null(); } double sum = 0; for (auto& j : arg0.array_range()) { if (!j.is_number()) { ec = jsonpath_errc::invalid_type; return value_type::null(); } sum += j.template as(); } return value_type(sum / static_cast(arg0.size()), semantic_tag::none); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("to_string function"); return s; } }; template class min_function : public function_base { public: using value_type = Json; using parameter_type = parameter; min_function() : function_base(1) { } value_type evaluate(const std::vector& args, std::error_code& ec) const override { if (args.size() != *this->arity()) { ec = jsonpath_errc::invalid_arity; return value_type::null(); } auto arg0= args[0].value(); if (!arg0.is_array()) { //std::cout << "arg: " << arg0 << "\n"; ec = jsonpath_errc::invalid_type; return value_type::null(); } if (arg0.empty()) { return value_type::null(); } bool is_number = arg0.at(0).is_number(); bool is_string = arg0.at(0).is_string(); if (!is_number && !is_string) { ec = jsonpath_errc::invalid_type; return value_type::null(); } std::size_t index = 0; for (std::size_t i = 1; i < arg0.size(); ++i) { if (!(arg0.at(i).is_number() == is_number && arg0.at(i).is_string() == is_string)) { ec = jsonpath_errc::invalid_type; return value_type::null(); } if (arg0.at(i) < arg0.at(index)) { index = i; } } return arg0.at(index); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("min function"); return s; } }; template class max_function : public function_base { public: using value_type = Json; using parameter_type = parameter; max_function() : function_base(1) { } value_type evaluate(const std::vector& args, std::error_code& ec) const override { if (args.size() != *this->arity()) { ec = jsonpath_errc::invalid_arity; return value_type::null(); } auto arg0= args[0].value(); if (!arg0.is_array()) { //std::cout << "arg: " << arg0 << "\n"; ec = jsonpath_errc::invalid_type; return value_type::null(); } if (arg0.empty()) { return value_type::null(); } bool is_number = arg0.at(0).is_number(); bool is_string = arg0.at(0).is_string(); if (!is_number && !is_string) { ec = jsonpath_errc::invalid_type; return value_type::null(); } std::size_t index = 0; for (std::size_t i = 1; i < arg0.size(); ++i) { if (!(arg0.at(i).is_number() == is_number && arg0.at(i).is_string() == is_string)) { ec = jsonpath_errc::invalid_type; return value_type::null(); } if (arg0.at(i) > arg0.at(index)) { index = i; } } return arg0.at(index); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("max function"); return s; } }; template class abs_function : public function_base { public: using value_type = Json; using parameter_type = parameter; abs_function() : function_base(1) { } value_type evaluate(const std::vector& args, std::error_code& ec) const override { if (args.size() != *this->arity()) { ec = jsonpath_errc::invalid_arity; return value_type::null(); } auto arg0= args[0].value(); switch (arg0.type()) { case json_type::uint64_value: return arg0; case json_type::int64_value: { return arg0.template as() >= 0 ? arg0 : value_type(std::abs(arg0.template as()), semantic_tag::none); } case json_type::double_value: { return arg0.template as() >= 0 ? arg0 : value_type(std::abs(arg0.template as()), semantic_tag::none); } default: { ec = jsonpath_errc::invalid_type; return value_type::null(); } } } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("abs function"); return s; } }; template class length_function : public function_base { public: using value_type = Json; using string_view_type = typename Json::string_view_type; using parameter_type = parameter; length_function() : function_base(1) { } value_type evaluate(const std::vector& args, std::error_code& ec) const override { if (args.size() != *this->arity()) { ec = jsonpath_errc::invalid_arity; return value_type::null(); } auto arg0 = args[0].value(); //std::cout << "length function arg: " << arg0 << "\n"; switch (arg0.type()) { case json_type::object_value: case json_type::array_value: //std::cout << "LENGTH ARG: " << arg0 << "\n"; return value_type(arg0.size(), semantic_tag::none); case json_type::string_value: { auto sv0 = arg0.template as(); auto length = unicode_traits::count_codepoints(sv0.data(), sv0.size()); return value_type(length, semantic_tag::none); } default: { ec = jsonpath_errc::invalid_type; return value_type::null(); } } } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("length function"); return s; } }; template class keys_function : public function_base { using allocator_type = typename Json::allocator_type; allocator_type alloc_; public: using value_type = Json; using parameter_type = parameter; using string_view_type = typename Json::string_view_type; keys_function(const allocator_type& alloc) : function_base(1), alloc_(alloc) { } value_type evaluate(const std::vector& args, std::error_code& ec) const override { if (args.size() != *this->arity()) { ec = jsonpath_errc::invalid_arity; return value_type::null(); } auto arg0 = args[0].value(); if (!arg0.is_object()) { ec = jsonpath_errc::invalid_type; return value_type::null(); } value_type result(json_array_arg, semantic_tag::none, alloc_); result.reserve(args.size()); for (auto& item : arg0.object_range()) { auto s = item.key(); result.emplace_back(s.c_str(), semantic_tag::none); } return result; } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("keys function"); return s; } }; enum class jsonpath_token_kind { root_node, current_node, expression, lparen, rparen, begin_union, end_union, begin_filter, end_filter, begin_expression, end_index_expression, end_argument_expression, separator, literal, selector, function, end_function, argument, unary_operator, binary_operator }; inline std::string to_string(jsonpath_token_kind kind) { switch (kind) { case jsonpath_token_kind::root_node: return "root_node"; case jsonpath_token_kind::current_node: return "current_node"; case jsonpath_token_kind::lparen: return "lparen"; case jsonpath_token_kind::rparen: return "rparen"; case jsonpath_token_kind::begin_union: return "begin_union"; case jsonpath_token_kind::end_union: return "end_union"; case jsonpath_token_kind::begin_filter: return "begin_filter"; case jsonpath_token_kind::end_filter: return "end_filter"; case jsonpath_token_kind::begin_expression: return "begin_expression"; case jsonpath_token_kind::end_index_expression: return "end_index_expression"; case jsonpath_token_kind::end_argument_expression: return "end_argument_expression"; case jsonpath_token_kind::separator: return "separator"; case jsonpath_token_kind::literal: return "literal"; case jsonpath_token_kind::selector: return "selector"; case jsonpath_token_kind::function: return "function"; case jsonpath_token_kind::end_function: return "end_function"; case jsonpath_token_kind::argument: return "argument"; case jsonpath_token_kind::unary_operator: return "unary_operator"; case jsonpath_token_kind::binary_operator: return "binary_operator"; default: return ""; } } template struct path_value_pair { using char_type = typename Json::char_type; using string_type = typename Json::string_type; using value_type = Json; using reference = JsonReference; using value_pointer = typename std::conditional::type>::value,typename Json::const_pointer,typename Json::pointer>::type; using path_node_type = basic_path_node; using path_pointer = const path_node_type*; path_pointer path_ptr_; value_pointer value_ptr_; path_value_pair(const path_node_type& path, reference value) noexcept : path_ptr_(std::addressof(path)), value_ptr_(std::addressof(value)) { } path_value_pair(const path_value_pair&) = default; path_value_pair(path_value_pair&& other) = default; path_value_pair& operator=(const path_value_pair&) = default; path_value_pair& operator=(path_value_pair&& other) = default; ~path_value_pair() = default; path_node_type path() const { return *path_ptr_; } reference value() { return *value_ptr_; } }; template struct path_value_pair_less { bool operator()(const path_value_pair& lhs, const path_value_pair& rhs) const noexcept { return lhs.path() < rhs.path(); } }; template struct path_value_pair_greater { bool operator()(const path_value_pair& lhs, const path_value_pair& rhs) const noexcept { return rhs.path() < lhs.path(); } }; template struct path_value_pair_equal { bool operator()(const path_value_pair& lhs, const path_value_pair& rhs) const noexcept { return lhs.path() == rhs.path(); } }; template struct path_component_value_pair { using char_type = typename Json::char_type; using string_type = typename Json::string_type; using value_type = Json; using reference = JsonReference; using value_pointer = typename std::conditional::type>::value,typename Json::const_pointer,typename Json::pointer>::type; using path_node_type = basic_path_node; using path_pointer = const path_node_type*; private: const path_node_type* last_ptr_; value_pointer value_ptr_; public: path_component_value_pair(const path_node_type& last, reference value) noexcept : last_ptr_(std::addressof(last)), value_ptr_(std::addressof(value)) { } const path_node_type& last() const { return *last_ptr_; } reference value() const { return *value_ptr_; } }; template class node_receiver { public: using char_type = typename Json::char_type; using string_type = typename Json::string_type; using reference = JsonReference; using path_node_type = basic_path_node; node_receiver() = default; node_receiver(const node_receiver&) = default; node_receiver(node_receiver&&) = default; virtual ~node_receiver() = default; node_receiver& operator=(const node_receiver&) = default; node_receiver& operator=(node_receiver&&) = default; virtual void add(const path_node_type& base_path, reference value) = 0; }; template class path_value_receiver : public node_receiver { public: using allocator_type = typename Json::allocator_type; using reference = JsonReference; using char_type = typename Json::char_type; using string_type = typename Json::string_type; using path_node_type = basic_path_node; using path_value_pair_type = path_value_pair; allocator_type alloc_; std::vector nodes; path_value_receiver(const allocator_type& alloc) : alloc_(alloc) { } void add(const path_node_type& base_path, reference value) override { nodes.emplace_back(base_path, value); } }; template class path_component_value_receiver : public node_receiver { public: using reference = JsonReference; using char_type = typename Json::char_type; using string_type = typename Json::string_type; using path_node_type = basic_path_node; using path_component_value_pair_type = path_component_value_pair; std::vector nodes; void add(const path_node_type& base_path, reference value) override { nodes.emplace_back(base_path, value); } }; template class eval_context { using allocator_type = typename Json::allocator_type; using char_type = typename Json::char_type; using string_type = typename Json::string_type; using reference = JsonReference; using pointer = typename std::conditional::type>::value,typename Json::const_pointer,typename Json::pointer>::type; using path_node_type = basic_path_node; allocator_type alloc_; std::vector> temp_json_values_; std::vector> temp_node_values_; std::unordered_map cache_; string_type length_label_; public: eval_context(const allocator_type& alloc = allocator_type()) : alloc_(alloc), length_label_{JSONCONS_CSTRING_CONSTANT(char_type, "length"), alloc} { } allocator_type get_allocator() const { return alloc_; } bool is_cached(std::size_t id) const { return cache_.find(id) != cache_.end(); } void add_to_cache(std::size_t id, reference val) { cache_.emplace(id, std::addressof(val)); } reference get_from_cache(std::size_t id) { return *cache_[id]; } reference null_value() { static Json a_null = Json(null_type(), semantic_tag::none); return a_null; } template Json* create_json(Args&& ... args) { auto temp = jsoncons::make_unique(std::forward(args)...); Json* ptr = temp.get(); temp_json_values_.push_back(std::move(temp)); return ptr; } const string_type& length_label() const { return length_label_; } template const path_node_type* create_path_node(Args&& ... args) { auto temp = jsoncons::make_unique(std::forward(args)...); path_node_type* ptr = temp.get(); temp_node_values_.push_back(std::move(temp)); return ptr; } }; template struct node_less { bool operator()(const path_value_pair& a, const path_value_pair& b) const { return *(a.ptr) < *(b.ptr); } }; template class jsonpath_selector { bool is_path_; std::size_t precedence_level_; public: using char_type = typename Json::char_type; using string_type = typename Json::string_type; using string_view_type = jsoncons::basic_string_view>; using value_type = Json; using reference = JsonReference; using pointer = typename std::conditional::type>::value,typename Json::const_pointer,typename Json::pointer>::type; using path_value_pair_type = path_value_pair; using path_node_type = basic_path_node; using node_receiver_type = node_receiver; using selector_type = jsonpath_selector; jsonpath_selector(bool is_path, std::size_t precedence_level = 0) : is_path_(is_path), precedence_level_(precedence_level) { } virtual ~jsonpath_selector() = default; bool is_path() const { return is_path_; } std::size_t precedence_level() const { return precedence_level_; } bool is_right_associative() const { return true; } virtual void select(eval_context& context, reference root, const path_node_type& base_path, reference val, node_receiver_type& receiver, result_options options) const = 0; virtual reference evaluate(eval_context& context, reference root, const path_node_type& base_path, reference current, result_options options, std::error_code& ec) const = 0; virtual void append_selector(jsonpath_selector*) { } virtual std::string to_string(int) const { return std::string(); } }; template struct static_resources { using allocator_type = typename Json::allocator_type; using char_type = typename Json::char_type; using string_type = typename Json::string_type; using value_type = Json; using reference = typename jsonpath_traits::reference; using const_reference = typename jsonpath_traits::const_reference; using function_base_type = function_base; using selector_type = jsonpath_selector; using const_selector_type = jsonpath_selector; struct MyHash { std::uintmax_t operator()(string_type const& s) const noexcept { const int p = 31; const int m = static_cast(1e9) + 9; std::uintmax_t hash_value = 0; std::uintmax_t p_pow = 1; for (char_type c : s) { hash_value = (hash_value + (c - 'a' + 1) * p_pow) % m; p_pow = (p_pow * p) % m; } return hash_value; } }; allocator_type alloc_; std::vector> selectors_; std::vector> const_selectors_; std::vector> temp_json_values_; std::vector>> unary_operators_; std::unordered_map,MyHash> functions_; std::unordered_map,MyHash> custom_functions_; static_resources(const static_resources&) = delete; static_resources(static_resources&&) = default; static_resources(const allocator_type& alloc = allocator_type()) : alloc_(alloc) { functions_.emplace(string_type{JSONCONS_CSTRING_CONSTANT(char_type, "abs"), alloc_}, jsoncons::make_unique>()); functions_.emplace(string_type{ JSONCONS_CSTRING_CONSTANT(char_type, "contains"), alloc_ }, jsoncons::make_unique>()); functions_.emplace(string_type{ JSONCONS_CSTRING_CONSTANT(char_type, "starts_with"), alloc_ }, jsoncons::make_unique>()); functions_.emplace(string_type{ JSONCONS_CSTRING_CONSTANT(char_type, "ends_with"), alloc_ }, jsoncons::make_unique>()); functions_.emplace(string_type{JSONCONS_CSTRING_CONSTANT(char_type, "ceil"), alloc_}, jsoncons::make_unique>()); functions_.emplace(string_type{JSONCONS_CSTRING_CONSTANT(char_type, "floor"), alloc_}, jsoncons::make_unique>()); functions_.emplace(string_type{ JSONCONS_CSTRING_CONSTANT(char_type, "to_number"), alloc_ }, jsoncons::make_unique>()); functions_.emplace(string_type{JSONCONS_CSTRING_CONSTANT(char_type, "sum"), alloc_}, jsoncons::make_unique>()); functions_.emplace(string_type{JSONCONS_CSTRING_CONSTANT(char_type, "prod"), alloc_}, jsoncons::make_unique>()); functions_.emplace(string_type{JSONCONS_CSTRING_CONSTANT(char_type, "avg"), alloc_}, jsoncons::make_unique>()); functions_.emplace(string_type{JSONCONS_CSTRING_CONSTANT(char_type, "min"), alloc_}, jsoncons::make_unique>()); functions_.emplace(string_type{JSONCONS_CSTRING_CONSTANT(char_type, "max"), alloc_}, jsoncons::make_unique>()); functions_.emplace(string_type{JSONCONS_CSTRING_CONSTANT(char_type, "length"), alloc_}, jsoncons::make_unique>()); functions_.emplace(string_type{ JSONCONS_CSTRING_CONSTANT(char_type, "keys"), alloc_ }, jsoncons::make_unique>(alloc_)); #if defined(JSONCONS_HAS_STD_REGEX) functions_.emplace(string_type{ JSONCONS_CSTRING_CONSTANT(char_type, "tokenize"), alloc_ }, jsoncons::make_unique>(alloc_)); #endif functions_.emplace(string_type{JSONCONS_CSTRING_CONSTANT(char_type, "count"), alloc_}, jsoncons::make_unique>()); } static_resources(const custom_functions& functions, const allocator_type& alloc = allocator_type()) : static_resources(alloc) { for (const auto& item : functions) { custom_functions_.emplace(item.name(), jsoncons::make_unique>(item.arity(),item.function())); } } ~static_resources() = default; static_resources operator=(const static_resources&) = delete; static_resources operator=(static_resources&&) = delete; const function_base_type* get_function(const string_type& name, std::error_code& ec) const { auto it = functions_.find(name); if (it == functions_.end()) { auto it2 = custom_functions_.find(name); if (it2 == custom_functions_.end()) { ec = jsonpath_errc::unknown_function; return nullptr; } return it2->second.get(); } return (*it).second.get(); } const unary_operator* get_unary_not() const { static unary_not_operator oper; return &oper; } const unary_operator* get_unary_minus() const { static unary_minus_operator oper; return &oper; } const unary_operator* get_regex_operator(std::basic_regex&& pattern) { unary_operators_.push_back(jsoncons::make_unique>(std::move(pattern))); return unary_operators_.back().get(); } const binary_operator* get_or_operator() const { static or_operator oper; return &oper; } const binary_operator* get_and_operator() const { static and_operator oper; return &oper; } const binary_operator* get_eq_operator() const { static eq_operator oper; return &oper; } const binary_operator* get_ne_operator() const { static ne_operator oper; return &oper; } const binary_operator* get_lt_operator() const { static lt_operator oper; return &oper; } const binary_operator* get_lte_operator() const { static lte_operator oper; return &oper; } const binary_operator* get_gt_operator() const { static gt_operator oper; return &oper; } const binary_operator* get_gte_operator() const { static gte_operator oper; return &oper; } const binary_operator* get_plus_operator() const { static plus_operator oper; return &oper; } const binary_operator* get_minus_operator() const { static minus_operator oper; return &oper; } const binary_operator* get_mult_operator() const { static mult_operator oper; return &oper; } const binary_operator* get_div_operator() const { static div_operator oper; return &oper; } const binary_operator* get_modulus_operator() const { static modulus_operator oper; return &oper; } template typename std::enable_if::type>::value,const_selector_type*>::type new_selector(T&& val) { const_selectors_.push_back(jsoncons::make_unique(std::forward(val))); return const_selectors_.back().get(); } template typename std::enable_if::type>::value,selector_type*>::type new_selector(T&& val) { selectors_.push_back(jsoncons::make_unique(std::forward(val))); return selectors_.back().get(); } template Json* create_json(Args&& ... args) { auto temp = jsoncons::make_unique(std::forward(args)...); Json* ptr = temp.get(); temp_json_values_.emplace_back(std::move(temp)); return ptr; } }; template class expression_base { public: using char_type = typename Json::char_type; using string_type = typename Json::string_type; using string_view_type = jsoncons::basic_string_view>; using value_type = Json; using reference = JsonReference; using pointer = typename std::conditional::type>::value,typename Json::const_pointer,typename Json::pointer>::type; using path_value_pair_type = path_value_pair; using path_node_type = basic_path_node; expression_base() = default; expression_base(const expression_base&) = default; expression_base(expression_base&&) = default; virtual ~expression_base() = default; expression_base& operator=(const expression_base&) = default; expression_base& operator=(expression_base&&) = default; virtual value_type evaluate(eval_context& context, reference root, reference val, result_options options, std::error_code& ec) const = 0; virtual std::string to_string(int level) const = 0; }; template class token { public: using selector_type = jsonpath_selector; using expression_base_type = expression_base; jsonpath_token_kind token_kind_; union { char dummy_; selector_type* selector_; std::unique_ptr expression_; const unary_operator* unary_operator_; const binary_operator* binary_operator_; const function_base* function_; Json value_; }; public: token(const token& other) = delete; token(token&& other) noexcept { construct(std::move(other)); } token(const unary_operator* expr) noexcept : token_kind_(jsonpath_token_kind::unary_operator), unary_operator_(expr) { } token(const binary_operator* expr) noexcept : token_kind_(jsonpath_token_kind::binary_operator), binary_operator_(expr) { } token(current_node_arg_t) noexcept : token_kind_(jsonpath_token_kind::current_node), dummy_{} { } token(root_node_arg_t) noexcept : token_kind_(jsonpath_token_kind::root_node), dummy_{} { } token(end_function_arg_t) noexcept : token_kind_(jsonpath_token_kind::end_function), dummy_{} { } token(separator_arg_t) noexcept : token_kind_(jsonpath_token_kind::separator), dummy_{} { } token(lparen_arg_t) noexcept : token_kind_(jsonpath_token_kind::lparen), dummy_{} { } token(rparen_arg_t) noexcept : token_kind_(jsonpath_token_kind::rparen), dummy_{} { } token(begin_union_arg_t) noexcept : token_kind_(jsonpath_token_kind::begin_union), dummy_{} { } token(end_union_arg_t) noexcept : token_kind_(jsonpath_token_kind::end_union), dummy_{} { } token(begin_filter_arg_t) noexcept : token_kind_(jsonpath_token_kind::begin_filter), dummy_{} { } token(end_filter_arg_t) noexcept : token_kind_(jsonpath_token_kind::end_filter), dummy_{} { } token(begin_expression_arg_t) noexcept : token_kind_(jsonpath_token_kind::begin_expression), dummy_{} { } token(end_index_expression_arg_t) noexcept : token_kind_(jsonpath_token_kind::end_index_expression), dummy_{} { } token(end_argument_expression_arg_t) noexcept : token_kind_(jsonpath_token_kind::end_argument_expression), dummy_{} { } token(selector_type* selector) : token_kind_(jsonpath_token_kind::selector), selector_(selector) { } token(std::unique_ptr&& expr) : token_kind_(jsonpath_token_kind::expression) { new (&expression_) std::unique_ptr(std::move(expr)); } token(const function_base* function) noexcept : token_kind_(jsonpath_token_kind::function), function_(function) { } token(argument_arg_t) noexcept : token_kind_(jsonpath_token_kind::argument), dummy_{} { } token(literal_arg_t, Json&& value) noexcept : token_kind_(jsonpath_token_kind::literal), value_(std::move(value)) { } const Json& get_value(const_reference_arg_t, eval_context&) const { return value_; } Json& get_value(reference_arg_t, eval_context& context) const { return *context.create_json(value_); } #if defined(__GNUC__) && JSONCONS_GCC_AVAILABLE(12,0,0) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif token& operator=(const token& other) = delete; token& operator=(token&& other) noexcept { if (&other != this) { if (token_kind_ == other.token_kind_) { switch (token_kind_) { case jsonpath_token_kind::selector: selector_ = other.selector_; break; case jsonpath_token_kind::expression: expression_ = std::move(other.expression_); break; case jsonpath_token_kind::unary_operator: unary_operator_ = other.unary_operator_; break; case jsonpath_token_kind::binary_operator: binary_operator_ = other.binary_operator_; break; case jsonpath_token_kind::function: function_ = other.function_; break; case jsonpath_token_kind::literal: value_ = std::move(other.value_); break; default: break; } } else { destroy(); construct(std::move(other)); } } return *this; } #if defined(__GNUC__) && JSONCONS_GCC_AVAILABLE(12,0,0) # pragma GCC diagnostic pop #endif ~token() noexcept { destroy(); } jsonpath_token_kind token_kind() const { return token_kind_; } bool is_lparen() const { return token_kind_ == jsonpath_token_kind::lparen; } bool is_rparen() const { return token_kind_ == jsonpath_token_kind::rparen; } bool is_current_node() const { return token_kind_ == jsonpath_token_kind::current_node; } bool is_path() const { if (token_kind_ == jsonpath_token_kind::selector) { JSONCONS_ASSERT(selector_ != nullptr); return selector_->is_path(); } return false; } bool is_operator() const { return token_kind_ == jsonpath_token_kind::unary_operator || token_kind_ == jsonpath_token_kind::binary_operator; } std::size_t precedence_level() const { switch(token_kind_) { case jsonpath_token_kind::selector: JSONCONS_ASSERT(selector_ != nullptr); return selector_->precedence_level(); case jsonpath_token_kind::unary_operator: JSONCONS_ASSERT(unary_operator_ != nullptr); return unary_operator_->precedence_level(); case jsonpath_token_kind::binary_operator: JSONCONS_ASSERT(binary_operator_ != nullptr); return binary_operator_->precedence_level(); default: return 0; } } jsoncons::optional arity() const { if (token_kind_ == jsonpath_token_kind::function) { JSONCONS_ASSERT(function_ != nullptr); return function_->arity(); } return jsoncons::optional(); } bool is_right_associative() const { switch(token_kind_) { case jsonpath_token_kind::selector: JSONCONS_ASSERT(selector_ != nullptr); return selector_->is_right_associative(); case jsonpath_token_kind::unary_operator: JSONCONS_ASSERT(unary_operator_ != nullptr); return unary_operator_->is_right_associative(); case jsonpath_token_kind::binary_operator: JSONCONS_ASSERT(binary_operator_ != nullptr); return binary_operator_->is_right_associative(); default: return false; } } #if defined(__GNUC__) && JSONCONS_GCC_AVAILABLE(12,0,0) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif void construct(token&& other) noexcept { token_kind_ = other.token_kind_; switch (token_kind_) { case jsonpath_token_kind::selector: selector_ = other.selector_; break; case jsonpath_token_kind::expression: new (&expression_) std::unique_ptr(std::move(other.expression_)); break; case jsonpath_token_kind::unary_operator: unary_operator_ = other.unary_operator_; break; case jsonpath_token_kind::binary_operator: binary_operator_ = other.binary_operator_; break; case jsonpath_token_kind::function: function_ = other.function_; break; case jsonpath_token_kind::literal: new (&value_) Json(std::move(other.value_)); break; default: break; } } #if defined(__GNUC__) && JSONCONS_GCC_AVAILABLE(12,0,0) # pragma GCC diagnostic pop #endif void destroy() noexcept { switch(token_kind_) { case jsonpath_token_kind::expression: expression_.~unique_ptr(); break; case jsonpath_token_kind::literal: value_.~Json(); break; default: break; } } std::string to_string(int level) const { std::string s; switch (token_kind_) { case jsonpath_token_kind::root_node: if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("root node"); break; case jsonpath_token_kind::current_node: if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("current node"); break; case jsonpath_token_kind::argument: if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("argument"); break; case jsonpath_token_kind::selector: JSONCONS_ASSERT(selector_ != nullptr); s.append(selector_->to_string(level)); break; case jsonpath_token_kind::expression: s.append(expression_->to_string(level)); break; case jsonpath_token_kind::literal: { if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } auto sbuf = value_.to_string(); unicode_traits::convert(sbuf.data(), sbuf.size(), s); break; } case jsonpath_token_kind::binary_operator: s.append(binary_operator_->to_string(level)); break; case jsonpath_token_kind::function: s.append(function_->to_string(level)); break; default: if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("token kind: "); s.append(jsoncons::jsonpath::detail::to_string(token_kind_)); break; } //s.append("\n"); return s; } }; template class callback_receiver : public node_receiver { public: using allocator_type = typename Json::allocator_type; using reference = JsonReference; using char_type = typename Json::char_type; using string_type = typename Json::string_type; using path_node_type = basic_path_node; private: allocator_type alloc_; Callback& callback_; public: callback_receiver(Callback& callback, const allocator_type& alloc) : alloc_(alloc), callback_(callback) { } void add(const path_node_type& base_path, reference value) override { callback_(base_path, value); } }; template class path_expression { public: using allocator_type = typename Json::allocator_type; using char_type = typename Json::char_type; using string_type = typename Json::string_type; using string_view_type = typename Json::string_view_type; using path_value_pair_type = path_value_pair; using path_value_pair_less_type = path_value_pair_less; using path_value_pair_greater_type = path_value_pair_greater; using path_value_pair_equal_type = path_value_pair_equal; using value_type = Json; using reference = typename path_value_pair_type::reference; using pointer = typename path_value_pair_type::value_pointer; using token_type = token; using reference_arg_type = typename std::conditional::type>::value, const_reference_arg_t,reference_arg_t>::type; using path_node_type = basic_path_node; using selector_type = jsonpath_selector; private: allocator_type alloc_; selector_type* selector_; result_options required_options_; public: path_expression(selector_type* selector, bool paths_required, const allocator_type& alloc) : alloc_(alloc), selector_(selector), required_options_() { if (paths_required) { required_options_ |= result_options::path; } } path_expression(const allocator_type& alloc) : alloc_(alloc), selector_(nullptr), required_options_() { } path_expression(const path_expression& expr) = delete; path_expression(path_expression&& expr) = default; ~path_expression() = default; path_expression& operator=(const path_expression& expr) = delete; path_expression& operator=(path_expression&& expr) = default; Json evaluate(eval_context& context, reference root, const path_node_type& path, reference instance, result_options options) const { Json result(json_array_arg, semantic_tag::none, alloc_); if ((options & result_options::path) == result_options::path) { auto callback = [&result](const path_node_type& pathp, reference) { result.emplace_back(to_basic_string(pathp)); }; evaluate(context, root, path, instance, callback, options); } else { auto callback = [&result](const path_node_type&, reference val) { result.push_back(val); }; evaluate(context, root, path, instance, callback, options); } return result; } template typename std::enable_if::value,void>::type evaluate(eval_context& context, reference root, const path_node_type& path, reference current, Callback callback, result_options options) const { std::error_code ec; options |= required_options_; const result_options require_more = result_options::nodups | result_options::sort | result_options::sort_descending; if (selector_ != nullptr) { if ((options & require_more) != result_options()) { path_value_receiver receiver{alloc_}; selector_->select(context, root, path, current, receiver, options); if (receiver.nodes.size() > 1) { if ((options & result_options::sort_descending) == result_options::sort_descending) { std::sort(receiver.nodes.begin(), receiver.nodes.end(), path_value_pair_greater_type()); } else if ((options & result_options::sort) == result_options::sort) { std::sort(receiver.nodes.begin(), receiver.nodes.end(), path_value_pair_less_type()); } } if (receiver.nodes.size() > 1 && (options & result_options::nodups) == result_options::nodups) { if ((options & result_options::sort_descending) == result_options::sort_descending) { auto last = std::unique(receiver.nodes.rbegin(),receiver.nodes.rend(),path_value_pair_equal_type()); receiver.nodes.erase(receiver.nodes.begin(), last.base()); for (auto& node : receiver.nodes) { callback(node.path(), node.value()); } } else if ((options & result_options::sort) == result_options::sort) { auto last = std::unique(receiver.nodes.begin(),receiver.nodes.end(),path_value_pair_equal_type()); receiver.nodes.erase(last,receiver.nodes.end()); for (auto& node : receiver.nodes) { callback(node.path(), node.value()); } } else { std::vector index(receiver.nodes); std::sort(index.begin(), index.end(), path_value_pair_less_type()); auto last = std::unique(index.begin(),index.end(),path_value_pair_equal_type()); index.erase(last,index.end()); std::vector temp2; temp2.reserve(index.size()); for (auto&& node : receiver.nodes) { auto it = std::lower_bound(index.begin(),index.end(),node, path_value_pair_less_type()); if (it != index.end() && (*it).path() == node.path()) { temp2.emplace_back(std::move(node)); index.erase(it); } } for (auto& node : temp2) { callback(node.path(), node.value()); } } } else { for (auto& node : receiver.nodes) { callback(node.path(), node.value()); } } } else { callback_receiver receiver(callback, alloc_); selector_->select(context, root, path, current, receiver, options); } } } std::string to_string(int level) const { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("expression "); if (selector_ != nullptr) { s.append(selector_->to_string(level+1)); } return s; } }; template class token_evaluator : public expression_base { public: using path_value_pair_type = path_value_pair; using value_type = Json; using reference = typename path_value_pair_type::reference; using pointer = typename path_value_pair_type::value_pointer; using const_pointer = const value_type*; using char_type = typename Json::char_type; using string_type = typename Json::string_type; using string_view_type = typename Json::string_view_type; using path_value_pair_less_type = path_value_pair_less; using path_value_pair_greater_type = path_value_pair_greater; using path_value_pair_equal_type = path_value_pair_equal; using parameter_type = parameter; using token_type = token; using reference_arg_type = typename std::conditional::type>::value, const_reference_arg_t,reference_arg_t>::type; using path_node_type = basic_path_node; using stack_item_type = value_or_pointer; private: std::vector token_list_; public: token_evaluator() { } token_evaluator(const token_evaluator& expr) = delete; token_evaluator(token_evaluator&& expr) = default; token_evaluator(std::vector&& token_stack) : token_list_(std::move(token_stack)) { } token_evaluator& operator=(const token_evaluator& expr) = delete; token_evaluator& operator=(token_evaluator&& expr) = default; ~token_evaluator() = default; value_type evaluate(eval_context& context, reference root, reference current, result_options options, std::error_code& ec) const override { std::vector stack; std::vector arg_stack; //std::cout << "EVALUATE TOKENS\n"; //for (auto& tok : token_list_) //{ // std::cout << tok.to_string() << "\n"; //} //std::cout << "\n"; if (!token_list_.empty()) { for (auto& tok : token_list_) { //std::cout << "Token: " << tok.to_string() << "\n"; switch (tok.token_kind()) { case jsonpath_token_kind::literal: { stack.emplace_back(std::addressof(tok.get_value(reference_arg_type(), context))); break; } case jsonpath_token_kind::unary_operator: { JSONCONS_ASSERT(!stack.empty()); auto item = std::move(stack.back()); stack.pop_back(); auto val = tok.unary_operator_->evaluate(item.value(), ec); stack.emplace_back(std::move(val)); break; } case jsonpath_token_kind::binary_operator: { //std::cout << "binary operator: " << stack.size() << "\n"; JSONCONS_ASSERT(stack.size() >= 2); auto rhs = std::move(stack.back()); //std::cout << "rhs: " << *rhs << "\n"; stack.pop_back(); auto lhs = std::move(stack.back()); //std::cout << "lhs: " << *lhs << "\n"; stack.pop_back(); auto val = tok.binary_operator_->evaluate(lhs.value(), rhs.value(), ec); //std::cout << "Evaluate binary expression: " << r << "\n"; stack.emplace_back(std::move(val)); break; } case jsonpath_token_kind::root_node: //std::cout << "root: " << root << "\n"; stack.emplace_back(std::addressof(root)); break; case jsonpath_token_kind::current_node: stack.emplace_back(std::addressof(current)); break; case jsonpath_token_kind::argument: JSONCONS_ASSERT(!stack.empty()); arg_stack.emplace_back(std::move(stack.back())); stack.pop_back(); break; case jsonpath_token_kind::function: { if (tok.function_->arity() && *(tok.function_->arity()) != arg_stack.size()) { ec = jsonpath_errc::invalid_arity; return Json::null(); } value_type val = tok.function_->evaluate(arg_stack, ec); if (JSONCONS_UNLIKELY(ec)) { return Json::null(); } //std::cout << "function result: " << val << "\n"; arg_stack.clear(); stack.emplace_back(std::move(val)); break; } case jsonpath_token_kind::expression: { value_type val = tok.expression_->evaluate(context, root, current, options, ec); stack.emplace_back(std::move(val)); break; } case jsonpath_token_kind::selector: { JSONCONS_ASSERT(!stack.empty()); auto item = std::move(stack.back()); //for (auto& item : stack) //{ //std::cout << "selector stack input:\n"; //switch (item.tag) //{ // case node_set_tag::single: // std::cout << "single: " << *(item.node.ptr) << "\n"; // break; // case node_set_tag::multi: // for (auto& node : stack.back().ptr().nodes) // { // std::cout << "multi: " << *node.ptr << "\n"; // } // break; // default: // break; //} //std::cout << "\n"; //} //std::cout << "selector item: " << *ptr << "\n"; reference val = tok.selector_->evaluate(context, root, path_node_type{}, item.value(), options, ec); stack.pop_back(); stack.emplace_back(stack_item_type(std::addressof(val))); break; } default: break; } } } //if (stack.size() != 1) //{ // std::cout << "Stack size: " << stack.size() << "\n"; //} return stack.empty() ? Json::null() : stack.back().value(); } std::string to_string(int level) const override { std::string s; if (level > 0) { s.append("\n"); s.append(std::size_t(level)*2, ' '); } s.append("token_evaluator "); for (const auto& item : token_list_) { s.append(item.to_string(level+1)); } return s; } private: }; } // namespace detail } // namespace jsonpath } // namespace jsoncons #endif // JSONCONS_EXT_JSONPATH_TOKEN_EVALUATOR_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonpointer/000077500000000000000000000000001477700171100220675ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons_ext/jsonpointer/jsonpointer.hpp000066400000000000000000001336751477700171100251710ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONPOINTER_JSONPOINTER_HPP #define JSONCONS_EXT_JSONPOINTER_JSONPOINTER_HPP #include #include #include #include #include // system_error #include // std::enable_if, std::true_type #include // std::move #include #include #include #include #include #include namespace jsoncons { namespace jsonpointer { namespace detail { enum class pointer_state { start, escaped, new_token, part }; } // namespace detail template > std::basic_string,Allocator> escape(jsoncons::basic_string_view s, const Allocator& = Allocator()) { std::basic_string,Allocator> result; for (auto c : s) { if (JSONCONS_UNLIKELY(c == '~')) { result.push_back('~'); result.push_back('0'); } else if (JSONCONS_UNLIKELY(c == '/')) { result.push_back('~'); result.push_back('1'); } else { result.push_back(c); } } return result; } template std::basic_string escape_string(const std::basic_string& s) { std::basic_string result; for (auto c : s) { switch (c) { case '~': result.push_back('~'); result.push_back('0'); break; case '/': result.push_back('~'); result.push_back('1'); break; default: result.push_back(c); break; } } return result; } // basic_json_pointer template class basic_json_pointer { public: // Member types using char_type = CharT; using string_type = std::basic_string; using string_view_type = jsoncons::basic_string_view; using const_iterator = typename std::vector::const_iterator; using iterator = const_iterator; using const_reverse_iterator = typename std::vector::const_reverse_iterator; using reverse_iterator = const_reverse_iterator; private: std::vector tokens_; public: // Constructors basic_json_pointer() { } basic_json_pointer(const std::vector& tokens) : tokens_(tokens) { } basic_json_pointer(std::vector&& tokens) : tokens_(std::move(tokens)) { } explicit basic_json_pointer(const string_view_type& s) { std::error_code ec; auto jp = parse(s, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(jsonpointer_error(ec)); } tokens_ = std::move(jp.tokens_); } explicit basic_json_pointer(const string_view_type& s, std::error_code& ec) { auto jp = parse(s, ec); if (!ec) { tokens_ = std::move(jp.tokens_); } } basic_json_pointer(const basic_json_pointer&) = default; basic_json_pointer(basic_json_pointer&&) = default; static basic_json_pointer parse(const string_view_type& input, std::error_code& ec) { std::vector tokens; if (input.empty()) { return basic_json_pointer(); } const char_type* p = input.data(); const char_type* pend = input.data() + input.size(); string_type unescaped; auto state = jsonpointer::detail::pointer_state::start; string_type buffer; while (p < pend) { switch (state) { case jsonpointer::detail::pointer_state::start: switch (*p) { case '/': state = jsonpointer::detail::pointer_state::new_token; break; default: ec = jsonpointer_errc::expected_slash; return basic_json_pointer(); }; break; case jsonpointer::detail::pointer_state::part: state = jsonpointer::detail::pointer_state::new_token; JSONCONS_FALLTHROUGH; case jsonpointer::detail::pointer_state::new_token: switch (*p) { case '/': tokens.push_back(buffer); buffer.clear(); state = jsonpointer::detail::pointer_state::part; break; case '~': state = jsonpointer::detail::pointer_state::escaped; break; default: buffer.push_back(*p); break; }; break; case jsonpointer::detail::pointer_state::escaped: switch (*p) { case '0': buffer.push_back('~'); state = jsonpointer::detail::pointer_state::new_token; break; case '1': buffer.push_back('/'); state = jsonpointer::detail::pointer_state::new_token; break; default: ec = jsonpointer_errc::expected_0_or_1; return basic_json_pointer(); }; break; } ++p; } if (state == jsonpointer::detail::pointer_state::escaped) { ec = jsonpointer_errc::expected_0_or_1; return basic_json_pointer(); } if (state == jsonpointer::detail::pointer_state::new_token || state == jsonpointer::detail::pointer_state::part) { tokens.push_back(buffer); } return basic_json_pointer(tokens); } // operator= basic_json_pointer& operator=(const basic_json_pointer&) = default; basic_json_pointer& operator=(basic_json_pointer&&) = default; // Modifiers void clear() { tokens_.clear(); } basic_json_pointer& append(const string_type& s) { tokens_.push_back(s); return *this; } template typename std::enable_if::value, basic_json_pointer&>::type append(IntegerType val) { string_type s; jsoncons::detail::from_integer(val, s); tokens_.push_back(s); return *this; } basic_json_pointer& operator/=(const string_type& s) { tokens_.push_back(s); return *this; } template typename std::enable_if::value, basic_json_pointer&>::type operator/=(IntegerType val) { string_type s; jsoncons::detail::from_integer(val, s); tokens_.push_back(s); return *this; } basic_json_pointer& operator+=(const basic_json_pointer& p) { for (const auto& s : p.tokens_) { tokens_.push_back(s); } return *this; } // Accessors bool empty() const { return tokens_.empty(); } string_type string() const { return to_string(); } string_type to_string() const { string_type buffer; for (const auto& token : tokens_) { buffer.push_back('/'); for (auto c : token) { switch (c) { case '~': buffer.push_back('~'); buffer.push_back('0'); break; case '/': buffer.push_back('~'); buffer.push_back('1'); break; default: buffer.push_back(c); break; } } } return buffer; } // Iterators iterator begin() const { return tokens_.begin(); } iterator end() const { return tokens_.end(); } reverse_iterator rbegin() const { return tokens_.rbegin(); } reverse_iterator rend() const { return tokens_.rend(); } // Non-member functions friend basic_json_pointer operator/(const basic_json_pointer& lhs, const string_type& rhs) { basic_json_pointer p(lhs); p /= rhs; return p; } friend basic_json_pointer operator+( const basic_json_pointer& lhs, const basic_json_pointer& rhs ) { basic_json_pointer p(lhs); p += rhs; return p; } friend bool operator==( const basic_json_pointer& lhs, const basic_json_pointer& rhs ) { return lhs.tokens_ == rhs.tokens_; } friend bool operator!=( const basic_json_pointer& lhs, const basic_json_pointer& rhs ) { return lhs.tokens_ != rhs.tokens_; } friend std::basic_ostream& operator<<( std::basic_ostream& os, const basic_json_pointer& p ) { os << p.to_string(); return os; } }; template typename std::enable_if::value, basic_json_pointer>::type operator/(const basic_json_pointer& lhs, IntegerType rhs) { basic_json_pointer p(lhs); p /= rhs; return p; } using json_pointer = basic_json_pointer; using wjson_pointer = basic_json_pointer; inline std::string to_string(const json_pointer& ptr) { return ptr.to_string(); } inline std::wstring to_wstring(const wjson_pointer& ptr) { return ptr.to_string(); } namespace detail { template const Json* resolve(const Json* current, const typename Json::string_view_type& buffer, std::error_code& ec) { if (current->is_array()) { if (buffer.size() == 1 && buffer[0] == '-') { ec = jsonpointer_errc::index_exceeds_array_size; return current; } std::size_t index{0}; auto result = jsoncons::detail::decimal_to_integer(buffer.data(), buffer.length(), index); if (!result) { ec = jsonpointer_errc::invalid_index; return current; } if (index >= current->size()) { ec = jsonpointer_errc::index_exceeds_array_size; return current; } current = std::addressof(current->at(index)); } else if (current->is_object()) { if (!current->contains(buffer)) { ec = jsonpointer_errc::key_not_found; return current; } current = std::addressof(current->at(buffer)); } else { ec = jsonpointer_errc::expected_object_or_array; return current; } return current; } template Json* resolve(Json* current, const typename Json::string_view_type& buffer, bool create_if_missing, std::error_code& ec) { if (current->is_array()) { if (buffer.size() == 1 && buffer[0] == '-') { ec = jsonpointer_errc::index_exceeds_array_size; return current; } std::size_t index{0}; auto result = jsoncons::detail::decimal_to_integer(buffer.data(), buffer.length(), index); if (!result) { ec = jsonpointer_errc::invalid_index; return current; } if (index >= current->size()) { ec = jsonpointer_errc::index_exceeds_array_size; return current; } current = std::addressof(current->at(index)); } else if (current->is_object()) { if (!current->contains(buffer)) { if (create_if_missing) { auto r = current->try_emplace(buffer, Json()); current = std::addressof(r.first->value()); } else { ec = jsonpointer_errc::key_not_found; return current; } } else { current = std::addressof(current->at(buffer)); } } else { ec = jsonpointer_errc::expected_object_or_array; return current; } return current; } } // namespace detail // get template Json& get(Json& root, const basic_json_pointer& location, bool create_if_missing, std::error_code& ec) { if (location.empty()) { return root; } Json* current = std::addressof(root); auto it = location.begin(); auto end = location.end(); while (it != end) { current = jsoncons::jsonpointer::detail::resolve(current, *it, create_if_missing, ec); if (JSONCONS_UNLIKELY(ec)) return *current; ++it; } return *current; } template typename std::enable_if>::value,Json&>::type get(Json& root, const StringSource& location_str, bool create_if_missing, std::error_code& ec) { auto jsonptr = basic_json_pointer::parse(location_str, ec); if (JSONCONS_UNLIKELY(ec)) { return root; } return get(root, jsonptr, create_if_missing, ec); } template const Json& get(const Json& root, const basic_json_pointer& location, std::error_code& ec) { if (location.empty()) { return root; } const Json* current = std::addressof(root); auto it = location.begin(); auto end = location.end(); while (it != end) { current = jsoncons::jsonpointer::detail::resolve(current, *it, ec); if (JSONCONS_UNLIKELY(ec)) return *current; ++it; } return *current; } template typename std::enable_if>::value,const Json&>::type get(const Json& root, const StringSource& location_str, std::error_code& ec) { auto jsonptr = basic_json_pointer::parse(location_str, ec); if (JSONCONS_UNLIKELY(ec)) { return root; } return get(root, jsonptr, ec); } template Json& get(Json& root, const basic_json_pointer& location, std::error_code& ec) { return get(root, location, false, ec); } template typename std::enable_if>::value,Json&>::type get(Json& root, const StringSource& location_str, std::error_code& ec) { return get(root, location_str, false, ec); } template Json& get(Json& root, const basic_json_pointer& location, bool create_if_missing = false) { std::error_code ec; Json& j = get(root, location, create_if_missing, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(jsonpointer_error(ec)); } return j; } template typename std::enable_if>::value,Json&>::type get(Json& root, const StringSource& location_str, bool create_if_missing = false) { std::error_code ec; Json& result = get(root, location_str, create_if_missing, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(jsonpointer_error(ec)); } return result; } template const Json& get(const Json& root, const basic_json_pointer& location) { std::error_code ec; const Json& j = get(root, location, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(jsonpointer_error(ec)); } return j; } template typename std::enable_if>::value,const Json&>::type get(const Json& root, const StringSource& location_str) { std::error_code ec; const Json& j = get(root, location_str, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(jsonpointer_error(ec)); } return j; } // contains template bool contains(const Json& root, const basic_json_pointer& location) { std::error_code ec; get(root, location, ec); return !ec ? true : false; } template typename std::enable_if>::value,bool>::type contains(const Json& root, const StringSource& location_str) { std::error_code ec; get(root, location_str, ec); return !ec ? true : false; } template void add(Json& root, const basic_json_pointer& location, T&& value, bool create_if_missing, std::error_code& ec) { Json* current = std::addressof(root); std::basic_string buffer; auto it = location.begin(); auto end = location.end(); while (it != end) { buffer = *it; ++it; if (it != end) { current = jsoncons::jsonpointer::detail::resolve(current, buffer, create_if_missing, ec); if (JSONCONS_UNLIKELY(ec)) return; } } if (current->is_array()) { if (buffer.size() == 1 && buffer[0] == '-') { current->emplace_back(std::forward(value)); current = std::addressof(current->at(current->size()-1)); } else { std::size_t index{0}; auto result = jsoncons::detail::decimal_to_integer(buffer.data(), buffer.length(), index); if (!result) { ec = jsonpointer_errc::invalid_index; return; } if (index > current->size()) { ec = jsonpointer_errc::index_exceeds_array_size; return; } if (index == current->size()) { current->emplace_back(std::forward(value)); current = std::addressof(current->at(current->size()-1)); } else { auto it2 = current->insert(current->array_range().begin()+index,std::forward(value)); current = std::addressof(*it2); } } } else if (current->is_object()) { auto r = current->insert_or_assign(buffer,std::forward(value)); current = std::addressof(r.first->value()); } else { ec = jsonpointer_errc::expected_object_or_array; return; } } // add template typename std::enable_if>::value,void>::type add(Json& root, const StringSource& location_str, T&& value, bool create_if_missing, std::error_code& ec) { auto jsonptr = basic_json_pointer::parse(location_str, ec); if (JSONCONS_UNLIKELY(ec)) { return; } add(root, jsonptr, std::forward(value), create_if_missing, ec); } template void add(Json& root, const basic_json_pointer& location, T&& value, std::error_code& ec) { add(root, location, std::forward(value), false, ec); } template typename std::enable_if>::value,void>::type add(Json& root, const StringSource& location_str, T&& value, std::error_code& ec) { add(root, location_str, std::forward(value), false, ec); } template void add(Json& root, const basic_json_pointer& location, T&& value, bool create_if_missing = false) { std::error_code ec; add(root, location, std::forward(value), create_if_missing, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(jsonpointer_error(ec)); } } template typename std::enable_if>::value,void>::type add(Json& root, const StringSource& location_str, T&& value, bool create_if_missing = false) { std::error_code ec; add(root, location_str, std::forward(value), create_if_missing, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(jsonpointer_error(ec)); } } // add_if_absent template void add_if_absent(Json& root, const basic_json_pointer& location, T&& value, bool create_if_missing, std::error_code& ec) { Json* current = std::addressof(root); std::basic_string buffer; auto it = location.begin(); auto end = location.end(); while (it != end) { buffer = *it; ++it; if (it != end) { current = jsoncons::jsonpointer::detail::resolve(current, buffer, create_if_missing, ec); if (JSONCONS_UNLIKELY(ec)) return; } } if (current->is_array()) { if (buffer.size() == 1 && buffer[0] == '-') { current->emplace_back(std::forward(value)); current = std::addressof(current->at(current->size()-1)); } else { std::size_t index{0}; auto result = jsoncons::detail::decimal_to_integer(buffer.data(), buffer.length(), index); if (!result) { ec = jsonpointer_errc::invalid_index; return; } if (index > current->size()) { ec = jsonpointer_errc::index_exceeds_array_size; return; } if (index == current->size()) { current->emplace_back(std::forward(value)); current = std::addressof(current->at(current->size()-1)); } else { auto it2 = current->insert(current->array_range().begin()+index,std::forward(value)); current = std::addressof(*it2); } } } else if (current->is_object()) { if (current->contains(buffer)) { ec = jsonpointer_errc::key_already_exists; return; } else { auto r = current->try_emplace(buffer,std::forward(value)); current = std::addressof(r.first->value()); } } else { ec = jsonpointer_errc::expected_object_or_array; return; } } template typename std::enable_if>::value,void>::type add_if_absent(Json& root, const StringSource& location_str, T&& value, bool create_if_missing, std::error_code& ec) { auto jsonptr = basic_json_pointer::parse(location_str, ec); if (JSONCONS_UNLIKELY(ec)) { return; } add_if_absent(root, jsonptr, std::forward(value), create_if_missing, ec); } template typename std::enable_if>::value,void>::type add_if_absent(Json& root, const StringSource& location, T&& value, std::error_code& ec) { add_if_absent(root, location, std::forward(value), false, ec); } template typename std::enable_if>::value,void>::type add_if_absent(Json& root, const StringSource& location_str, T&& value, bool create_if_missing = false) { std::error_code ec; add_if_absent(root, location_str, std::forward(value), create_if_missing, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(jsonpointer_error(ec)); } } template void add_if_absent(Json& root, const basic_json_pointer& location, T&& value, std::error_code& ec) { add_if_absent(root, location, std::forward(value), false, ec); } template void add_if_absent(Json& root, const basic_json_pointer& location, T&& value, bool create_if_missing = false) { std::error_code ec; add_if_absent(root, location, std::forward(value), create_if_missing, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(jsonpointer_error(ec)); } } // remove template void remove(Json& root, const basic_json_pointer& location, std::error_code& ec) { Json* current = std::addressof(root); std::basic_string buffer; auto it = location.begin(); auto end = location.end(); while (it != end) { buffer = *it; ++it; if (it != end) { current = jsoncons::jsonpointer::detail::resolve(current, buffer, false, ec); if (JSONCONS_UNLIKELY(ec)) return; } } if (current->is_array()) { if (buffer.size() == 1 && buffer[0] == '-') { ec = jsonpointer_errc::index_exceeds_array_size; return; } else { std::size_t index{0}; auto result = jsoncons::detail::decimal_to_integer(buffer.data(), buffer.length(), index); if (!result) { ec = jsonpointer_errc::invalid_index; return; } if (index >= current->size()) { ec = jsonpointer_errc::index_exceeds_array_size; return; } current->erase(current->array_range().begin()+index); } } else if (current->is_object()) { if (!current->contains(buffer)) { ec = jsonpointer_errc::key_not_found; return; } else { current->erase(buffer); } } else { ec = jsonpointer_errc::expected_object_or_array; return; } } template typename std::enable_if>::value,void>::type remove(Json& root, const StringSource& location_str, std::error_code& ec) { auto jsonptr = basic_json_pointer::parse(location_str, ec); if (JSONCONS_UNLIKELY(ec)) { return; } remove(root, jsonptr, ec); } template typename std::enable_if>::value,void>::type remove(Json& root, const StringSource& location_str) { std::error_code ec; remove(root, location_str, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(jsonpointer_error(ec)); } } template void remove(Json& root, const basic_json_pointer& location) { std::error_code ec; remove(root, location, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(jsonpointer_error(ec)); } } // replace template void replace(Json& root, const basic_json_pointer& location, T&& value, bool create_if_missing, std::error_code& ec) { Json* current = std::addressof(root); std::basic_string buffer; auto it = location.begin(); auto end = location.end(); while (it != end) { buffer = *it; ++it; if (it != end) { current = jsoncons::jsonpointer::detail::resolve(current, buffer, create_if_missing, ec); if (JSONCONS_UNLIKELY(ec)) return; } } if (current->is_array()) { if (buffer.size() == 1 && buffer[0] == '-') { ec = jsonpointer_errc::index_exceeds_array_size; return; } else { std::size_t index{}; auto result = jsoncons::detail::decimal_to_integer(buffer.data(), buffer.length(), index); if (!result) { ec = jsonpointer_errc::invalid_index; return; } if (index >= current->size()) { ec = jsonpointer_errc::index_exceeds_array_size; return; } current->at(index) = std::forward(value); } } else if (current->is_object()) { if (!current->contains(buffer)) { if (create_if_missing) { current->try_emplace(buffer,std::forward(value)); } else { ec = jsonpointer_errc::key_not_found; return; } } else { auto r = current->insert_or_assign(buffer,std::forward(value)); current = std::addressof(r.first->value()); } } else { ec = jsonpointer_errc::expected_object_or_array; return; } } template typename std::enable_if>::value,void>::type replace(Json& root, const StringSource& location_str, T&& value, bool create_if_missing, std::error_code& ec) { auto jsonptr = basic_json_pointer::parse(location_str, ec); if (JSONCONS_UNLIKELY(ec)) { return; } replace(root, jsonptr, std::forward(value), create_if_missing, ec); } template typename std::enable_if>::value,void>::type replace(Json& root, const StringSource& location_str, T&& value, std::error_code& ec) { replace(root, location_str, std::forward(value), false, ec); } template typename std::enable_if>::value,void>::type replace(Json& root, const StringSource& location_str, T&& value, bool create_if_missing = false) { std::error_code ec; replace(root, location_str, std::forward(value), create_if_missing, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(jsonpointer_error(ec)); } } template void replace(Json& root, const basic_json_pointer& location, T&& value, std::error_code& ec) { replace(root, location, std::forward(value), false, ec); } template void replace(Json& root, const basic_json_pointer& location, T&& value, bool create_if_missing = false) { std::error_code ec; replace(root, location, std::forward(value), create_if_missing, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(jsonpointer_error(ec)); } } template typename std::enable_if::value>::type escape(const String& s, Result& result) { for (auto c : s) { if (c == '~') { result.push_back('~'); result.push_back('0'); } else if (c == '/') { result.push_back('~'); result.push_back('1'); } else { result.push_back(c); } } } // flatten template void flatten_(const std::basic_string& parent_key, const Json& parent_value, Json& result) { using char_type = typename Json::char_type; using string_type = std::basic_string; switch (parent_value.type()) { case json_type::array_value: { if (parent_value.empty()) { // Flatten empty array to null //result.try_emplace(parent_key, null_type{}); //result[parent_key] = parent_value; result.try_emplace(parent_key, parent_value); } else { for (std::size_t i = 0; i < parent_value.size(); ++i) { string_type key(parent_key); key.push_back('/'); jsoncons::detail::from_integer(i,key); flatten_(key, parent_value.at(i), result); } } break; } case json_type::object_value: { if (parent_value.empty()) { // Flatten empty object to null //result.try_emplace(parent_key, null_type{}); //result[parent_key] = parent_value; result.try_emplace(parent_key, parent_value); } else { for (const auto& item : parent_value.object_range()) { string_type key(parent_key); key.push_back('/'); escape(jsoncons::basic_string_view(item.key().data(),item.key().size()), key); flatten_(key, item.value(), result); } } break; } default: { // add primitive parent_value with its reference string //result[parent_key] = parent_value; result.try_emplace(parent_key, parent_value); break; } } } template Json flatten(const Json& value) { Json result; std::basic_string parent_key; flatten_(parent_key, value, result); return result; } // unflatten enum class unflatten_options {none,assume_object = 1 }; template Json safe_unflatten (Json& value) { if (!value.is_object() || value.empty()) { return value; } bool safe = true; std::size_t index = 0; for (const auto& item : value.object_range()) { std::size_t n; auto r = jsoncons::detail::decimal_to_integer(item.key().data(),item.key().size(), n); if (!r || (index++ != n)) { safe = false; break; } } if (safe) { Json j(json_array_arg); j.reserve(value.size()); for (auto& item : value.object_range()) { j.emplace_back(std::move(item.value())); } Json a(json_array_arg); for (auto& item : j.array_range()) { a.emplace_back(safe_unflatten (item)); } return a; } else { Json o(json_object_arg); for (auto& item : value.object_range()) { o.try_emplace(item.key(), safe_unflatten (item.value())); } return o; } } template jsoncons::optional try_unflatten_array(const Json& value) { using char_type = typename Json::char_type; if (JSONCONS_UNLIKELY(!value.is_object())) { JSONCONS_THROW(jsonpointer_error(jsonpointer_errc::argument_to_unflatten_invalid)); } Json result; for (const auto& item: value.object_range()) { Json* part = &result; basic_json_pointer ptr(item.key()); std::size_t index = 0; for (auto it = ptr.begin(); it != ptr.end(); ) { auto s = *it; std::size_t n{0}; auto r = jsoncons::detail::decimal_to_integer(s.data(), s.size(), n); if (r.ec == jsoncons::detail::to_integer_errc() && (index++ == n)) { if (!part->is_array()) { *part = Json(json_array_arg); } if (++it != ptr.end()) { if (n+1 > part->size()) { Json& ref = part->emplace_back(); part = std::addressof(ref); } else { part = &part->at(n); } } else { Json& ref = part->emplace_back(item.value()); part = std::addressof(ref); } } else if (part->is_object()) { if (++it != ptr.end()) { auto res = part->try_emplace(s,Json()); part = &(res.first->value()); } else { auto res = part->try_emplace(s, item.value()); part = &(res.first->value()); } } else { return jsoncons::optional(); } } } return result; } template Json unflatten_to_object(const Json& value, unflatten_options options = unflatten_options::none) { using char_type = typename Json::char_type; if (JSONCONS_UNLIKELY(!value.is_object())) { JSONCONS_THROW(jsonpointer_error(jsonpointer_errc::argument_to_unflatten_invalid)); } Json result; for (const auto& item: value.object_range()) { Json* part = &result; basic_json_pointer ptr(item.key()); for (auto it = ptr.begin(); it != ptr.end(); ) { auto s = *it; if (++it != ptr.end()) { auto res = part->try_emplace(s,Json()); part = &(res.first->value()); } else { auto res = part->try_emplace(s, item.value()); part = &(res.first->value()); } } } return options == unflatten_options::none ? safe_unflatten (result) : result; } template Json unflatten(const Json& value, unflatten_options options = unflatten_options::none) { if (options == unflatten_options::none) { jsoncons::optional j = try_unflatten_array(value); return j ? *j : unflatten_to_object(value,options); } else { return unflatten_to_object(value,options); } } } // namespace jsonpointer } // namespace jsoncons namespace std { template struct hash> { std::size_t operator()(const jsoncons::jsonpointer::basic_json_pointer& ptr) const noexcept { constexpr std::uint64_t prime{0x100000001B3}; std::uint64_t result{0xcbf29ce484222325}; for (const auto& str : ptr) { for (std::size_t i = 0; i < str.length(); ++i) { result = (result * prime) ^ str[i]; } } return result; } }; } // namespace std #endif jsoncons-1.3.2/include/jsoncons_ext/jsonpointer/jsonpointer_error.hpp000066400000000000000000000070431477700171100263670ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONPOINTER_JSONPOINTER_ERROR_HPP #define JSONCONS_EXT_JSONPOINTER_JSONPOINTER_ERROR_HPP #include #include #include #include namespace jsoncons { namespace jsonpointer { class jsonpointer_error : public std::system_error, public virtual json_exception { public: jsonpointer_error(const std::error_code& ec) : std::system_error(ec) { } jsonpointer_error(const std::error_code& ec, const std::string& what_arg) : std::system_error(ec, what_arg) { } jsonpointer_error(const std::error_code& ec, const char* what_arg) : std::system_error(ec, what_arg) { } jsonpointer_error(const jsonpointer_error& other) = default; jsonpointer_error(jsonpointer_error&& other) = default; const char* what() const noexcept override { return std::system_error::what(); } }; enum class jsonpointer_errc { success = 0, expected_slash = 1, index_exceeds_array_size, expected_0_or_1, invalid_index, key_not_found, key_already_exists, expected_object_or_array, end_of_input, unexpected_end_of_input, argument_to_unflatten_invalid, invalid_flattened_key, invalid_uri_escaped_data }; class jsonpointer_error_category_impl : public std::error_category { public: const char* name() const noexcept override { return "jsoncons/jsonpointer"; } std::string message(int ev) const override { switch (static_cast(ev)) { case jsonpointer_errc::expected_slash: return "Expected /"; case jsonpointer_errc::index_exceeds_array_size: return "Index exceeds array size"; case jsonpointer_errc::expected_0_or_1: return "Expected '0' or '1' after escape character '~'"; case jsonpointer_errc::key_not_found: return "Key not found"; case jsonpointer_errc::invalid_index: return "Invalid array index"; case jsonpointer_errc::key_already_exists: return "Key already exists"; case jsonpointer_errc::expected_object_or_array: return "Expected object or array"; case jsonpointer_errc::end_of_input: return "Unexpected end of input"; case jsonpointer_errc::unexpected_end_of_input: return "Unexpected end of jsonpointer input"; case jsonpointer_errc::argument_to_unflatten_invalid: return "Argument to unflatten must be an object"; case jsonpointer_errc::invalid_flattened_key: return "Flattened key is invalid"; default: return "Unknown jsonpointer error"; } } }; inline const std::error_category& jsonpointer_error_category() { static jsonpointer_error_category_impl instance; return instance; } inline std::error_code make_error_code(jsonpointer_errc result) { return std::error_code(static_cast(result),jsonpointer_error_category()); } } // namespace jsonpointer } // namespace jsoncons namespace std { template<> struct is_error_code_enum : public true_type { }; } // namespace std #endif jsoncons-1.3.2/include/jsoncons_ext/jsonschema/000077500000000000000000000000001477700171100216475ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons_ext/jsonschema/common/000077500000000000000000000000001477700171100231375ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons_ext/jsonschema/common/compilation_context.hpp000066400000000000000000000102401477700171100277270ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_COMMON_COMPILATION_CONTEXT_HPP #define JSONCONS_EXT_JSONSCHEMA_COMMON_COMPILATION_CONTEXT_HPP #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace jsonschema { template class compilation_context { using anchor_uri_map_type = std::unordered_map; using schema_validator_ptr_type = typename std::unique_ptr>; uri_wrapper base_uri_; std::vector uris_; jsoncons::optional id_; std::unordered_map custom_messages_; std::string custom_message_; public: explicit compilation_context(const uri_wrapper& retrieval_uri, const std::unordered_map& custom_messages = std::unordered_map{}) : base_uri_(retrieval_uri), uris_(std::vector{{retrieval_uri}}), custom_messages_{custom_messages} { } explicit compilation_context(const std::vector& uris, const std::unordered_map& custom_messages = std::unordered_map{}) : uris_(uris), custom_messages_{custom_messages} { if (uris_.empty()) { uris_.push_back(uri_wrapper{"#"}); } base_uri_ = uris_.back(); } explicit compilation_context(const std::vector& uris, const jsoncons::optional& id, const std::unordered_map& custom_messages, const std::string& custom_message) : uris_(uris), id_(id), custom_messages_{custom_messages}, custom_message_(custom_message) { if (uris_.empty()) { uris_.push_back(uri_wrapper{"#"}); } base_uri_ = uris_.back(); } std::string get_custom_message(const std::string& message_key) const { if (!custom_message_.empty()) { return custom_message_; } auto it = custom_messages_.find(message_key); return it == custom_messages_.end() ? std::string{} : it->second; } const std::unordered_map& custom_messages() const { return custom_messages_; } const std::vector& uris() const {return uris_;} const jsoncons::optional& id() const { return id_; } uri get_base_uri() const { return base_uri_.uri(); } jsoncons::uri make_schema_location(const std::string& keyword) const { for (auto it = uris_.rbegin(); it != uris_.rend(); ++it) { if (!(*it).has_plain_name_fragment()) { return (*it).append(keyword).uri(); } } return uri{"#"}; } static jsoncons::uri make_random_uri() { std::random_device dev; std::mt19937 gen{ dev() }; std::uniform_int_distribution dist(1, 10000); std::string str = "https:://jsoncons.com/" + std::to_string(dist(gen)); jsoncons::uri uri{str}; return uri; } }; } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_COMPILATION_CONTEXT_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/common/eval_context.hpp000066400000000000000000000121671477700171100263520ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_COMMON_EVAL_CONTEXT_HPP #define JSONCONS_EXT_JSONSCHEMA_COMMON_EVAL_CONTEXT_HPP #include #include #include #include #include #include #include namespace jsoncons { namespace jsonschema { template class schema_validator; enum class evaluation_flags : uint32_t {require_evaluated_properties=1, require_evaluated_items=2}; inline evaluation_flags operator~(evaluation_flags a) { return static_cast(~static_cast(a)); } inline evaluation_flags operator&(evaluation_flags a, evaluation_flags b) { return static_cast(static_cast(a) & static_cast(b)); } inline evaluation_flags operator^(evaluation_flags a, evaluation_flags b) { return static_cast(static_cast(a) ^ static_cast(b)); } inline evaluation_flags operator|(evaluation_flags a, evaluation_flags b) { return static_cast(static_cast(a) | static_cast(b)); } inline evaluation_flags operator&=(evaluation_flags& a, evaluation_flags b) { a = a & b; return a; } inline evaluation_flags operator^=(evaluation_flags& a, evaluation_flags b) { a = a ^ b; return a; } inline evaluation_flags operator|=(evaluation_flags& a, evaluation_flags b) { a = a | b; return a; } template class eval_context { private: std::vector*> dynamic_scope_; jsonpointer::json_pointer eval_path_; evaluation_flags flags_; public: eval_context() : flags_{} { } eval_context(const eval_context& other) : dynamic_scope_ { other.dynamic_scope_}, eval_path_{other.eval_path_}, flags_(other.flags_) { } eval_context(eval_context&& other) noexcept : dynamic_scope_{std::move(other.dynamic_scope_)},eval_path_{std::move(other.eval_path_)}, flags_(other.flags_) { } eval_context(const eval_context& parent, const schema_validator *validator) : dynamic_scope_ { parent.dynamic_scope_ }, eval_path_{ parent.eval_path_ }, flags_(parent.flags_) { if (validator->id() || dynamic_scope_.empty()) { dynamic_scope_.push_back(validator); } } eval_context(const eval_context& parent, const schema_validator *validator, evaluation_flags flags) : dynamic_scope_ { parent.dynamic_scope_ }, eval_path_{ parent.eval_path_ }, flags_(flags) { if (validator->id() || dynamic_scope_.empty()) { dynamic_scope_.push_back(validator); } } eval_context(const eval_context& parent, const std::string& name) : dynamic_scope_{parent.dynamic_scope_}, eval_path_(parent.eval_path() / name), flags_(parent.flags_) { } eval_context(const eval_context& parent, const std::string& name, evaluation_flags flags) : dynamic_scope_{parent.dynamic_scope_}, eval_path_(parent.eval_path() / name), flags_(flags) { } eval_context(const eval_context& parent, std::size_t index) : dynamic_scope_{parent.dynamic_scope_}, eval_path_(parent.eval_path() / index), flags_(parent.flags_) { } eval_context(const eval_context& parent, std::size_t index, evaluation_flags flags) : dynamic_scope_{parent.dynamic_scope_}, eval_path_(parent.eval_path() / index), flags_(flags) { } const std::vector*>& dynamic_scope() const { return dynamic_scope_; } const jsonpointer::json_pointer& eval_path() const { return eval_path_; } evaluation_flags eval_flags() const { return flags_; } bool require_evaluated_properties() const { return (flags_ & evaluation_flags::require_evaluated_properties) == evaluation_flags::require_evaluated_properties; } bool require_evaluated_items() const { return (flags_ & evaluation_flags::require_evaluated_items) == evaluation_flags::require_evaluated_items; } }; } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_COMPILATION_CONTEXT_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/common/format.hpp000066400000000000000000001206221477700171100251430ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_COMMON_FORMAT_HPP #define JSONCONS_EXT_JSONSCHEMA_COMMON_FORMAT_HPP #include #include #include #include #include #include #include #include #include #include #include #include #if defined(JSONCONS_HAS_STD_REGEX) #include #endif namespace jsoncons { namespace jsonschema { inline bool is_digit(char c) { return c >= '0' && c <= '9'; } inline bool is_vchar(char c) { return c >= 0x21 && c <= 0x7E; } inline bool is_alpha(char c) { return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); } inline bool is_atext( char c) { switch (c) { case '!': case '#': case '$': case '%': case '&': case '\'': case '*': case '+': case '-': case '/': case '=': case '?': case '^': case '_': case '`': case '{': case '|': case '}': case '~': return true; default: return is_digit(c) || is_alpha(c); } } inline bool is_dtext( char c) { return (c >= 33 && c <= 90) || (c >= 94 && c <= 126); } // RFC 5322, section 3.4.1 inline bool validate_email_rfc5322(const std::string& s) { enum class state_t {local_part,atom,dot_atom,quoted_string,amp,domain,domain_name,domain_literal,done}; state_t state = state_t::local_part; std::size_t part_length = 0; std::size_t length = s.size(); for (std::size_t i = 0; i < length; ++i) { const char c = s[i]; switch (state) { case state_t::local_part: { if (is_atext(c)) { state = state_t::atom; } else if (c == '"') { state = state_t::quoted_string; } else { return false; } break; } case state_t::dot_atom: { if (is_atext(c)) { ++part_length; state = state_t::atom; } else { return false; } break; } case state_t::atom: { switch (c) { case '@': state = state_t::domain; part_length = 0; break; case '.': state = state_t::dot_atom; ++part_length; break; default: if (is_atext(c)) { ++part_length; } else { return false; } break; } break; } case state_t::quoted_string: { if (c == '\"') { state = state_t::amp; } else { ++part_length; } break; } case state_t::amp: { if (c == '@') { state = state_t::domain; part_length = 0; } else { return false; } break; } case state_t::domain: { if (c == '[') { state = state_t::domain_literal; } else if (is_digit(c) || is_alpha(c)) { state = state_t::domain_name; } else { return false; } break; } case state_t::domain_literal: { if (c == ']') { state = state_t::done; } else if (!is_dtext(c)) { return false; } break; } case state_t::domain_name: { switch (c) { case '.': if (part_length == 0) { return false; } part_length = 0; break; default: { if (is_digit(c) || is_alpha(c) || c == '-') { ++part_length; } else { return false; } } break; } break; } default: break; } } return state == state_t::domain_name || state == state_t::done; } // RFC 2673, Section 3.2 inline bool validate_ipv6_rfc2373(const std::string& s) { enum class state_t{start,expect_hexdig_or_unspecified, hexdig, decdig,expect_unspecified, unspecified}; state_t state = state_t::start; std::size_t digit_count = 0; std::size_t piece_count = 0; std::size_t piece_count2 = 0; bool has_unspecified = false; std::size_t dec_value = 0; for (std::size_t i = 0; i < s.length(); ++i) { const char c = s[i]; switch (state) { case state_t::start: { switch (c) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': case 'A':case 'B':case 'C':case 'D':case 'E':case 'F': case 'a':case 'b':case 'c':case 'd':case 'e':case 'f': state = state_t::hexdig; ++digit_count; piece_count = 0; break; case ':': if (!has_unspecified) { state = state_t::expect_unspecified; } else { return false; } break; default: return false; } break; } case state_t::expect_hexdig_or_unspecified: { switch (c) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': dec_value = dec_value*10 + static_cast(c - '0'); // just in case this piece is followed by a dot state = state_t::hexdig; ++digit_count; break; case 'A':case 'B':case 'C':case 'D':case 'E':case 'F': case 'a':case 'b':case 'c':case 'd':case 'e':case 'f': state = state_t::hexdig; ++digit_count; break; case ':': if (!has_unspecified) { has_unspecified = true; state = state_t::unspecified; } else { return false; } break; default: return false; } break; } case state_t::expect_unspecified: { if (c == ':') { has_unspecified = true; state = state_t::unspecified; } else { return false; } break; } case state_t::hexdig: { switch (c) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': case 'A':case 'B':case 'C':case 'D':case 'E':case 'F': case 'a':case 'b':case 'c':case 'd':case 'e':case 'f': ++digit_count; break; case ':': if (digit_count <= 4) { ++piece_count; digit_count = 0; dec_value = 0; state = state_t::expect_hexdig_or_unspecified; } else { return false; } break; case '.': if (piece_count == 6 || has_unspecified) { ++piece_count2; state = state_t::decdig; dec_value = 0; } else { return false; } break; default: return false; } break; } case state_t::decdig: { switch (c) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': dec_value = dec_value*10 + static_cast(c - '0'); ++digit_count; break; case '.': if (dec_value > 0xff) { return false; } digit_count = 0; dec_value = 0; ++piece_count2; break; default: return false; } break; } case state_t::unspecified: { switch (c) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': case 'A':case 'B':case 'C':case 'D':case 'E':case 'F': case 'a':case 'b':case 'c':case 'd':case 'e':case 'f': state = state_t::hexdig; ++digit_count; break; default: return false; } break; } default: return false; } } switch (state) { case state_t::unspecified: return piece_count <= 8; case state_t::hexdig: if (digit_count <= 4) { ++piece_count; return digit_count > 0 && (piece_count == 8 || (has_unspecified && piece_count <= 8)); } else { return false; } case state_t::decdig: ++piece_count2; if (dec_value > 0xff) { return false; } return digit_count > 0 && piece_count2 == 4; default: return false; } } // RFC 2673, Section 3.2 inline bool validate_ipv4_rfc2673(const std::string& s) { enum class state_t {expect_indicator_or_dotted_quad,decbyte, bindig, octdig, hexdig}; state_t state = state_t::expect_indicator_or_dotted_quad; std::size_t digit_count = 0; std::size_t decbyte_count = 0; std::size_t value = 0; for (std::size_t i = 0; i < s.length(); ++i) { const char c = s[i]; switch (state) { case state_t::expect_indicator_or_dotted_quad: { switch (c) { case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': state = state_t::decbyte; decbyte_count = 0; digit_count = 1; value = 0; break; case 'b': state = state_t::bindig; digit_count = 0; break; case '0': state = state_t::octdig; digit_count = 0; break; case 'x': state = state_t::hexdig; digit_count = 0; break; default: return false; } break; } case state_t::bindig: { if (digit_count >= 256) { return false; } switch (c) { case '0':case '1': ++digit_count; break; default: return false; } break; } case state_t::octdig: { if (digit_count >= 86) { return false; } switch (c) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7': ++digit_count; break; default: return false; } break; } case state_t::hexdig: { if (digit_count >= 64) { return false; } switch (c) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': case 'A':case 'B':case 'C':case 'D':case 'E':case 'F': case 'a':case 'b':case 'c':case 'd':case 'e':case 'f': ++digit_count; break; default: return false; } break; } case state_t::decbyte: { if (decbyte_count >= 4) { return false; } switch (c) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': { if (digit_count >= 3) { return false; } ++digit_count; value = value*10 + static_cast(c - '0'); if (value > 255) { return false; } break; } case '.': if (decbyte_count > 3) { return false; } ++decbyte_count; digit_count = 0; value = 0; break; default: return false; } break; } default: return false; } } switch (state) { case state_t::decbyte: if (digit_count > 0) { ++decbyte_count; } else { return false; } return (decbyte_count == 4) ? true : false; case state_t::bindig: return digit_count > 0 ? true : false; case state_t::octdig: return digit_count > 0 ? true : false; case state_t::hexdig: return digit_count > 0 ? true : false; default: return false; } } // RFC 1034, Section 3.1 inline bool validate_hostname_rfc1034(const std::string& hostname) { enum class state_t {start_label,expect_letter_or_digit_or_hyphen_or_dot}; state_t state = state_t::start_label; std::size_t length = hostname.length() - 1; std::size_t label_length = 0; for (std::size_t i = 0; i < length; ++i) { const char c = hostname[i]; switch (state) { case state_t::start_label: { if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { ++label_length; state = state_t::expect_letter_or_digit_or_hyphen_or_dot; } else { return false; } break; } case state_t::expect_letter_or_digit_or_hyphen_or_dot: { if (c == '.') { label_length = 0; state = state_t::start_label; } else if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c < '9') || c == '-')) { return false; } if (++label_length > 63) { return false; } break; } } } char last = hostname.back(); if (!((last >= 'a' && last <= 'z') || (last >= 'A' && last <= 'Z') || (last >= '0' && last < '9'))) { return false; } return true; } inline bool is_leap_year(std::size_t year) { return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); } inline std::size_t days_in_month(std::size_t year, std::size_t month) { switch (month) { case 1: return 31; case 2: return is_leap_year(year) ? 29 : 28; case 3: return 31; case 4: return 30; case 5: return 31; case 6: return 30; case 7: return 31; case 8: return 31; case 9: return 30; case 10: return 31; case 11: return 30; case 12: return 31; default: JSONCONS_UNREACHABLE(); break; } } enum class date_time_type {date_time,date,time}; // RFC 3339, Section 5.6 inline bool validate_date_time_rfc3339(const std::string& s, date_time_type type) { enum class state_t {fullyear,month,mday,hour,minute,second,secfrac,z,offset_hour,offset_minute}; std::size_t piece_length = 0; std::size_t year = 0; std::size_t month = 0; std::size_t mday = 0; int hour = 0; int minute = 0; int second = 0; int secfrac = 0; int offset_signum = 0; int offset_hour = 0; int offset_minute = 0; state_t state = (type == date_time_type::time) ? state_t::hour : state_t::fullyear; for (const char c : s) { switch (state) { case state_t::fullyear: { if (piece_length < 4 && (c >= '0' && c <= '9')) { piece_length++; year = year*10 + static_cast(c - '0'); } else if (c == '-' && piece_length == 4) { state = state_t::month; piece_length = 0; } else { return false; } break; } case state_t::month: { if (piece_length < 2 && (c >= '0' && c <= '9')) { piece_length++; month = month*10 + static_cast(c - '0'); } else if (c == '-' && piece_length == 2 && (month >=1 && month <= 12)) { state = state_t::mday; piece_length = 0; } else { return false; } break; } case state_t::mday: { if (piece_length < 2 && (c >= '0' && c <= '9')) { piece_length++; mday = mday *10 + static_cast(c - '0'); } else if ((c == 'T' || c == 't') && piece_length == 2 && (mday <= days_in_month(year, month))) { piece_length = 0; state = state_t::hour; } else { return false; } break; } case state_t::hour: { if (piece_length < 2 && (c >= '0' && c <= '9')) { piece_length++; hour = hour*10 + static_cast(c - '0'); } else if (c == ':' && piece_length == 2 && (/*hour >=0 && */ hour <= 23)) { state = state_t::minute; piece_length = 0; } else { return false; } break; } case state_t::minute: { if (piece_length < 2 && (c >= '0' && c <= '9')) { piece_length++; minute = minute*10 + static_cast(c - '0'); } else if (c == ':' && piece_length == 2 && (/*minute >=0 && */minute <= 59)) { state = state_t::second; piece_length = 0; } else { return false; } break; } case state_t::second: { if (piece_length < 2 && (c >= '0' && c <= '9')) { piece_length++; second = second*10 + static_cast(c - '0'); } else if (piece_length == 2 && second <= 60) // 00-58, 00-59, 00-60 based on leap second rules { switch (c) { case '.': state = state_t::secfrac; break; case '+': offset_signum = 1; piece_length = 0; state = state_t::offset_hour; break; case '-': offset_signum = -1; piece_length = 0; state = state_t::offset_hour; break; case 'Z': case 'z': state = state_t::z; break; default: return false; } } break; } case state_t::secfrac: { if (c >= '0' && c <= '9') { secfrac = secfrac*10 + static_cast(c - '0'); } else { switch (c) { case '+': offset_signum = 1; piece_length = 0; state = state_t::offset_hour; break; case '-': offset_signum = -1; piece_length = 0; state = state_t::offset_hour; break; case 'Z': case 'z': state = state_t::z; break; default: return false; } } break; } case state_t::offset_hour: { if (piece_length < 2 && (c >= '0' && c <= '9')) { piece_length++; offset_hour = offset_hour*10 + static_cast(c - '0'); } else if (c == ':' && piece_length == 2 && (/*offset_hour >=0 && */offset_hour <= 23)) { piece_length = 0; state = state_t::offset_minute; } else { return false; } break; } case state_t::offset_minute: { if (piece_length < 2 && (c >= '0' && c <= '9')) { piece_length++; offset_minute = offset_minute*10 + static_cast(c - '0'); } else if (c == ':' && piece_length == 2 && (/*offset_minute >=0 && */offset_minute <= 59)) { piece_length = 0; } else { return false; } break; } case state_t::z: return false; // Nothing follows z default: return false; } } switch (state) { case state_t::hour: case state_t::minute: case state_t::second: case state_t::secfrac: return false; default: break; } if (offset_hour < 0 || offset_hour > 23) { return false; } if (offset_minute < 0 || offset_minute > 59) { return false; } if (offset_signum == -1) { offset_hour = -offset_hour; offset_minute = -offset_minute; } auto day_minutes = hour * 60 + minute - (offset_hour * 60 + offset_minute); if (day_minutes < 0) { day_minutes += 60 * 24; } hour = day_minutes % 24; minute = day_minutes / 24; if (hour == 23 && minute == 59) { if (second < 0 || second > 60) { return false; } } else { if (second < 0 || second > 59) { return false; } } if (type == date_time_type::date) { return state == state_t::mday && piece_length == 2 && (mday >= 1 && mday <= days_in_month(year, month)); } return state == state_t::offset_minute || state == state_t::z || state == state_t::secfrac; } // format checkers using validate_format = std::function; inline walk_result uri_check(const validation_message_factory& message_factory, const jsonpointer::json_pointer& eval_path, const jsonpointer::json_pointer& instance_location, const std::string& str, error_reporter& reporter) { std::error_code ec; auto u = uri::parse(str, ec); if (JSONCONS_UNLIKELY(ec)) { walk_result result = reporter.error(message_factory.make_validation_message( eval_path, instance_location, "'" + str + "': " + ec.message())); if (result == walk_result::abort) { return result; } } else if (!u.is_absolute()) { walk_result result = reporter.error(message_factory.make_validation_message( eval_path, instance_location, "'" + str + "' is not an absolute URI.")); if (result == walk_result::abort) { return result; } } return walk_result::advance; } inline walk_result uri_reference_check(const validation_message_factory& message_factory, const jsonpointer::json_pointer& eval_path, const jsonpointer::json_pointer& instance_location, const std::string& str, error_reporter& reporter) { std::error_code ec; auto u = uri::parse(str, ec); if (JSONCONS_UNLIKELY(ec)) { walk_result result = reporter.error(message_factory.make_validation_message( eval_path, instance_location, "'" + str + "': " + ec.message())); if (result == walk_result::abort) { return result; } } return walk_result::advance; } inline walk_result jsonpointer_check(const validation_message_factory& message_factory, const jsonpointer::json_pointer& eval_path, const jsonpointer::json_pointer& instance_location, const std::string& str, error_reporter& reporter) { std::error_code ec; jsonpointer::json_pointer::parse(str, ec); if (JSONCONS_UNLIKELY(ec)) { walk_result result = reporter.error(message_factory.make_validation_message( eval_path, instance_location, "'" + str + "' is not a valid JSONPointer.")); if (result == walk_result::abort) { return result; } } return walk_result::advance; } inline walk_result rfc3339_date_check(const validation_message_factory& message_factory, const jsonpointer::json_pointer& eval_path, const jsonpointer::json_pointer& instance_location, const std::string& value, error_reporter& reporter) { if (!validate_date_time_rfc3339(value,date_time_type::date)) { walk_result result = reporter.error(message_factory.make_validation_message( eval_path, instance_location, "'" + value + "' is not a RFC 3339 date string.")); if (result == walk_result::abort) { return result; } } return walk_result::advance; } inline walk_result rfc3339_time_check(const validation_message_factory& message_factory, const jsonpointer::json_pointer& eval_path, const jsonpointer::json_pointer& instance_location, const std::string &value, error_reporter& reporter) { if (!validate_date_time_rfc3339(value, date_time_type::time)) { walk_result result = reporter.error(message_factory.make_validation_message( eval_path, instance_location, "'" + value + "' is not a RFC 3339 time string.")); if (result == walk_result::abort) { return result; } } return walk_result::advance; } inline walk_result rfc3339_date_time_check(const validation_message_factory& message_factory, const jsonpointer::json_pointer& eval_path, const jsonpointer::json_pointer& instance_location, const std::string &value, error_reporter& reporter) { if (!validate_date_time_rfc3339(value, date_time_type::date_time)) { walk_result result = reporter.error(message_factory.make_validation_message( eval_path, instance_location, "'" + value + "' is not a RFC 3339 date-time string.")); if (result == walk_result::abort) { return result; } } return walk_result::advance; } inline walk_result email_check(const validation_message_factory& message_factory, const jsonpointer::json_pointer& eval_path, const jsonpointer::json_pointer& instance_location, const std::string& value, error_reporter& reporter) { if (!validate_email_rfc5322(value)) { walk_result result = reporter.error(message_factory.make_validation_message( eval_path, instance_location, "'" + value + "' is not a valid email address as defined by RFC 5322.")); if (result == walk_result::abort) { return result; } } return walk_result::advance; } inline walk_result hostname_check(const validation_message_factory& message_factory, const jsonpointer::json_pointer& eval_path, const jsonpointer::json_pointer& instance_location, const std::string& value, error_reporter& reporter) { if (!validate_hostname_rfc1034(value)) { walk_result result = reporter.error(message_factory.make_validation_message( eval_path, instance_location, "'" + value + "' is not a valid hostname as defined by RFC 3986 Appendix A.")); if (result == walk_result::abort) { return result; } } return walk_result::advance; } inline walk_result ipv4_check(const validation_message_factory& message_factory, const jsonpointer::json_pointer& eval_path, const jsonpointer::json_pointer& instance_location, const std::string& value, error_reporter& reporter) { if (!validate_ipv4_rfc2673(value)) { walk_result result = reporter.error(message_factory.make_validation_message( eval_path, instance_location, "'" + value + "' is not a valid IPv4 address as defined by RFC 2673.")); if (result == walk_result::abort) { return result; } } return walk_result::advance; } inline walk_result ipv6_check(const validation_message_factory& message_factory, const jsonpointer::json_pointer& eval_path, const jsonpointer::json_pointer& instance_location, const std::string& value, error_reporter& reporter) { if (!validate_ipv6_rfc2373(value)) { walk_result result = reporter.error(message_factory.make_validation_message( eval_path, instance_location, "'" + value + "' is not a valid IPv6 address as defined by RFC 2373.")); if (result == walk_result::abort) { return result; } } return walk_result::advance; } inline walk_result regex_check(const validation_message_factory& message_factory, const jsonpointer::json_pointer& eval_path, const jsonpointer::json_pointer& instance_location, const std::string& value, error_reporter& reporter) { #if defined(JSONCONS_HAS_STD_REGEX) try { std::regex re(value, std::regex::ECMAScript); } catch (const std::exception& e) { walk_result result = reporter.error(message_factory.make_validation_message( eval_path, instance_location, "'" + value + "' is not a valid ECMAScript regular expression. " + e.what())); if (result == walk_result::abort) { return result; } } #endif return walk_result::advance; } } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_FORMAT_VALIDATOR_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/common/keyword_validator.hpp000066400000000000000000005063511477700171100274130ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_COMMON_KEYWORD_VALIDATOR_HPP #define JSONCONS_EXT_JSONSCHEMA_COMMON_KEYWORD_VALIDATOR_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(JSONCONS_HAS_STD_REGEX) #include #endif namespace jsoncons { namespace jsonschema { template class schema_validator; template class ref { public: virtual ~ref() = default; virtual void set_referred_schema(const schema_validator* target) = 0; }; template class keyword_base : public validation_message_factory { using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::string keyword_name_; const Json* schema_ptr_; uri schema_location_; std::string custom_message_; public: keyword_base(const std::string& keyword_name, const Json& schema, const uri& schema_location, const std::string& custom_message) : keyword_name_(keyword_name), schema_ptr_(std::addressof(schema)), schema_location_(schema_location), custom_message_(custom_message) { } virtual ~keyword_base() = default; keyword_base(const keyword_base&) = delete; keyword_base(keyword_base&&) = default; keyword_base& operator=(const keyword_base&) = delete; keyword_base& operator=(keyword_base&&) = default; const std::string& keyword_name() const { return keyword_name_; } const Json& schema() const { return *schema_ptr_; } const uri& schema_location() const { return schema_location_; } validation_message make_validation_message(const jsonpointer::json_pointer& eval_path, const jsonpointer::json_pointer& instance_location, const std::string& message) const override { return validation_message(keyword_name_, eval_path, schema_location_, instance_location, custom_message_.empty() ? message : custom_message_); } validation_message make_validation_message(const jsonpointer::json_pointer& eval_path, const jsonpointer::json_pointer& instance_location, const std::string& message, const std::vector& details) const override { return validation_message(keyword_name_, eval_path, schema_location_, instance_location, custom_message_.empty() ? message : custom_message_, details); } }; template class keyword_validator : public keyword_base, public virtual validator_base { public: using keyword_validator_ptr_type = std::unique_ptr>; keyword_validator(const std::string& keyword_name, const Json& schema, const uri& schema_location, const std::string& custom_message) : keyword_base(keyword_name, schema, schema_location, custom_message) { } keyword_validator(const keyword_validator&) = delete; keyword_validator(keyword_validator&&) = default; keyword_validator& operator=(const keyword_validator&) = delete; keyword_validator& operator=(keyword_validator&&) = default; bool always_fails() const override { return false; } bool always_succeeds() const override { return false; } const uri& schema_location() const override { return keyword_base::schema_location(); } }; template class ref_validator : public keyword_validator, public virtual ref { using keyword_validator_ptr_type = std::unique_ptr>; using schema_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; const schema_validator* referred_schema_; public: ref_validator(const Json& schema, const ref_validator& other) : keyword_validator(other.keyword_name(), schema, other.schema_location()), referred_schema_{other.referred_schema_} { } ref_validator(const Json& schema, const uri& schema_location, const std::string& custom_message = std::string{}) : keyword_validator("$ref", schema, schema_location, custom_message), referred_schema_{nullptr} { //std::cout << "ref_validator: " << this->schema_location().string() << "\n"; } ref_validator(const Json& schema, const uri& schema_location, const schema_validator* referred_schema, const std::string& custom_message = std::string{}) : keyword_validator("$ref", schema, schema_location, custom_message), referred_schema_(referred_schema) { //std::cout << "ref_validator2: " << this->schema_location().string() << "\n"; } const schema_validator* referred_schema() const {return referred_schema_;} void set_referred_schema(const schema_validator* target) final { referred_schema_ = target; } uri get_base_uri() const { return this->schema_location(); } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const final { eval_context this_context(context, this->keyword_name()); if (!referred_schema_) { return reporter.error(validation_message(this->keyword_name(), this_context.eval_path(), this->schema_location(), instance_location, "Unresolved schema reference " + this->schema_location().string())); } return referred_schema_->validate(this_context, instance, instance_location, results, reporter, patch); } walk_result do_walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { if (!referred_schema_) { return walk_result::advance; } eval_context this_context(context, this->keyword_name()); return referred_schema_->walk(this_context, instance, instance_location, reporter); } }; template class recursive_ref_validator : public keyword_validator, public virtual ref { using keyword_validator_ptr_type = std::unique_ptr>; using schema_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; const schema_validator *tentative_target_{nullptr}; public: recursive_ref_validator(const Json& schema, const uri& schema_location, const std::string& custom_message) : keyword_validator("$recursiveRef", schema, schema_location, custom_message) {} uri get_base_uri() const { return this->schema_location(); } void set_referred_schema(const schema_validator* target) final { tentative_target_ = target; } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const final { auto rit = context.dynamic_scope().rbegin(); auto rend = context.dynamic_scope().rend(); const schema_validator* schema_ptr = tentative_target_; JSONCONS_ASSERT(schema_ptr != nullptr); if (schema_ptr->recursive_anchor()) { while (rit != rend) { if ((*rit)->recursive_anchor()) { schema_ptr = *rit; } ++rit; } } eval_context this_context(context, this->keyword_name()); if (schema_ptr == nullptr) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, "Unresolved schema reference " + this->schema_location().string())); return result; } return schema_ptr->validate(this_context, instance, instance_location, results, reporter, patch); } walk_result do_walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { auto rit = context.dynamic_scope().rbegin(); auto rend = context.dynamic_scope().rend(); const schema_validator* schema_ptr = tentative_target_; JSONCONS_ASSERT(schema_ptr != nullptr); if (schema_ptr->recursive_anchor()) { while (rit != rend) { if ((*rit)->recursive_anchor()) { schema_ptr = *rit; } ++rit; } } //std::cout << "recursive_ref_validator.do_validate " << "keywordLocation: << " << this->schema_location().string() << ", instanceLocation:" << instance_location.string() << "\n"; if (schema_ptr == nullptr) { return walk_result::advance; } eval_context this_context(context, this->keyword_name()); return schema_ptr->walk(this_context, instance, instance_location, reporter); } }; template class dynamic_ref_validator : public keyword_validator, public virtual ref { using keyword_validator_ptr_type = std::unique_ptr>; using schema_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; uri_wrapper value_; const schema_validator* tentative_target_{nullptr}; public: dynamic_ref_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, const uri_wrapper& value) : keyword_validator("$dynamicRef", schema, schema_location, custom_message), value_(value) { //std::cout << "dynamic_ref_validator path: " << schema_location.string() << ", value: " << value.string() << "\n"; } void set_referred_schema(const schema_validator* target) final { tentative_target_ = target; } const jsoncons::uri& value() const { return value_.uri(); } uri get_base_uri() const { return this->schema_location(); } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const final { //std::cout << "dynamic_ref_validator [" << context.eval_path().string() << "," << this->schema_location().string() << "]"; //std::cout << "results:\n"; //for (const auto& s : results) //{ // std::cout << " " << s << "\n"; //} //std::cout << "\n"; auto rit = context.dynamic_scope().rbegin(); auto rend = context.dynamic_scope().rend(); //std::cout << "dynamic_ref_validator::do_validate " << this->value().string() << "\n"; const schema_validator *schema_ptr = tentative_target_; JSONCONS_ASSERT(schema_ptr != nullptr); if (value_.has_plain_name_fragment() && schema_ptr->dynamic_anchor()) { while (rit != rend) { auto p = (*rit)->get_schema_for_dynamic_anchor(schema_ptr->dynamic_anchor()->fragment()); //std::cout << " (2) [" << (*rit)->schema_location().string() << "] " << ((*rit)->dynamic_anchor() ? (*rit)->dynamic_anchor()->value().string() : "") << "\n"; if (p != nullptr) { //std::cout << "Match found " << p->schema_location().string() << "\n"; schema_ptr = p; } ++rit; } } //assert(schema_ptr != tentative_target_); //std::cout << "dynamic_ref_validator.do_validate " << "keywordLocation: << " << this->schema_location().string() << ", instanceLocation:" << instance_location.string() << "\n"; eval_context this_context(context, this->keyword_name()); return schema_ptr->validate(this_context, instance, instance_location, results, reporter, patch); } walk_result do_walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { auto rit = context.dynamic_scope().rbegin(); auto rend = context.dynamic_scope().rend(); const schema_validator *schema_ptr = tentative_target_; JSONCONS_ASSERT(schema_ptr != nullptr); if (value_.has_plain_name_fragment() && schema_ptr->dynamic_anchor()) { while (rit != rend) { auto p = (*rit)->get_schema_for_dynamic_anchor(schema_ptr->dynamic_anchor()->fragment()); if (p != nullptr) { schema_ptr = p; } ++rit; } } eval_context this_context(context, this->keyword_name()); return schema_ptr->walk(this_context, instance, instance_location, reporter); } }; // contentEncoding template class content_encoding_validator : public keyword_validator { using keyword_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::string content_encoding_; public: content_encoding_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, const std::string& content_encoding) : keyword_validator("contentEncoding", schema, schema_location, custom_message), content_encoding_(content_encoding) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& /*results*/, error_reporter& reporter, Json& /*patch*/) const final { if (!instance.is_string()) { return walk_result::advance; } eval_context this_context(context, this->keyword_name()); if (content_encoding_ == "base64") { auto s = instance.template as(); std::string content; auto retval = jsoncons::decode_base64(s.begin(), s.end(), content); if (retval.ec != jsoncons::conv_errc::success) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, "Content is not a base64 string")); if (result == walk_result::abort) { return result; } } } else if (!content_encoding_.empty()) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, "unable to check for contentEncoding '" + content_encoding_ + "'")); if (result == walk_result::abort) { return result; } } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; // contentMediaType template class content_media_type_validator : public keyword_validator { using keyword_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::string content_media_type_; std::string content_encoding_; public: content_media_type_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, const std::string& content_media_type, const std::string& content_encoding) : keyword_validator("contentMediaType", schema, schema_location, custom_message), content_media_type_(content_media_type), content_encoding_(content_encoding) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& /*results*/, error_reporter& reporter, Json& /*patch*/) const final { if (!instance.is_string()) { return walk_result::advance; } std::string str = instance.as_string(); if (content_encoding_ == "base64") { std::string content; auto retval = jsoncons::decode_base64(str.begin(), str.end(), content); if (retval.ec != jsoncons::conv_errc::success) { return walk_result::advance; } str = std::move(content); } eval_context this_context(context, this->keyword_name()); if (content_media_type_ == "application/json") { json_string_reader reader(str); std::error_code ec; reader.read(ec); if (JSONCONS_UNLIKELY(ec)) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, std::string("Content is not JSON: ") + ec.message())); if (result == walk_result::abort) { return result; } } } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; // format template class format_validator : public keyword_validator { using keyword_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; validate_format validate_; public: format_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, const validate_format& validate) : keyword_validator("format", schema, schema_location, custom_message), validate_(validate) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& /*results*/, error_reporter& reporter, Json& /*patch*/) const final { if (!instance.is_string()) { return walk_result::advance; } if (validate_ != nullptr) { eval_context this_context(context, this->keyword_name()); auto s = instance.template as(); walk_result result = validate_(*this, this_context.eval_path(), instance_location, s, reporter); if (result == walk_result::abort) { return result; } } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; // pattern #if defined(JSONCONS_HAS_STD_REGEX) template class pattern_validator : public keyword_validator { using keyword_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::string pattern_string_; std::regex regex_; public: pattern_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, const std::string& pattern_string, const std::regex& regex) : keyword_validator("pattern", schema, schema_location, custom_message), pattern_string_(pattern_string), regex_(regex) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& /*results*/, error_reporter& reporter, Json& /*patch*/) const final { if (!instance.is_string()) { return walk_result::advance; } eval_context this_context(context, this->keyword_name()); auto s = instance.template as(); if (!std::regex_search(s, regex_)) { std::string message("String '"); message.append(s); message.append("' does not match pattern '"); message.append(pattern_string_); message.append("'."); walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, std::move(message))); if (result == walk_result::abort) { return result; } } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; #else template class pattern_validator : public keyword_validator { using keyword_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; public: pattern_validator(const Json& schema, const uri& schema_location, const std::string& custom_message) : keyword_validator("pattern", schema, schema_location, custom_message) { } private: walk_result do_validate(const Json&, const jsonpointer::json_pointer&, evaluation_results& /*results*/, error_reporter&, Json& /*patch*/) const final { return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; #endif // maxLength template class max_length_validator : public keyword_validator { using keyword_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::size_t max_length_{0}; public: max_length_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, std::size_t max_length) : keyword_validator("maxLength", schema, schema_location, custom_message), max_length_(max_length) { } ~max_length_validator() = default; private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& /*results*/, error_reporter& reporter, Json& /*patch*/) const final { if (!instance.is_string()) { return walk_result::advance; } eval_context this_context(context, this->keyword_name()); auto sv = instance.as_string_view(); std::size_t length = unicode_traits::count_codepoints(sv.data(), sv.size()); if (length > max_length_) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, std::string("Number of characters must be at most ") + std::to_string(max_length_))); if (result == walk_result::abort) { return result; } } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; // minLength template class min_length_validator : public keyword_validator { using keyword_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::size_t min_length_; public: min_length_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, std::size_t min_length) : keyword_validator("minLength", schema, schema_location, custom_message), min_length_(min_length) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& /*results*/, error_reporter& reporter, Json& /*patch*/) const final { if (!instance.is_string()) { return walk_result::advance; } eval_context this_context(context, this->keyword_name()); auto sv = instance.as_string_view(); std::size_t length = unicode_traits::count_codepoints(sv.data(), sv.size()); if (length < min_length_) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, std::string("Number of characters must be at least ") + std::to_string(min_length_))); if (result == walk_result::abort) { return result; } } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; // maxItems template class max_items_validator : public keyword_validator { using keyword_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::size_t max_items_; public: max_items_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, std::size_t max_items) : keyword_validator("maxItems", schema, schema_location, custom_message), max_items_(max_items) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& /*results*/, error_reporter& reporter, Json& /*patch*/) const final { if (!instance.is_array()) { return walk_result::advance; } eval_context this_context(context, this->keyword_name()); if (instance.size() > max_items_) { std::string message("Maximum number of items is " + std::to_string(max_items_)); message.append(" but found " + std::to_string(instance.size())); walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, std::move(message))); if (result == walk_result::abort) { return result; } } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; // minItems template class min_items_validator : public keyword_validator { using keyword_validator_ptr_type = typename keyword_validator::keyword_validator_ptr_type; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::size_t min_items_; public: min_items_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, std::size_t min_items) : keyword_validator("minItems", schema, schema_location, custom_message), min_items_(min_items) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& /*results*/, error_reporter& reporter, Json& /*patch*/) const final { if (!instance.is_array()) { return walk_result::advance; } eval_context this_context(context, this->keyword_name()); if (instance.size() < min_items_) { std::string message("Minimum number of items is " + std::to_string(min_items_)); message.append(" but found " + std::to_string(instance.size())); walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, std::move(message))); if (result == walk_result::abort) { return result; } } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; // items template class items_validator : public keyword_validator { using keyword_validator_ptr_type = typename keyword_validator::keyword_validator_ptr_type; using schema_validator_ptr_type = typename schema_validator::schema_validator_ptr_type; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; schema_validator_ptr_type schema_val_; public: items_validator(const std::string& keyword_name, const Json& schema, const uri& schema_location, const std::string& custom_message, schema_validator_ptr_type&& schema_val) : keyword_validator(keyword_name, schema, schema_location, custom_message), schema_val_(std::move(schema_val)) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const final { if (!instance.is_array()) { return walk_result::advance; } eval_context this_context(context, this->keyword_name()); if (instance.size() > 0 && schema_val_) { if (schema_val_->always_fails()) { jsonpointer::json_pointer item_location = instance_location / 0; walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), item_location, "Item at index '0' but the schema does not allow any items.")); return result; } else if (schema_val_->always_succeeds()) { if (context.require_evaluated_items()) { results.evaluated_items.insert(range{0,instance.size()}); } } else { std::size_t index = 0; std::size_t start = 0; std::size_t end = 0; for (const auto& item : instance.array_range()) { jsonpointer::json_pointer item_location = instance_location / index; std::size_t errors = reporter.error_count(); walk_result result = schema_val_->validate(this_context, item, item_location, results, reporter, patch); if (result == walk_result::abort) { return result; } if (errors == reporter.error_count()) { if (context.require_evaluated_items()) { if (end == start) { start = end = index; } ++end; } } else { if (start < end) { results.evaluated_items.insert(range{start, end}); start = end; } } ++index; } if (start < end) { results.evaluated_items.insert(range{start, end}); start = end; } } } return walk_result::advance; } walk_result do_walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { if (!instance.is_array()) { return walk_result::advance; } walk_result result = reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); if (result == walk_result::abort) { return result; } if (schema_val_) { std::size_t index = 0; for (const auto& item : instance.array_range()) { jsonpointer::json_pointer item_location = instance_location / index; result = schema_val_->walk(context, item, item_location, reporter); if (result == walk_result::abort) { return result; } ++index; } } return walk_result::advance; } }; // items // uniqueItems template class unique_items_validator : public keyword_validator { using keyword_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; bool are_unique_; public: unique_items_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, bool are_unique) : keyword_validator("uniqueItems", schema, schema_location, custom_message), are_unique_(are_unique) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& /*results*/, error_reporter& reporter, Json& /*patch*/) const final { if (!instance.is_array()) { return walk_result::advance; } eval_context this_context(context, this->keyword_name()); if (are_unique_ && !array_has_unique_items(instance)) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, "Array items are not unique")); if (result == walk_result::abort) { return result; } } return walk_result::advance; } static bool array_has_unique_items(const Json& a) { for (auto it = a.array_range().begin(); it != a.array_range().end(); ++it) { for (auto jt = it+1; jt != a.array_range().end(); ++jt) { if (*it == *jt) { return false; // contains duplicates } } } return true; // elements are unique } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; // not template class not_validator : public keyword_validator { using keyword_validator_ptr_type = typename keyword_validator::keyword_validator_ptr_type; using schema_validator_ptr_type = typename schema_validator::schema_validator_ptr_type; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; schema_validator_ptr_type schema_val_; public: not_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, schema_validator_ptr_type&& schema_val) : keyword_validator("not", schema, schema_location, custom_message), schema_val_(std::move(schema_val)) { } bool always_fails() const final { return schema_val_ ? schema_val_->always_succeeds() : false;; } bool always_succeeds() const final { return schema_val_ ? schema_val_->always_fails() : false;; } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const final { eval_context this_context(context, this->keyword_name()); evaluation_results local_results; collecting_error_listener local_reporter; walk_result result = schema_val_->validate(this_context, instance, instance_location, local_results, local_reporter, patch); if (result == walk_result::abort) { return result; } if (local_reporter.errors.empty()) { result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, "Instance must not be valid against schema")); if (result == walk_result::abort) { return result; } } else { results.merge(local_results); } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; template class any_of_validator : public keyword_validator { using keyword_validator_ptr_type = typename keyword_validator::keyword_validator_ptr_type; using schema_validator_ptr_type = typename schema_validator::schema_validator_ptr_type; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::vector validators_; public: any_of_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, std::vector&& validators) : keyword_validator("anyOf", schema, schema_location, custom_message), validators_(std::move(validators)) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const final { //std::cout << "any_of_validator.do_validate " << context.eval_path().string() << ", " << instance << "\n"; collecting_error_listener local_reporter; eval_context this_context(context, this->keyword_name()); evaluation_results local_results1; std::size_t count = 0; for (std::size_t i = 0; i < validators_.size(); ++i) { evaluation_results local_results2; eval_context item_context(this_context, i); std::size_t errors = local_reporter.errors.size(); walk_result result = validators_[i]->validate(item_context, instance, instance_location, local_results2, local_reporter, patch); if (result == walk_result::abort) { return result; } if (errors == local_reporter.errors.size()) { local_results1.merge(local_results2); ++count; } //std::cout << "success: " << i << " " << success << "\n"; } if (count > 0) { results.merge(local_results1); } else { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, "Must be valid against at least one schema, but found no matching schemas", local_reporter.errors)); if (result == walk_result::abort) { return result; } } return walk_result::advance; } walk_result do_walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { walk_result result = reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); if (result == walk_result::abort) { return result; } eval_context this_context(context, this->keyword_name()); for (std::size_t i = 0; i < validators_.size(); ++i) { eval_context item_context(this_context, i); result = validators_[i]->walk(item_context, instance, instance_location, reporter); if (result == walk_result::abort) { return result; } } return walk_result::advance; } }; template class one_of_validator : public keyword_validator { using keyword_validator_ptr_type = typename keyword_validator::keyword_validator_ptr_type; using schema_validator_ptr_type = typename schema_validator::schema_validator_ptr_type; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::vector validators_; public: one_of_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, std::vector&& validators) : keyword_validator("oneOf", schema, schema_location, custom_message), validators_(std::move(validators)) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const final { //std::cout << "any_of_validator.do_validate " << context.eval_path().string() << ", " << instance << "\n"; collecting_error_listener local_reporter; eval_context this_context(context, this->keyword_name()); evaluation_results local_results1; std::vector indices; for (std::size_t i = 0; i < validators_.size(); ++i) { evaluation_results local_results2; eval_context item_context(this_context, i); std::size_t errors = local_reporter.errors.size(); walk_result result = validators_[i]->validate(item_context, instance, instance_location, local_results2, local_reporter, patch); if (result == walk_result::abort) { return result; } if (errors == local_reporter.errors.size()) { local_results1.merge(local_results2); indices.push_back(i); } //std::cout << "success: " << i << " " << success << "\n"; } if (indices.size() == 1) { results.merge(local_results1); } else { std::string message; if (indices.size() == 0) { message = "Must be valid against exactly one schema, but found no matching schemas"; } else { message = "Must be valid against exactly one schema, but found " + std::to_string(indices.size()) + " matching schemas at indices "; for (std::size_t i = 0; i < indices.size(); ++i) { if (i > 0) { message.push_back(','); } message.append(std::to_string(i)); } } walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, message, local_reporter.errors)); if (result == walk_result::abort) { return result; } } return walk_result::advance; } walk_result do_walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { walk_result result = reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); if (result == walk_result::abort) { return result; } eval_context this_context(context, this->keyword_name()); for (std::size_t i = 0; i < validators_.size(); ++i) { eval_context item_context(this_context, i); result = validators_[i]->walk(item_context, instance, instance_location, reporter); if (result == walk_result::abort) { return result; } } return walk_result::advance; } }; template class all_of_validator : public keyword_validator { using keyword_validator_ptr_type = typename keyword_validator::keyword_validator_ptr_type; using schema_validator_ptr_type = typename schema_validator::schema_validator_ptr_type; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::vector validators_; public: all_of_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, std::vector&& validators) : keyword_validator("allOf", schema, schema_location, custom_message), validators_(std::move(validators)) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const final { //std::cout << this->keyword_name() << " [" << context.eval_path().string() << ", " << this->schema_location().string() << "]\n"; evaluation_results local_results1; collecting_error_listener local_reporter; eval_context this_context(context, this->keyword_name()); std::size_t count = 0; for (std::size_t i = 0; i < validators_.size(); ++i) { evaluation_results local_results2; eval_context item_context(this_context, i); std::size_t errors = local_reporter.errors.size(); walk_result result = validators_[i]->validate(item_context, instance, instance_location, local_results2, local_reporter, patch); if (result == walk_result::abort) { return result; } //std::cout << "local_results2:\n"; //for (const auto& s : local_results2.evaluated_items) //{ // std::cout << " " << s << "\n"; //} if (errors == local_reporter.errors.size()) { local_results1.merge(local_results2); ++count; } //std::cout << "success: " << i << " " << success << "\n"; } //std::cout << "local_results1:\n"; //for (const auto& s : local_results1.evaluated_items) //{ // std::cout << " " << s << "\n"; //} if (count == validators_.size()) { results.merge(local_results1); } else { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, "Must be valid against all schemas, but found unmatched schemas", local_reporter.errors)); if (result == walk_result::abort) { return result; } } return walk_result::advance; } walk_result do_walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { walk_result result = reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); if (result == walk_result::abort) { return result; } eval_context this_context(context, this->keyword_name()); for (std::size_t i = 0; i < validators_.size(); ++i) { eval_context item_context(this_context, i); result = validators_[i]->walk(item_context, instance, instance_location, reporter); if (result == walk_result::abort) { return result; } } return walk_result::advance; } }; template class maximum_validator : public keyword_validator { using keyword_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; Json value_; std::string message_; public: maximum_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, const Json& value) : keyword_validator("maximum", schema, schema_location, custom_message), value_(value), message_{"Maximum value is " + value.template as() + " but found"} { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& /*results*/, error_reporter& reporter, Json& /*patch*/) const final { eval_context this_context(context, this->keyword_name()); if (instance.is_int64() && value_.is_int64()) { if (instance.template as() > value_.template as()) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, message_ + instance.template as())); if (result == walk_result::abort) { return result; } } } else if (instance.is_uint64() && value_.is_uint64()) { if (instance.template as() > value_.template as()) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, message_ + instance.template as())); if (result == walk_result::abort) { return result; } } } else if (instance.is_string_view() && instance.tag() == semantic_tag::bigint) { auto sv1 = instance.as_string_view(); bigint n1 = bigint::from_string(sv1.data(), sv1.length()); auto s2 = value_.as_string(); bigint n2 = bigint::from_string(s2.data(), s2.length()); if (n1 > n2) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, message_ + instance.template as())); if (result == walk_result::abort) { return result; } } } else if (instance.is_number()) { if (instance.template as() > value_.template as()) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, message_ + instance.template as())); if (result == walk_result::abort) { return result; } } } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; template class exclusive_maximum_validator : public keyword_validator { using keyword_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; Json value_; std::string message_; public: exclusive_maximum_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, const Json& value) : keyword_validator("exclusiveMaximum", schema, schema_location, custom_message), value_(value), message_{"Exclusive maximum value is " + value.template as() + " but found "} { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& /*results*/, error_reporter& reporter, Json& /*patch*/) const final { eval_context this_context(context, this->keyword_name()); if (instance.is_int64() && value_.is_int64()) { if (instance.template as() >= value_.template as()) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, message_ + instance.template as())); if (result == walk_result::abort) { return result; } } } else if (instance.is_uint64() && value_.is_uint64()) { if (instance.template as() >= value_.template as()) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, message_ + instance.template as())); if (result == walk_result::abort) { return result; } } } else if (instance.is_string_view() && instance.tag() == semantic_tag::bigint) { auto sv1 = instance.as_string_view(); bigint n1 = bigint::from_string(sv1.data(), sv1.length()); auto s2 = value_.as_string(); bigint n2 = bigint::from_string(s2.data(), s2.length()); if (n1 >= n2) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, message_ + instance.template as())); if (result == walk_result::abort) { return result; } } } else if (instance.is_number()) { if (instance.template as() >= value_.template as()) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, message_ + instance.template as())); if (result == walk_result::abort) { return result; } } } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; template class minimum_validator : public keyword_validator { using keyword_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; Json value_; std::string message_; public: minimum_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, const Json& value) : keyword_validator("minimum", schema, schema_location, custom_message), value_(value), message_{"Minimum value is " + value.template as() + " but found "} { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& /*results*/, error_reporter& reporter, Json& /*patch*/) const final { eval_context this_context(context, this->keyword_name()); if (instance.is_int64() && value_.is_int64()) { if (instance.template as() < value_.template as()) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, message_ + instance.template as())); if (result == walk_result::abort) { return result; } } } else if (instance.is_uint64() && value_.is_uint64()) { if (instance.template as() < value_.template as()) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, message_ + instance.template as())); if (result == walk_result::abort) { return result; } } } else if (instance.is_string_view() && instance.tag() == semantic_tag::bigint) { auto sv1 = instance.as_string_view(); bigint n1 = bigint::from_string(sv1.data(), sv1.length()); auto s2 = value_.as_string(); bigint n2 = bigint::from_string(s2.data(), s2.length()); if (n1 < n2) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, message_ + instance.template as())); if (result == walk_result::abort) { return result; } } } else if (instance.is_number()) { if (instance.template as() < value_.template as()) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, message_ + instance.template as())); if (result == walk_result::abort) { return result; } } } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; template class exclusive_minimum_validator : public keyword_validator { using keyword_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; Json value_; std::string message_; public: exclusive_minimum_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, const Json& value) : keyword_validator("exclusiveMinimum", schema, schema_location, custom_message), value_(value), message_{"Exclusive minimum value is " + value.template as() + " but found "} { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& /*results*/, error_reporter& reporter, Json& /*patch*/) const final { eval_context this_context(context, this->keyword_name()); if (instance.is_int64() && value_.is_int64()) { if (instance.template as() <= value_.template as()) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, message_ + instance.template as())); if (result == walk_result::abort) { return result; } } } else if (instance.is_uint64() && value_.is_uint64()) { if (instance.template as() <= value_.template as()) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, message_ + instance.template as())); if (result == walk_result::abort) { return result; } } } else if (instance.is_string_view() && instance.tag() == semantic_tag::bigint) { auto sv1 = instance.as_string_view(); bigint n1 = bigint::from_string(sv1.data(), sv1.length()); auto s2 = value_.as_string(); bigint n2 = bigint::from_string(s2.data(), s2.length()); if (n1 <= n2) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, message_ + instance.template as())); if (result == walk_result::abort) { return result; } } } else if (instance.is_number()) { if (instance.template as() <= value_.template as()) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, message_ + instance.template as())); if (result == walk_result::abort) { return result; } } } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; template class multiple_of_validator : public keyword_validator { using keyword_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; double value_; public: multiple_of_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, double value) : keyword_validator("multipleOf", schema, schema_location, custom_message), value_(value) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& /*results*/, error_reporter& reporter, Json& /*patch*/) const final { if (!instance.is_number()) { return walk_result::advance; } eval_context this_context(context, this->keyword_name()); double value = instance.template as(); if (value != 0) // Exclude zero { if (!is_multiple_of(value, static_cast(value_))) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, instance.template as() + " is not a multiple of " + std::to_string(value_))); if (result == walk_result::abort) { return result; } } } return walk_result::advance; } static bool is_multiple_of(double x, double multiple_of) { double rem = std::remainder(x, multiple_of); double eps = std::nextafter(x, 0) - x; return std::fabs(rem) < std::fabs(eps); } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; template class required_validator : public keyword_validator { using keyword_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::vector items_; public: required_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, const std::vector& items) : keyword_validator("required", schema, schema_location, custom_message), items_(items) { } required_validator(const required_validator&) = delete; required_validator(required_validator&&) = default; required_validator& operator=(const required_validator&) = delete; required_validator& operator=(required_validator&&) = default; private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& /*results*/, error_reporter& reporter, Json& /*patch*/) const final { if (!instance.is_object()) { return walk_result::advance; } eval_context this_context(context, this->keyword_name()); for (const auto& key : items_) { if(instance.find(key) == instance.object_range().end()) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, "Required property '" + key + "' not found.")); if(result == walk_result::abort) { return result; } } } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; // maxProperties template class max_properties_validator : public keyword_validator { using keyword_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::size_t max_properties_; public: max_properties_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, std::size_t max_properties) : keyword_validator("maxProperties", schema, schema_location, custom_message), max_properties_(max_properties) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& /*results*/, error_reporter& reporter, Json& /*patch*/) const final { if (!instance.is_object()) { return walk_result::advance; } if (instance.size() > max_properties_) { eval_context this_context(context, this->keyword_name()); std::string message("Maximum number of properties is " + std::to_string(max_properties_)); message.append(" but found " + std::to_string(instance.size())); walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, std::move(message))); if (result == walk_result::abort) { return result; } } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; // minProperties template class min_properties_validator : public keyword_validator { using keyword_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::size_t min_properties_; public: min_properties_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, std::size_t min_properties) : keyword_validator("minProperties", schema, schema_location, custom_message), min_properties_(min_properties) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& /*results*/, error_reporter& reporter, Json& /*patch*/) const final { if (!instance.is_object()) { return walk_result::advance; } if (instance.size() < min_properties_) { eval_context this_context(context, this->keyword_name()); std::string message("Minimum number of properties is " + std::to_string(min_properties_)); message.append(" but found " + std::to_string(instance.size())); walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, std::move(message))); if (result == walk_result::abort) { return result; } } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; template class conditional_validator : public keyword_validator { using keyword_validator_ptr_type = typename keyword_validator::keyword_validator_ptr_type; using schema_validator_ptr_type = typename schema_validator::schema_validator_ptr_type; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; schema_validator_ptr_type if_val_; schema_validator_ptr_type then_val_; schema_validator_ptr_type else_val_; public: conditional_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, schema_validator_ptr_type&& if_val, schema_validator_ptr_type&& then_val, schema_validator_ptr_type&& else_val ) : keyword_validator("", schema, std::move(schema_location), custom_message), if_val_(std::move(if_val)), then_val_(std::move(then_val)), else_val_(std::move(else_val)) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const final { if (if_val_) { collecting_error_listener local_reporter; evaluation_results local_results; eval_context if_context(context, "if"); walk_result result = if_val_->validate(if_context, instance, instance_location, local_results, local_reporter, patch); if (result == walk_result::abort) { return result; } //std::cout << "if: evaluated properties\n"; //for (auto& item : results.evaluated_properties) //{ // std::cout << " " << item << "\n"; //} if (local_reporter.errors.empty()) { results.merge(local_results); if (then_val_) { eval_context then_context(context, "then"); result = then_val_->validate(then_context, instance, instance_location, results, reporter, patch); if (result == walk_result::abort) { return result; } //std::cout << "then: evaluated properties\n"; //for (auto& item : results.evaluated_properties) //{ // std::cout << " " << item << "\n"; //} } } else { if (else_val_) { eval_context else_context(context, "else"); result = else_val_->validate(else_context, instance, instance_location, results, reporter, patch); if (result == walk_result::abort) { return result; } //std::cout << "else: evaluated properties\n"; //for (auto& item : results.evaluated_properties) //{ // std::cout << " " << item << "\n"; //} } } } return walk_result::advance; } walk_result do_walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { walk_result result = walk_result::advance; if (if_val_) { eval_context if_context(context, "if"); result = if_val_->walk(if_context, instance, instance_location, reporter); if (result == walk_result::abort) { return result; } if (then_val_) { eval_context then_context(context, "then"); result = then_val_->walk(then_context, instance, instance_location, reporter); if (result == walk_result::abort) { return result; } } if (else_val_) { eval_context else_context(context, "else"); result = else_val_->walk(else_context, instance, instance_location, reporter); if (result == walk_result::abort) { return result; } } } return walk_result::advance; } }; // enum_validator template class enum_validator : public keyword_validator { using keyword_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; Json value_; public: enum_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, const Json& sch) : keyword_validator("enum", schema, schema_location, custom_message), value_(sch) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& /*results*/, error_reporter& reporter, Json& /*patch*/) const final { eval_context this_context(context, this->keyword_name()); bool in_range = false; for (const auto& item : value_.array_range()) { if (item == instance) { in_range = true; break; } } if (!in_range) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, "'" + instance.template as() + "' is not a valid enum value.")); if (result == walk_result::abort) { return result; } } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; // const_validator template class const_validator : public keyword_validator { using keyword_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; Json value_; public: const_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, const Json& sch) : keyword_validator("const", schema, schema_location, custom_message), value_(sch) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& /*results*/, error_reporter& reporter, Json& /*patch*/) const final { if (value_ != instance) { eval_context this_context(context, this->keyword_name()); walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, "Instance is not const")); if (result == walk_result::abort) { return result; } } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; enum class json_schema_type{null,object,array,string,boolean,integer,number}; inline std::string to_string(json_schema_type type) { switch (type) { case json_schema_type::null: return "null"; case json_schema_type::object: return "object"; case json_schema_type::array: return "array"; case json_schema_type::string: // OK return "string"; case json_schema_type::boolean: // OK return "boolean"; case json_schema_type::integer: return "integer"; case json_schema_type::number: return "number"; default: return "unknown"; } } template class type_validator : public keyword_validator { using keyword_validator_ptr_type = typename keyword_validator::keyword_validator_ptr_type; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::vector expected_types_; public: type_validator(const type_validator&) = delete; type_validator& operator=(const type_validator&) = delete; type_validator(type_validator&&) = default; type_validator& operator=(type_validator&&) = default; type_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, std::vector&& expected_types) : keyword_validator("type", schema, std::move(schema_location), custom_message), expected_types_(std::move(expected_types)) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& /*results*/, error_reporter& reporter, Json& /*patch*/) const final { //std::cout << "type_validator.do_validate " << context.eval_path().string() << instance << "\n"; //for (auto& type : expected_types_ ) //{ // std::cout << " " << to_string(type) << "\n"; //} eval_context this_context(context, this->keyword_name()); bool is_type_found = expected_types_.empty(); auto end = expected_types_.end(); for (auto it = expected_types_.begin(); it != end && !is_type_found; ++it) { switch (*it) { case json_schema_type::null: if (instance.is_null()) // OK { is_type_found = true; } break; case json_schema_type::object: if (instance.is_object()) // OK { is_type_found = true; } break; case json_schema_type::array: if (instance.is_array()) // OK { is_type_found = true; } break; case json_schema_type::string: // OK if (instance.is_string() && instance.tag() != semantic_tag::bigint) { is_type_found = true; } break; case json_schema_type::boolean: // OK if (instance.is_bool()) { is_type_found = true; } break; case json_schema_type::integer: if (instance.is_int64() || instance.is_uint64()) { is_type_found = true; } else if (instance.is_double() && static_cast(instance.template as()) == instance.template as()) { is_type_found = true; } else if (instance.is_string() && instance.tag() == semantic_tag::bigint) { is_type_found = true; } break; case json_schema_type::number: if (instance.is_number()) { is_type_found = true; } break; default: break; } } if (!is_type_found) { std::string message = "Expected "; for (std::size_t i = 0; i < expected_types_.size(); ++i) { if (i > 0) { message.append(", "); if (i+1 == expected_types_.size()) { message.append("or "); } } message.append(to_string(expected_types_[i])); } message.append(", found "); message.append(to_schema_type(instance.type())); return reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, message)); } return walk_result::advance; } std::string to_schema_type(json_type type) const { switch (type) { case json_type::null_value: { return "null"; } case json_type::bool_value: { return "boolean"; } case json_type::int64_value: case json_type::uint64_value: { return "integer"; } case json_type::half_value: case json_type::double_value: { return "number"; } case json_type::string_value: { return "string"; } case json_type::array_value: { return "array"; } case json_type::object_value: { return "object"; } default: { return "unsupported type"; } } } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; template class properties_validator : public keyword_validator { using keyword_validator_ptr_type = typename keyword_validator::keyword_validator_ptr_type; using schema_validator_ptr_type = typename schema_validator::schema_validator_ptr_type; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::map properties_; public: properties_validator(const properties_validator&) = delete; properties_validator& operator=(const properties_validator&) = delete; properties_validator(properties_validator&&) = default; properties_validator& operator=(properties_validator&&) = default; properties_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, std::map&& properties) : keyword_validator("properties", schema, std::move(schema_location), custom_message), properties_(std::move(properties)) { } walk_result validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch, std::unordered_set& allowed_properties) const { //std::cout << "properties_validator begin[" << context.eval_path().string() << "," << this->schema_location().string() << "]\n"; if (!instance.is_object()) { return walk_result::advance; } //std::cout << "results:\n"; //for (const auto& s : results) //{ // std::cout << " " << s << "\n"; //} //std::cout << "\n"; eval_context this_context(context, this->keyword_name()); for (const auto& prop : instance.object_range()) { auto prop_it = properties_.find(prop.key()); // check if it is in "properties" if (prop_it != properties_.end()) { eval_context prop_context{this_context, prop.key(), evaluation_flags{}}; jsonpointer::json_pointer prop_location = instance_location / prop.key(); std::size_t errors = reporter.error_count(); walk_result result = (*prop_it).second->validate(prop_context, prop.value(), prop_location, results, reporter, patch); if (result == walk_result::abort) { return result; } allowed_properties.insert(prop.key()); if (errors == reporter.error_count()) { if (context.require_evaluated_properties()) { results.evaluated_properties.insert(prop.key()); } } } } // Any property that doesn't match any of the property names in the properties keyword is ignored by this keyword. // reverse search for (auto const& prop : properties_) { //std::cout << " prop:" << prop.first << "\n"; const auto finding = instance.find(prop.first); if (finding == instance.object_range().end()) { // If prop is not in instance auto default_value = prop.second->get_default_value(); if (default_value) { // If default value is available, update patch jsonpointer::json_pointer prop_location = instance_location / prop.first; update_patch(patch, prop_location, std::move(*default_value)); } } } //std::cout << "properties_validator end[" << context.eval_path().string() << "," << this->schema_location().string() << "]"; //std::cout << "results:\n"; //for (const auto& s : results) //{ // std::cout << " " << s << "\n"; //} //std::cout << "\n"; return walk_result::advance; } walk_result walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter, std::unordered_set& allowed_properties) const { if (!instance.is_object()) { return walk_result::advance; } walk_result result = reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); if (result == walk_result::abort) { return result; } for (const auto& prop : instance.object_range()) { auto prop_it = properties_.find(prop.key()); if (prop_it != properties_.end()) { jsonpointer::json_pointer prop_location = instance_location / prop.key(); result = (*prop_it).second->walk(context, prop.value(), prop_location, reporter); allowed_properties.insert(prop.key()); if (result == walk_result::abort) { return result; } } } return walk_result::advance; } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const final { std::unordered_set allowed_properties; return validate(context, instance, instance_location, results, reporter, patch, allowed_properties); } walk_result do_walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { std::unordered_set allowed_properties; return walk(context, instance, instance_location, reporter, allowed_properties); } void update_patch(Json& patch, const jsonpointer::json_pointer& instance_location, Json&& default_value) const { Json j; j.try_emplace("op", "add"); j.try_emplace("path", instance_location.string()); j.try_emplace("value", std::forward(default_value)); patch.push_back(std::move(j)); } }; template class pattern_properties_validator : public keyword_validator { using keyword_validator_ptr_type = typename keyword_validator::keyword_validator_ptr_type; using schema_validator_ptr_type = typename schema_validator::schema_validator_ptr_type; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::vector> pattern_properties_; public: pattern_properties_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, std::vector>&& pattern_properties) : keyword_validator("patternProperties", schema, std::move(schema_location), custom_message), pattern_properties_(std::move(pattern_properties)) { } walk_result validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch, std::unordered_set& allowed_properties) const { (void)context; (void)instance; (void)instance_location; (void)results; (void)reporter; (void)patch; (void)allowed_properties; #if defined(JSONCONS_HAS_STD_REGEX) if (!instance.is_object()) { return walk_result::advance; } eval_context this_context(context, this->keyword_name()); for (const auto& prop : instance.object_range()) { eval_context prop_context{this_context, prop.key(), evaluation_flags{}}; jsonpointer::json_pointer prop_location = instance_location / prop.key(); // check all matching "patternProperties" for (auto& schema_pp : pattern_properties_) { if (std::regex_search(prop.key(), schema_pp.first)) { allowed_properties.insert(prop.key()); std::size_t errors = reporter.error_count(); walk_result result = schema_pp.second->validate(prop_context, prop.value() , prop_location, results, reporter, patch); if (result == walk_result::abort) { return result; } if (errors == reporter.error_count()) { if (context.require_evaluated_properties()) { results.evaluated_properties.insert(prop.key()); } } } } } #endif return walk_result::advance; } walk_result walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter, std::unordered_set& allowed_properties) const { if (!instance.is_object()) { return walk_result::advance; } walk_result result = reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); if (result == walk_result::abort) { return result; } (void)context; #if defined(JSONCONS_HAS_STD_REGEX) eval_context this_context(context, this->keyword_name()); for (const auto& prop : instance.object_range()) { eval_context prop_context{this_context, prop.key(), evaluation_flags{}}; jsonpointer::json_pointer prop_location = instance_location / prop.key(); // check all matching "patternProperties" for (auto& schema_pp : pattern_properties_) { if (std::regex_search(prop.key(), schema_pp.first)) { allowed_properties.insert(prop.key()); result = schema_pp.second->walk(prop_context, prop.value() , prop_location, reporter); if (result == walk_result::abort) { return result; } } } } #endif return walk_result::advance; } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const final { std::unordered_set allowed_properties; return validate(context, instance, instance_location, results, reporter, patch, allowed_properties); } walk_result do_walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { std::unordered_set allowed_properties; return walk(context,instance, instance_location, reporter, allowed_properties); } }; template class additional_properties_validator : public keyword_validator { using keyword_validator_ptr_type = typename keyword_validator::keyword_validator_ptr_type; using schema_validator_ptr_type = typename schema_validator::schema_validator_ptr_type; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::unique_ptr> properties_; std::unique_ptr> pattern_properties_; schema_validator_ptr_type additional_properties_; public: additional_properties_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, std::unique_ptr>&& properties, std::unique_ptr>&& pattern_properties, schema_validator_ptr_type&& additional_properties ) : keyword_validator("additionalProperties", schema, std::move(schema_location), custom_message), properties_(std::move(properties)), pattern_properties_(std::move(pattern_properties)), additional_properties_(std::move(additional_properties)) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const final { if (!instance.is_object()) { return walk_result::advance; } std::unordered_set allowed_properties; if (properties_) { walk_result result = properties_->validate(context, instance, instance_location, results, reporter, patch, allowed_properties); if (result == walk_result::abort) { return result; } } if (pattern_properties_) { walk_result result = pattern_properties_->validate(context, instance, instance_location, results, reporter, patch, allowed_properties); if (result == walk_result::abort) { return result; } } if (additional_properties_) { eval_context this_context(context, this->keyword_name()); if (additional_properties_->always_fails()) { for (const auto& prop : instance.object_range()) { eval_context prop_context{this_context, prop.key(), evaluation_flags{}}; jsonpointer::json_pointer prop_location = instance_location / prop.key(); // check if it is in "allowed properties" auto prop_it = allowed_properties.find(prop.key()); if (prop_it == allowed_properties.end()) { walk_result result = reporter.error(this->make_validation_message( prop_context.eval_path(), prop_location, "Additional property '" + prop.key() + "' not allowed by schema.")); if (result == walk_result::abort) { return result; } break; } } } else if (additional_properties_->always_succeeds()) { if (context.require_evaluated_properties()) { for (const auto& prop : instance.object_range()) { results.evaluated_properties.insert(prop.key()); } } } else { for (const auto& prop : instance.object_range()) { // check if it is in "allowed properties" auto prop_it = allowed_properties.find(prop.key()); if (prop_it == allowed_properties.end()) { eval_context prop_context{this_context, prop.key(), evaluation_flags{}}; jsonpointer::json_pointer prop_location = instance_location / prop.key(); // finally, check "additionalProperties" //std::cout << "additional_properties_validator a_prop_or_pattern_matched " << a_prop_or_pattern_matched << ", " << bool(additional_properties_); //std::cout << " !!!additionalProperties!!!"; collecting_error_listener local_reporter; walk_result result = additional_properties_->validate(prop_context, prop.value() , prop_location, results, local_reporter, patch); if (result == walk_result::abort) { return result; } if (!local_reporter.errors.empty()) { result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, "Additional property '" + prop.key() + "' found but was invalid.")); if (result == walk_result::abort) { return result; } } else if (context.require_evaluated_properties()) { results.evaluated_properties.insert(prop.key()); } } //std::cout << "\n"; } } } return walk_result::advance; } walk_result do_walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { if (!instance.is_object()) { return walk_result::advance; } walk_result result = reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); if (result == walk_result::abort) { return result; } std::unordered_set allowed_properties; if (properties_) { result = properties_->walk(context, instance, instance_location, reporter, allowed_properties); if (result == walk_result::abort) { return result; } } if (pattern_properties_) { result = pattern_properties_->walk(context, instance, instance_location, reporter, allowed_properties); if (result == walk_result::abort) { return result; } } if (additional_properties_) { eval_context this_context(context, this->keyword_name()); for (const auto& prop : instance.object_range()) { // check if it is in "allowed properties" auto prop_it = allowed_properties.find(prop.key()); if (prop_it == allowed_properties.end()) { eval_context prop_context{this_context, prop.key(), evaluation_flags{}}; jsonpointer::json_pointer prop_location = instance_location / prop.key(); result = additional_properties_->walk(prop_context, prop.value() , prop_location, reporter); if (result == walk_result::abort) { return result; } } } } return walk_result::advance; } }; template class dependent_required_validator : public keyword_validator { using keyword_validator_ptr_type = typename keyword_validator::keyword_validator_ptr_type; using schema_validator_ptr_type = typename schema_validator::schema_validator_ptr_type; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::map dependent_required_; public: dependent_required_validator(const Json& schema, const uri& schema_location, std::map&& dependent_required, const std::string& custom_message = std::string{} ) : keyword_validator("dependentRequired", schema, std::move(schema_location), custom_message), dependent_required_(std::move(dependent_required)) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const final { if (!instance.is_object()) { return walk_result::advance; } eval_context this_context(context, this->keyword_name()); for (const auto& dep : dependent_required_) { auto prop = instance.find(dep.first); if (prop != instance.object_range().end()) { // if dependency-prop is present in instance jsonpointer::json_pointer prop_location = instance_location / dep.first; walk_result result = dep.second->validate(this_context, instance, prop_location, results, reporter, patch); // validate if (result == walk_result::abort) { return result; } } } return walk_result::advance; } walk_result do_walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { if (!instance.is_object()) { return walk_result::advance; } walk_result result = reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); if (result == walk_result::abort) { return result; } eval_context this_context(context, this->keyword_name()); for (const auto& dep : dependent_required_) { auto prop = instance.find(dep.first); if (prop != instance.object_range().end()) { // if dependency-prop is present in instance result = dep.second->walk(this_context, instance, instance_location / dep.first, reporter); if (result == walk_result::abort) { return result; } } } return walk_result::advance; } }; template class dependent_schemas_validator : public keyword_validator { using keyword_validator_ptr_type = typename keyword_validator::keyword_validator_ptr_type; using schema_validator_ptr_type = typename schema_validator::schema_validator_ptr_type; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::map dependent_schemas_; public: dependent_schemas_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, std::map&& dependent_schemas ) : keyword_validator("dependentSchemas", schema, std::move(schema_location), custom_message), dependent_schemas_(std::move(dependent_schemas)) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const final { if (!instance.is_object()) { return walk_result::advance; } eval_context this_context(context, this->keyword_name()); for (const auto& dep : dependent_schemas_) { auto prop = instance.find(dep.first); if (prop != instance.object_range().end()) { // if dependency-prop is present in instance jsonpointer::json_pointer prop_location = instance_location / dep.first; walk_result result = dep.second->validate(this_context, instance, prop_location, results, reporter, patch); // validate if (result == walk_result::abort) { return result; } } } return walk_result::advance; } walk_result do_walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { if (!instance.is_object()) { return walk_result::advance; } walk_result result = reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); if (result == walk_result::abort) { return result; } eval_context this_context(context, this->keyword_name()); for (const auto& dep : dependent_schemas_) { auto prop = instance.find(dep.first); if (prop != instance.object_range().end()) { // if dependency-prop is present in instance result = dep.second->walk(this_context, instance, instance_location / dep.first, reporter); if (result == walk_result::abort) { return result; } } } return walk_result::advance; } }; template class property_names_validator : public keyword_validator { using keyword_validator_ptr_type = typename keyword_validator::keyword_validator_ptr_type; using schema_validator_ptr_type = typename schema_validator::schema_validator_ptr_type; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; schema_validator_ptr_type schema_val_; public: property_names_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, schema_validator_ptr_type&& schema_val) : keyword_validator("propertyNames", schema, schema_location, custom_message), schema_val_{ std::move(schema_val) } { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const final { if (!instance.is_object()) { return walk_result::advance; } eval_context this_context(context, this->keyword_name()); if (instance.size() > 0 && schema_val_) { if (schema_val_->always_fails()) { jsonpointer::json_pointer item_location = instance_location / 0; return reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, "Instance has properties but the schema does not allow any property names.")); } else if (schema_val_->always_succeeds()) { return walk_result::advance; } else { for (const auto& prop : instance.object_range()) { jsonpointer::json_pointer prop_location = instance_location / prop.key(); walk_result result = schema_val_->validate(this_context, prop.key() , instance_location, results, reporter, patch); if (result == walk_result::abort) { return result; } } } } return walk_result::advance; } walk_result do_walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { if (!instance.is_object()) { return walk_result::advance; } walk_result result = reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); if (result == walk_result::abort) { return result; } eval_context this_context(context, this->keyword_name()); if (instance.size() > 0 && schema_val_) { for (const auto& prop : instance.object_range()) { result = schema_val_->walk(this_context, prop.key(), instance_location / prop.key(), reporter); if (result == walk_result::abort) { return result; } } } return walk_result::advance; } }; template class dependencies_validator : public keyword_validator { using keyword_validator_ptr_type = typename keyword_validator::keyword_validator_ptr_type; using schema_validator_ptr_type = typename schema_validator::schema_validator_ptr_type; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::map dependent_required_; std::map dependent_schemas_; public: dependencies_validator(const Json& schema, const uri& schema_location, std::map&& dependent_required, std::map&& dependent_schemas, const std::string& custom_message = std::string{} ) : keyword_validator("dependencies", schema, std::move(schema_location), custom_message), dependent_required_(std::move(dependent_required)), dependent_schemas_(std::move(dependent_schemas)) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const final { if (!instance.is_object()) { return walk_result::advance; } eval_context this_context(context, this->keyword_name()); for (const auto& dep : dependent_required_) { auto prop = instance.find(dep.first); if (prop != instance.object_range().end()) { // if dependency-prop is present in instance jsonpointer::json_pointer prop_location = instance_location / dep.first; walk_result result = dep.second->validate(this_context, instance, prop_location, results, reporter, patch); // validate if (result == walk_result::abort) { return result; } } } for (const auto& dep : dependent_schemas_) { auto prop = instance.find(dep.first); if (prop != instance.object_range().end()) { // if dependency-prop is present in instance jsonpointer::json_pointer prop_location = instance_location / dep.first; walk_result result = dep.second->validate(this_context, instance, prop_location, results, reporter, patch); // validate if (result == walk_result::abort) { return result; } } } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; template class max_contains_keyword : public keyword_base { using keyword_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::size_t max_value_; public: max_contains_keyword(const Json& schema, const uri& schema_location, const std::string& custom_message, std::size_t max_value) : keyword_base("maxContains", schema, schema_location, custom_message), max_value_(max_value) { } walk_result validate(const eval_context& context, const jsonpointer::json_pointer& instance_location, std::size_t count, error_reporter& reporter) const { eval_context this_context(context, this->keyword_name()); if (count > max_value_) { std::string message("A schema can match a contains constraint at most " + std::to_string(max_value_) + " times"); message.append(" but it matched " + std::to_string(count) + " times."); walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, std::move(message))); if (result == walk_result::abort) { return result; } } return walk_result::advance; } walk_result walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; // minItems template class min_contains_keyword : public keyword_base { using keyword_validator_ptr_type = typename keyword_validator::keyword_validator_ptr_type; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::size_t min_value_; public: min_contains_keyword(const Json& schema, const uri& schema_location, const std::string& custom_message, std::size_t min_value) : keyword_base("minContains", schema, schema_location, custom_message), min_value_(min_value) { } walk_result validate(const eval_context& context, const jsonpointer::json_pointer& instance_location, std::size_t count, error_reporter& reporter) const { eval_context this_context(context, this->keyword_name()); if (count < min_value_) { std::string message("A schema must match a contains constraint at least " + std::to_string(min_value_) + " times"); message.append(" but it matched " + std::to_string(count) + " times."); walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, std::move(message))); if (result == walk_result::abort) { return result; } } return walk_result::advance; } walk_result walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; template class contains_validator : public keyword_validator { using keyword_validator_ptr_type = typename keyword_validator::keyword_validator_ptr_type; using schema_validator_ptr_type = typename schema_validator::schema_validator_ptr_type; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; schema_validator_ptr_type schema_validator_; std::unique_ptr> max_contains_; std::unique_ptr> min_contains_; public: contains_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, schema_validator_ptr_type&& schema_validator, std::unique_ptr>&& max_contains, std::unique_ptr>&& min_contains) : keyword_validator("contains", schema, std::move(schema_location), custom_message), schema_validator_(std::move(schema_validator)), max_contains_(std::move(max_contains)), min_contains_(std::move(min_contains)) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const final { if (!instance.is_array()) { return walk_result::advance; } if (!schema_validator_) { return walk_result::advance; } eval_context this_context(context, this->keyword_name()); std::size_t contains_count = 0; collecting_error_listener local_reporter; std::size_t index = 0; std::size_t start = 0; std::size_t end = 0; for (const auto& item : instance.array_range()) { std::size_t errors = local_reporter.errors.size(); walk_result result = schema_validator_->validate(this_context, item, instance_location / index, results, local_reporter, patch); if (result == walk_result::abort) { return result; } if (errors == local_reporter.errors.size()) { if (context.require_evaluated_items()) { if (end == start) { start = end = index; } ++end; } ++contains_count; } else { if (start < end) { results.evaluated_items.insert(range{start, end}); start = end; } } ++index; } if (start < end) { results.evaluated_items.insert(range{start, end}); start = end; } if (max_contains_ || min_contains_) { if (max_contains_) { walk_result result = max_contains_->validate(this_context, instance_location, contains_count, reporter); if (result == walk_result::abort) { return result; } } if (min_contains_) { walk_result result = min_contains_->validate(this_context, instance_location, contains_count, reporter); if (result == walk_result::abort) { return result; } } } else if (contains_count == 0) { walk_result result = reporter.error(this->make_validation_message( this_context.eval_path(), instance_location, "Expected at least one array item to match 'contains' schema.", local_reporter.errors)); if (result == walk_result::abort) { return result; } } return walk_result::advance; } walk_result do_walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const override { if (!instance.is_array()) { return walk_result::advance; } if (!schema_validator_) { return walk_result::advance; } walk_result result = reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); if (result == walk_result::abort) { return result; } eval_context this_context(context, this->keyword_name()); for (std::size_t index = 0; index < instance.size(); ++index) { result = schema_validator_->walk(this_context, instance.at(index), instance_location / index, reporter); if (result == walk_result::abort) { return result; } } if (max_contains_) { result = max_contains_->walk(this_context, instance, instance_location, reporter); if (result == walk_result::abort) { return result; } } if (min_contains_) { result = min_contains_->walk(this_context, instance, instance_location, reporter); if (result == walk_result::abort) { return result; } } return walk_result::advance; } }; template class items_keyword : public keyword_base { using keyword_validator_ptr_type = std::unique_ptr>; using schema_validator_ptr_type = typename schema_validator::schema_validator_ptr_type; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; schema_validator_ptr_type items_val_; public: items_keyword(const std::string& keyword_name, const Json& schema, const uri& schema_location, const std::string& custom_message, schema_validator_ptr_type&& items_val) : keyword_base(keyword_name, schema, schema_location, custom_message), items_val_(std::move(items_val)) { } walk_result validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch, std::size_t data_index) const { if (!instance.is_array()) { return walk_result::advance; } if (data_index < instance.size() && items_val_) { eval_context items_context(context, this->keyword_name()); if (items_val_->always_fails()) { jsonpointer::json_pointer item_location = instance_location / data_index; walk_result result = reporter.error(this->make_validation_message( items_context.eval_path(), item_location, "Extra item at index '" + std::to_string(data_index) + "' but the schema does not allow extra items.")); if (result == walk_result::abort) { return result; } } else if (items_val_->always_succeeds()) { results.evaluated_items.insert(range{0,instance.size()}); } else { std::size_t start = 0; std::size_t end = 0; for (; data_index < instance.size(); ++data_index) { jsonpointer::json_pointer item_location = instance_location / data_index; std::size_t errors = reporter.error_count(); walk_result result = items_val_->validate(items_context, instance[data_index], item_location, results, reporter, patch); if (result == walk_result::abort) { return result; } if (errors == reporter.error_count()) { if (context.require_evaluated_items()) { if (end == start) { start = end = data_index; } ++end; } } else { if (start < end) { results.evaluated_items.insert(range{start, end}); start = end; } } } if (start < end) { results.evaluated_items.insert(range{start, end}); start = end; } } } return walk_result::advance; } walk_result walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter, std::size_t data_index) const { if (!instance.is_array()) { return walk_result::advance; } walk_result result = reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); if (result == walk_result::abort) { return result; } if (data_index < instance.size() && items_val_) { eval_context items_context(context, this->keyword_name()); for (; data_index < instance.size(); ++data_index) { jsonpointer::json_pointer item_location = instance_location / data_index; result = items_val_->walk(items_context, instance[data_index], item_location, reporter); if (result == walk_result::abort) { return result; } } } return walk_result::advance; } }; template class prefix_items_validator : public keyword_validator { using schema_validator_ptr_type = typename schema_validator::schema_validator_ptr_type; using keyword_validator_ptr_type = typename keyword_validator::keyword_validator_ptr_type; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::vector prefix_item_validators_; std::unique_ptr> items_val_; public: prefix_items_validator(const std::string& keyword_name, const Json& schema, const uri& schema_location, const std::string& custom_message, std::vector&& prefix_item_validators, std::unique_ptr>&& items_val) : keyword_validator(keyword_name, schema, schema_location, custom_message), prefix_item_validators_(std::move(prefix_item_validators)), items_val_(std::move(items_val)) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const final { if (!instance.is_array()) { return walk_result::advance; } std::size_t data_index = 0; eval_context prefix_items_context(context, this->keyword_name()); std::size_t start = 0; std::size_t end = 0; for (std::size_t schema_index=0; schema_index < prefix_item_validators_.size() && data_index < instance.size(); ++schema_index, ++data_index) { auto& val = prefix_item_validators_[schema_index]; eval_context item_context{prefix_items_context, schema_index, evaluation_flags{}}; jsonpointer::json_pointer item_location = instance_location / data_index; std::size_t errors = reporter.error_count(); walk_result result = val->validate(item_context, instance[data_index], item_location, results, reporter, patch); if (result == walk_result::abort) { return result; } if (errors == reporter.error_count()) { if (context.require_evaluated_items()) { if (end == start) { start = end = data_index; } ++end; } } else { if (start < end) { results.evaluated_items.insert(range{start, end}); start = end; } } } if (start < end) { results.evaluated_items.insert(range{start, end}); } if (data_index < instance.size() && items_val_) { walk_result result = items_val_->validate(context, instance, instance_location, results, reporter, patch, data_index); if (result == walk_result::abort) { return result; } } return walk_result::advance; } walk_result do_walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { if (!instance.is_array()) { return walk_result::advance; } walk_result result = reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); if (result == walk_result::abort) { return result; } std::size_t data_index = 0; eval_context prefix_items_context(context, this->keyword_name()); for (std::size_t schema_index=0; schema_index < prefix_item_validators_.size() && data_index < instance.size(); ++schema_index, ++data_index) { auto& val = prefix_item_validators_[schema_index]; eval_context item_context{prefix_items_context, schema_index, evaluation_flags{}}; jsonpointer::json_pointer item_location = instance_location / data_index; result = val->walk(item_context, instance[data_index], item_location, reporter); if (result == walk_result::abort) { return result; } } if (data_index < instance.size() && items_val_) { items_val_->walk(context, instance, instance_location, reporter, data_index); } return walk_result::advance; } }; template class unevaluated_properties_validator : public keyword_validator { using keyword_validator_ptr_type = typename keyword_validator::keyword_validator_ptr_type; using schema_validator_ptr_type = typename schema_validator::schema_validator_ptr_type; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; schema_validator_ptr_type schema_val_; public: unevaluated_properties_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, schema_validator_ptr_type&& schema_val) : keyword_validator("unevaluatedProperties", schema, std::move(schema_location), custom_message), schema_val_(std::move(schema_val)) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const final { //std::cout << "unevaluated_properties_validator [" << context.eval_path().string() << "," << this->schema_location().string() << "]"; //std::cout << "results:\n"; //for (const auto& s : results.evaluated_properties_) //{ // std::cout << " " << s << "\n"; //} //std::cout << "\n"; if (!instance.is_object()) { return walk_result::advance; } if (schema_val_) { eval_context this_context(context, this->keyword_name()); if (schema_val_->always_fails()) { for (const auto& prop : instance.object_range()) { // check if it is in "evaluated_properties" auto prop_it = results.evaluated_properties.find(prop.key()); if (prop_it == results.evaluated_properties.end()) { eval_context prop_context{this_context, prop.key(), evaluation_flags{}}; jsonpointer::json_pointer prop_location = instance_location / prop.key(); walk_result result = reporter.error(this->make_validation_message( prop_context.eval_path(), prop_location, "Unevaluated property '" + prop.key() + "' but the schema does not allow unevaluated properties.")); if (result == walk_result::abort) { return result; } break; } } } else if (schema_val_->always_succeeds()) { if (context.require_evaluated_properties()) { for (const auto& prop : instance.object_range()) { results.evaluated_properties.insert(prop.key()); } } } else { for (const auto& prop : instance.object_range()) { // check if it is in "evaluated_properties" auto prop_it = results.evaluated_properties.find(prop.key()); if (prop_it == results.evaluated_properties.end()) { //std::cout << "Not in evaluated properties: " << prop.key() << "\n"; const std::size_t error_count = reporter.error_count(); walk_result result = schema_val_->validate(this_context, prop.value() , instance_location, results, reporter, patch); if (result == walk_result::abort) { return result; } if (reporter.error_count() == error_count) { if (context.require_evaluated_properties()) { results.evaluated_properties.insert(prop.key()); } } } } } } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; template class unevaluated_items_validator : public keyword_validator { using keyword_validator_ptr_type = typename keyword_validator::keyword_validator_ptr_type; using schema_validator_ptr_type = typename schema_validator::schema_validator_ptr_type; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; schema_validator_ptr_type schema_val_; public: unevaluated_items_validator(const Json& schema, const uri& schema_location, const std::string& custom_message, schema_validator_ptr_type&& schema_val) : keyword_validator("unevaluatedProperties", schema, std::move(schema_location), custom_message), schema_val_(std::move(schema_val)) { } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const final { //std::cout << this->keyword_name() << " [" << context.eval_path().string() << ", " << this->schema_location().string() << "]"; //std::cout << "results:\n"; //for (const auto& s : results.evaluated_items) //{ // std::cout << " " << s << "\n"; //} //std::cout << "\n"; if (!instance.is_array()) { return walk_result::advance; } if (schema_val_) { eval_context this_context(context, this->keyword_name()); if (schema_val_->always_fails()) { for (std::size_t index = 0; index < instance.size(); ++index) { // check if it is in "evaluated_items" if (!results.evaluated_items.contains(index)) { eval_context item_context{this_context, index, evaluation_flags{}}; jsonpointer::json_pointer item_location = instance_location / index; //std::cout << "Not in evaluated properties: " << item.key() << "\n"; walk_result result = reporter.error(this->make_validation_message( item_context.eval_path(), item_location, "Unevaluated item at index '" + std::to_string(index) + "' but the schema does not allow unevaluated items.")); if (result == walk_result::abort) { return result; } break; } } } else if (schema_val_->always_succeeds()) { if (context.require_evaluated_items()) { results.evaluated_items.insert(range{0,instance.size()}); } } else { std::size_t index = 0; std::size_t start = 0; std::size_t end = 0; for (const auto& item : instance.array_range()) { // check if it is in "evaluated_items" if (!results.evaluated_items.contains(index)) { eval_context item_context{this_context, index, evaluation_flags{}}; jsonpointer::json_pointer item_location = instance_location / index; //std::cout << "Not in evaluated properties: " << item.key() << "\n"; const std::size_t error_count = reporter.error_count(); walk_result result = schema_val_->validate(item_context, item, item_location, results, reporter, patch); if (result == walk_result::abort) { return result; } if (reporter.error_count() == error_count) { if (context.require_evaluated_items()) { if (end == start) { start = end = index; } ++end; } } else { if (start < end) { results.evaluated_items.insert(range{start, end}); start = end; } } } ++index; } if (start < end) { results.evaluated_items.insert(range{start, end}); start = end; } } } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { return reporter(this->keyword_name(), this->schema(), this->schema_location(), instance, instance_location); } }; } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_COMMON_KEYWORD_VALIDATOR_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/common/keyword_validator_factory.hpp000066400000000000000000001161671477700171100311440ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_COMMON_KEYWORD_VALIDATOR_FACTORY_HPP #define JSONCONS_EXT_JSONSCHEMA_COMMON_KEYWORD_VALIDATOR_FACTORY_HPP #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace jsonschema { template using resolve_uri_type = std::function; template class keyword_validator_factory { public: using schema_store_type = std::map*>; using validator_factory_factory_type = std::function>(const Json&, const evaluation_options&,schema_store_type*,const std::vector>&, const std::unordered_map&)>; using keyword_validator_ptr_type = typename std::unique_ptr>; using schema_validator_ptr_type = typename std::unique_ptr>; using ref_validator_type = ref_validator; using ref_type = ref; using anchor_uri_map_type = std::unordered_map; private: schema_validator_factory_base* factory_; public: keyword_validator_factory(schema_validator_factory_base* factory) : factory_(factory) { JSONCONS_ASSERT(factory_ != nullptr); } // keyword validator factories // No dependence on data members std::unique_ptr> make_properties_validator(const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict) { std::string keyword = "properties"; uri schema_location = context.get_base_uri(); std::map properties; for (const auto& prop : sch.object_range()) { std::string sub_keys[] = {keyword, prop.key()}; properties.emplace(std::make_pair(prop.key(), factory_->make_cross_draft_schema_validator(context, prop.value(), sub_keys, anchor_dict))); } return jsoncons::make_unique>(parent, std::move(schema_location), context.get_custom_message(keyword), std::move(properties)); } #if defined(JSONCONS_HAS_STD_REGEX) std::unique_ptr> make_pattern_properties_validator( const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict) { std::string keyword = "patternProperties"; uri schema_location = context.get_base_uri(); std::string custom_message = context.get_custom_message(keyword); std::vector> pattern_properties; for (const auto& prop : sch.object_range()) { pattern_properties.emplace_back( std::make_pair( std::regex(prop.key(), std::regex::ECMAScript), factory_->make_cross_draft_schema_validator(context, prop.value(), {}, anchor_dict))); } return jsoncons::make_unique>(parent, std::move(schema_location), custom_message, std::move(pattern_properties)); } #endif std::unique_ptr> make_max_length_validator(const compilation_context& context, const Json& sch, const Json& parent) { uri schema_location = context.make_schema_location("maxLength"); if (!sch.is_number()) { const std::string message("maxLength must be a number value"); JSONCONS_THROW(schema_error(schema_location.string() + ": " + message)); } auto value = sch.template as(); return jsoncons::make_unique>(parent, schema_location, context.get_custom_message("maxLength"), value); } std::unique_ptr> make_min_length_validator(const compilation_context& context, const Json& sch, const Json& parent) { uri schema_location = context.make_schema_location("minLength"); if (!sch.is_number()) { const std::string message("minLength must be an integer value"); JSONCONS_THROW(schema_error(schema_location.string() + ": " + message)); } auto value = sch.template as(); return jsoncons::make_unique>(parent, schema_location, context.get_custom_message("minLength"), value); } std::unique_ptr> make_not_validator(const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict) { uri schema_location = context.make_schema_location("not"); std::string not_key[] = { "not" }; return jsoncons::make_unique>(parent, schema_location, context.get_custom_message("not"), factory_->make_cross_draft_schema_validator(context, sch, not_key, anchor_dict)); } std::unique_ptr> make_const_validator(const compilation_context& context, const Json& sch, const Json& parent) { uri schema_location = context.make_schema_location("const"); return jsoncons::make_unique>(parent, schema_location, context.get_custom_message("const"), sch); } std::unique_ptr> make_enum_validator(const compilation_context& context, const Json& sch, const Json& parent) { uri schema_location = context.make_schema_location("enum"); return jsoncons::make_unique>(parent, schema_location, context.get_custom_message("enum"), sch); } std::unique_ptr> make_required_validator(const compilation_context& context, const Json& sch, const Json& parent) { uri schema_location = context.make_schema_location("required"); return jsoncons::make_unique>(parent, schema_location, context.get_custom_message("required"), sch.template as>()); } std::unique_ptr> make_maximum_validator(const compilation_context& context, const Json& sch, const Json& parent) { uri schema_location = context.make_schema_location("maximum"); if (!sch.is_number()) { const std::string message("maximum must be a number value"); JSONCONS_THROW(schema_error(schema_location.string() + ": " + message)); } return jsoncons::make_unique>(parent, schema_location, context.get_custom_message("maximum"), sch); } std::unique_ptr> make_exclusive_maximum_validator(const compilation_context& context, const Json& sch, const Json& parent) { uri schema_location = context.make_schema_location("exclusiveMaximum"); if (!sch.is_number()) { const std::string message("exclusiveMaximum must be a number value"); JSONCONS_THROW(schema_error(schema_location.string() + ": " + message)); } return jsoncons::make_unique>(parent, schema_location, context.get_custom_message("exclusiveMaximum"), sch); } std::unique_ptr> make_minimum_validator(const compilation_context& context, const Json& sch, const Json& parent) { uri schema_location = context.make_schema_location("minimum"); if (!sch.is_number()) { const std::string message("minimum must be an integer"); JSONCONS_THROW(schema_error(schema_location.string() + ": " + message)); } return jsoncons::make_unique>(parent, schema_location, context.get_custom_message("minimum"), sch); } std::unique_ptr> make_exclusive_minimum_validator(const compilation_context& context, const Json& sch, const Json& parent) { uri schema_location = context.make_schema_location("exclusiveMinimum"); if (!sch.is_number()) { const std::string message("exclusiveMinimum must be a number value"); JSONCONS_THROW(schema_error(schema_location.string() + ": " + message)); } return jsoncons::make_unique>(parent, schema_location, context.get_custom_message("exclusiveMinimum"), sch); } std::unique_ptr> make_multiple_of_validator(const compilation_context& context, const Json& sch, const Json& parent) { uri schema_location = context.make_schema_location("multipleOf"); if (!sch.is_number()) { const std::string message("multipleOf must be a number value"); JSONCONS_THROW(schema_error(schema_location.string() + ": " + message)); } auto value = sch.template as(); return jsoncons::make_unique>(parent, schema_location, context.get_custom_message("multipleOf"), value); } std::unique_ptr> make_type_validator(const compilation_context& context, const Json& sch, const Json& parent) { std::string keyword = "type"; uri schema_location = context.get_base_uri(); std::vector expected_types; switch (sch.type()) { case json_type::string_value: { auto type = sch.template as(); if (type == "null") { expected_types.push_back(json_schema_type::null); } else if (type == "object") { expected_types.push_back(json_schema_type::object); } else if (type == "array") { expected_types.push_back(json_schema_type::array); } else if (type == "string") { expected_types.push_back(json_schema_type::string); } else if (type == "boolean") { expected_types.push_back(json_schema_type::boolean); } else if (type == "integer") { expected_types.push_back(json_schema_type::integer); } else if (type == "number") { expected_types.push_back(json_schema_type::number); } else { JSONCONS_THROW(schema_error(schema_location.string() + ": " + "Invalid type '" + type + "'")); } break; } case json_type::array_value: // "type": ["type1", "type2"] { for (const auto& item : sch.array_range()) { auto type = item.template as(); if (type == "null") { expected_types.push_back(json_schema_type::null); } else if (type == "object") { expected_types.push_back(json_schema_type::object); } else if (type == "array") { expected_types.push_back(json_schema_type::array); } else if (type == "string") { expected_types.push_back(json_schema_type::string); } else if (type == "boolean") { expected_types.push_back(json_schema_type::boolean); } else if (type == "integer") { expected_types.push_back(json_schema_type::integer); } else if (type == "number") { expected_types.push_back(json_schema_type::number); } else { JSONCONS_THROW(schema_error(schema_location.string() + ": " + "Invalid type '" + type + "'")); } } break; } default: break; } return jsoncons::make_unique>(parent, std::move(schema_location), context.get_custom_message(keyword), std::move(expected_types)); } std::unique_ptr> make_content_encoding_validator(const compilation_context& context, const Json& sch, const Json& parent) { std::string keyword = "contentEncoding"; uri schema_location = context.make_schema_location(keyword); if (!sch.is_string()) { const std::string message("contentEncoding must be a string"); JSONCONS_THROW(schema_error(schema_location.string() + ": " + message)); } auto value = sch.template as(); return jsoncons::make_unique>(parent, schema_location, context.get_custom_message(keyword), value); } std::unique_ptr> make_content_media_type_validator(const compilation_context& context, const Json& sch, const Json& parent) { std::string keyword = "contentMediaType"; uri schema_location = context.make_schema_location(keyword); if (!sch.is_string()) { const std::string message("contentMediaType must be a string"); JSONCONS_THROW(schema_error(schema_location.string() + ": " + message)); } std::string content_encoding; auto it = parent.find("contentEncoding"); if (it != parent.object_range().end()) { if (!(*it).value().is_string()) { const std::string message("contentEncoding must be a string"); JSONCONS_THROW(schema_error(schema_location.string() + ": " + message)); } content_encoding = (*it).value().as_string(); } auto value = sch.template as(); return jsoncons::make_unique>(parent, schema_location, context.get_custom_message(keyword), value, content_encoding); } std::unique_ptr> make_format_validator(const compilation_context& context, const Json& sch, const Json& parent) { auto schema_location = context.make_schema_location("format"); std::string format = sch.template as(); std::string message_key; validate_format validate; if (format == "date-time") { message_key = "format.date-time"; validate = rfc3339_date_time_check; } else if (format == "date") { message_key = "format.date"; validate = rfc3339_date_check; } else if (format == "time") { message_key = "format.time"; validate = rfc3339_time_check; } else if (format == "email") { message_key = "format.email"; validate = email_check; } else if (format == "hostname") { message_key = "format.hostname"; validate = hostname_check; } else if (format == "ipv4") { message_key = "format.ipv4"; validate = ipv4_check; } else if (format == "ipv6") { message_key = "format.ipv6"; validate = ipv6_check; } else if (format == "regex") { message_key = "format.regex"; validate = regex_check; } else if (format == "json-pointer") { message_key = "format.json-pointer"; validate = jsonpointer_check; } else if (format == "uri") { message_key = "format.uri"; validate = uri_check; } else if (format == "uri-reference") { message_key = "format.uri-reference"; validate = uri_reference_check; } else { // Not supported - ignore validate = nullptr; } return jsoncons::make_unique>(parent, schema_location, context.get_custom_message(message_key), validate); } std::unique_ptr> make_pattern_validator(const compilation_context& context, const Json& sch, const Json& parent) { uri schema_location = context.make_schema_location("pattern"); auto pattern_string = sch.template as(); auto regex = std::regex(pattern_string, std::regex::ECMAScript); return jsoncons::make_unique>(parent, schema_location, context.get_custom_message("pattern"), pattern_string, regex); } std::unique_ptr> make_max_items_validator(const compilation_context& context, const Json& sch, const Json& parent) { std::string keyword = "maxItems"; uri schema_location = context.make_schema_location(keyword); if (!sch.is_number()) { const std::string message("maxItems must be a number value"); JSONCONS_THROW(schema_error(schema_location.string() + ": " + message)); } auto value = sch.template as(); return jsoncons::make_unique>(parent, schema_location, context.get_custom_message(keyword), value); } std::unique_ptr> make_min_items_validator(const compilation_context& context, const Json& sch, const Json& parent) { std::string keyword = "minItems"; uri schema_location = context.make_schema_location(keyword); if (!sch.is_number()) { const std::string message("minItems must be a number value"); JSONCONS_THROW(schema_error(schema_location.string() + ": " + message)); } auto value = sch.template as(); return jsoncons::make_unique>(parent, schema_location, context.get_custom_message(keyword), value); } std::unique_ptr> make_max_properties_validator(const compilation_context& context, const Json& sch, const Json& parent) { std::string keyword = "maxProperties"; uri schema_location = context.make_schema_location(keyword); if (!sch.is_number()) { const std::string message("maxProperties must be a number value"); JSONCONS_THROW(schema_error(schema_location.string() + ": " + message)); } auto value = sch.template as(); return jsoncons::make_unique>(parent, schema_location, context.get_custom_message(keyword), value); } std::unique_ptr> make_min_properties_validator(const compilation_context& context, const Json& sch, const Json& parent) { std::string keyword = "minProperties"; uri schema_location = context.make_schema_location(keyword); if (!sch.is_number()) { const std::string message("minProperties must be a number value"); JSONCONS_THROW(schema_error(schema_location.string() + ": " + message)); } auto value = sch.template as(); return jsoncons::make_unique>(parent, schema_location, context.get_custom_message(keyword), value); } std::unique_ptr> make_contains_validator(const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict) { uri schema_location = context.make_schema_location("contains"); std::string sub_keys[] = { "contains" }; std::unique_ptr> max_contains; auto it = parent.find("maxContains"); if (it != parent.object_range().end()) { uri path = context.make_schema_location("maxContains"); auto value = (*it).value().template as(); max_contains = jsoncons::make_unique>(parent, path, context.get_custom_message("maxContains"), value); } else { uri path = context.make_schema_location("maxContains"); max_contains = jsoncons::make_unique>(parent, path, context.get_custom_message("maxContains"), (std::numeric_limits::max)()); } std::unique_ptr> min_contains; it = parent.find("minContains"); if (it != parent.object_range().end()) { uri path = context.make_schema_location("minContains"); auto value = (*it).value().template as(); min_contains = jsoncons::make_unique>(parent, path, context.get_custom_message("minContains"), value); } else { uri path = context.make_schema_location("minContains"); min_contains = jsoncons::make_unique>(parent, path, context.get_custom_message("minContains"), 1); } return jsoncons::make_unique>(parent, schema_location, context.get_custom_message("contains"), factory_->make_cross_draft_schema_validator(context, sch, sub_keys, anchor_dict), std::move(max_contains), std::move(min_contains)); } std::unique_ptr> make_unique_items_validator(const compilation_context& context, const Json& sch, const Json& parent) { uri schema_location = context.make_schema_location("uniqueItems"); bool are_unique = sch.template as(); return jsoncons::make_unique>(parent, schema_location, context.get_custom_message("uniqueItems"), are_unique); } std::unique_ptr> make_all_of_validator(const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict) { uri schema_location = context.make_schema_location("allOf"); std::vector subschemas; std::size_t c = 0; for (const auto& subsch : sch.array_range()) { std::string sub_keys[] = { "allOf", std::to_string(c++) }; subschemas.emplace_back(factory_->make_cross_draft_schema_validator(context, subsch, sub_keys, anchor_dict)); } return jsoncons::make_unique>(parent, std::move(schema_location), context.get_custom_message("allOf"), std::move(subschemas)); } std::unique_ptr> make_any_of_validator(const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict) { uri schema_location = context.make_schema_location("anyOf"); std::vector subschemas; std::size_t c = 0; for (const auto& subsch : sch.array_range()) { std::string sub_keys[] = { "anyOf", std::to_string(c++) }; subschemas.emplace_back(factory_->make_cross_draft_schema_validator(context, subsch, sub_keys, anchor_dict)); } return jsoncons::make_unique>(parent, std::move(schema_location), context.get_custom_message("anyOf"), std::move(subschemas)); } std::unique_ptr> make_one_of_validator(const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict) { uri schema_location{ context.make_schema_location("oneOf") }; std::vector subschemas; std::size_t c = 0; for (const auto& subsch : sch.array_range()) { std::string sub_keys[] = { "oneOf", std::to_string(c++) }; subschemas.emplace_back(factory_->make_cross_draft_schema_validator(context, subsch, sub_keys, anchor_dict)); } return jsoncons::make_unique>(parent, std::move(schema_location), context.get_custom_message("oneOf"), std::move(subschemas)); } std::unique_ptr> make_dependencies_validator(const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict) { uri schema_location = context.get_base_uri(); std::map dependent_required; std::map dependent_schemas; //std::cout << "dependencies" << "\n" << pretty_print(sch) << "\n"; for (const auto& dep : sch.object_range()) { switch (dep.value().type()) { case json_type::array_value: { auto location = context.make_schema_location("dependencies"); dependent_required.emplace(dep.key(), this->make_required_validator(compilation_context(std::vector{{uri_wrapper{ location }}}), dep.value(), sch)); break; } case json_type::bool_value: case json_type::object_value: { std::string sub_keys[] = {"dependencies"}; dependent_schemas.emplace(dep.key(), factory_->make_cross_draft_schema_validator(context, dep.value(), sub_keys, anchor_dict)); break; } default: { break; } } } return jsoncons::make_unique>(parent, std::move(schema_location), std::move(dependent_required), std::move(dependent_schemas)); } std::unique_ptr> make_property_names_validator(const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict) { uri schema_location = context.get_base_uri(); schema_validator_ptr_type property_names_schema_validator; std::string sub_keys[] = { "propertyNames"}; property_names_schema_validator = factory_->make_cross_draft_schema_validator(context, sch, sub_keys, anchor_dict); return jsoncons::make_unique>(parent, std::move(schema_location), context.get_custom_message("propertyNames"), std::move(property_names_schema_validator)); } // 201909 and later std::unique_ptr> make_dependent_required_validator( const compilation_context& context, const Json& sch, const Json& parent) { uri schema_location = context.get_base_uri(); std::map dependent_required; for (const auto& dep : sch.object_range()) { switch (dep.value().type()) { case json_type::array_value: { auto location = context.make_schema_location("dependentRequired"); dependent_required.emplace(dep.key(), this->make_required_validator(compilation_context(std::vector{{uri_wrapper{ location }}}), dep.value(), sch)); break; } default: { break; } } } return jsoncons::make_unique>(parent, std::move(schema_location), std::move(dependent_required)); } std::unique_ptr> make_dependent_schemas_validator( const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict) { uri schema_location = context.get_base_uri(); std::map dependent_schemas; for (const auto& dep : sch.object_range()) { switch (dep.value().type()) { case json_type::bool_value: case json_type::object_value: { std::string sub_keys[] = {"dependentSchemas"}; dependent_schemas.emplace(dep.key(), factory_->make_cross_draft_schema_validator(context, dep.value(), sub_keys, anchor_dict)); break; } default: { break; } } } return jsoncons::make_unique>(parent, std::move(schema_location), context.get_custom_message("dependentSchemas"), std::move(dependent_schemas)); } std::unique_ptr> make_prefix_items_validator_07(const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict) { std::vector prefix_item_validators; std::unique_ptr> items_val; uri schema_location{context.make_schema_location("items")}; if (sch.type() == json_type::array_value) { std::size_t c = 0; for (const auto& subsch : sch.array_range()) { std::string sub_keys[] = {"items", std::to_string(c++)}; prefix_item_validators.emplace_back(factory_->make_cross_draft_schema_validator(context, subsch, sub_keys, anchor_dict)); } auto it = parent.find("additionalItems"); if (it != parent.object_range().end()) { uri items_location{context.make_schema_location("additionalItems")}; std::string sub_keys[] = {"additionalItems"}; items_val = jsoncons::make_unique>("additionalItems", parent, items_location, context.get_custom_message("additionalItems"), factory_->make_cross_draft_schema_validator(context, (*it).value(), sub_keys, anchor_dict)); } } return jsoncons::make_unique>("items", parent, schema_location, context.get_custom_message("items"), std::move(prefix_item_validators), std::move(items_val)); } std::unique_ptr> make_items_validator(const std::string& keyword_name, const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict) { uri schema_location{context.make_schema_location(keyword_name)}; std::string sub_keys[] = {keyword_name}; return jsoncons::make_unique>(keyword_name, parent, schema_location, context.get_custom_message(keyword_name), factory_->make_cross_draft_schema_validator(context, sch, sub_keys, anchor_dict)); } std::unique_ptr> make_unevaluated_properties_validator( const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict) { std::string keyword = "unevaluatedProperties"; uri schema_location = context.get_base_uri(); std::string sub_keys[] = {keyword}; return jsoncons::make_unique>(parent, std::move(schema_location), context.get_custom_message(keyword), factory_->make_cross_draft_schema_validator(context, sch, sub_keys, anchor_dict)); } std::unique_ptr> make_unevaluated_items_validator( const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict) { uri schema_location = context.get_base_uri(); std::string sub_keys[] = {"unevaluatedItems"}; return jsoncons::make_unique>(parent, std::move(schema_location), context.get_custom_message("unevaluatedItems"), factory_->make_cross_draft_schema_validator(context, sch, sub_keys, anchor_dict)); } std::unique_ptr> make_additional_properties_validator( const compilation_context& context, const Json& sch, const Json& parent, std::unique_ptr>&& properties, std::unique_ptr>&& pattern_properties, anchor_uri_map_type& anchor_dict) { std::string keyword = "additionalProperties"; uri schema_location = context.get_base_uri(); std::vector validators; schema_validator_ptr_type additional_properties; std::string sub_keys[] = {keyword}; additional_properties = factory_->make_cross_draft_schema_validator(context, sch, sub_keys, anchor_dict); return jsoncons::make_unique>(parent, additional_properties->schema_location(), context.get_custom_message(keyword), std::move(properties), std::move(pattern_properties), std::move(additional_properties)); } // Since 202012 std::unique_ptr> make_prefix_items_validator(const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict) { std::vector prefix_item_validators; std::unique_ptr> items_val; uri schema_location{context.make_schema_location("prefixItems")}; if (sch.type() == json_type::array_value) { std::size_t c = 0; for (const auto& subsch : sch.array_range()) { std::string sub_keys[] = {"prefixItems", std::to_string(c++)}; prefix_item_validators.emplace_back(factory_->make_cross_draft_schema_validator(context, subsch, sub_keys, anchor_dict)); } auto it = parent.find("items"); if (it != parent.object_range().end()) { uri items_location{context.make_schema_location("items")}; std::string sub_keys[] = { "additionalItems" }; items_val = jsoncons::make_unique>("items", parent, items_location, context.get_custom_message("items"), factory_->make_cross_draft_schema_validator(context, (*it).value(), sub_keys, anchor_dict)); } } return jsoncons::make_unique>("prefixItems", parent, schema_location, context.get_custom_message("prefixItems"), std::move(prefix_item_validators), std::move(items_val)); } }; } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_COMMON_SCHEMA_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/common/schema_validator.hpp000066400000000000000000000441301477700171100271570ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_COMMON_SCHEMA_VALIDATOR_HPP #define JSONCONS_EXT_JSONSCHEMA_COMMON_SCHEMA_VALIDATOR_HPP #include #include #include #include #include #include #include #include namespace jsoncons { namespace jsonschema { template class schema_validator : public validator_base { public: using walk_reporter_type = typename json_schema_traits::walk_reporter_type; using schema_validator_ptr_type = typename std::unique_ptr>; public: schema_validator() {} virtual jsoncons::optional get_default_value() const = 0; virtual bool recursive_anchor() const = 0; virtual const jsoncons::optional& id() const = 0; virtual const schema_validator* get_schema_for_dynamic_anchor(const std::string& anchor) const = 0; virtual const jsoncons::optional& dynamic_anchor() const = 0; }; template class document_schema_validator : public schema_validator { using schema_validator_ptr_type = std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; std::unique_ptr root_schema_; schema_validator_ptr_type schema_val_; std::vector schemas_; public: document_schema_validator(std::unique_ptr&& root_schema, schema_validator_ptr_type&& schema_val, std::vector&& schemas) : root_schema_(std::move(root_schema)), schema_val_(std::move(schema_val)), schemas_(std::move(schemas)) { if (schema_val_ == nullptr) JSONCONS_THROW(schema_error("There is no schema to validate an instance against")); } document_schema_validator(const document_schema_validator&) = delete; document_schema_validator(document_schema_validator&&) = default; document_schema_validator& operator=(const document_schema_validator&) = delete; document_schema_validator& operator=(document_schema_validator&&) = default; jsoncons::optional get_default_value() const final { return schema_val_->get_default_value(); } const uri& schema_location() const final { return schema_val_->schema_location(); } bool recursive_anchor() const final { return schema_val_->recursive_anchor(); } const jsoncons::optional& id() const final { return schema_val_->id(); } const jsoncons::optional& dynamic_anchor() const final { return schema_val_->dynamic_anchor(); } const schema_validator* get_schema_for_dynamic_anchor(const std::string& anchor) const final { return schema_val_->get_schema_for_dynamic_anchor(anchor); } bool always_fails() const final { return schema_val_->always_fails(); } bool always_succeeds() const final { return schema_val_->always_succeeds(); } walk_result walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const { return do_walk(context, instance, instance_location, reporter); } private: walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const { JSONCONS_ASSERT(schema_val_ != nullptr); return schema_val_->validate(context, instance, instance_location, results, reporter, patch); } walk_result do_walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { JSONCONS_ASSERT(schema_val_ != nullptr); return schema_val_->walk(context, instance, instance_location, reporter); } }; template class boolean_schema_validator : public schema_validator { public: using schema_validator_ptr_type = typename std::unique_ptr>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; uri schema_location_; bool value_; jsoncons::optional id_; jsoncons::optional dynamic_anchor_; public: boolean_schema_validator(const boolean_schema_validator&) = delete; boolean_schema_validator& operator=(const boolean_schema_validator&) = delete; boolean_schema_validator(boolean_schema_validator&&) = default; boolean_schema_validator& operator=(boolean_schema_validator&&) = default; boolean_schema_validator(const uri& schema_location, bool value) : schema_location_(schema_location), value_(value) { } jsoncons::optional get_default_value() const final { return jsoncons::optional{}; } const uri& schema_location() const final { return schema_location_; } bool recursive_anchor() const final { return false; } const jsoncons::optional& id() const final { return id_; } const jsoncons::optional& dynamic_anchor() const final { return dynamic_anchor_; } const schema_validator* get_schema_for_dynamic_anchor(const std::string& /*anchor*/) const final { return nullptr; } bool always_fails() const final { return !value_; } bool always_succeeds() const final { return value_; } private: walk_result do_validate(const eval_context& context, const Json&, const jsonpointer::json_pointer& instance_location, evaluation_results& /*results*/, error_reporter& reporter, Json& /*patch*/) const final { if (!value_) { reporter.error(validation_message("false", context.eval_path(), this->schema_location(), instance_location, "False schema always fails")); } return walk_result::advance; } walk_result do_walk(const eval_context& /*context*/, const Json& /*instance*/, const jsonpointer::json_pointer& /*instance_location*/, const walk_reporter_type& /*reporter*/) const final { return walk_result::advance; } }; template class object_schema_validator : public schema_validator { public: using schema_validator_ptr_type = typename std::unique_ptr>; using keyword_validator_ptr_type = typename std::unique_ptr>; using anchor_schema_map_type = std::unordered_map>>; using walk_reporter_type = typename json_schema_traits::walk_reporter_type; uri schema_location_; jsoncons::optional id_; std::vector validators_; std::unique_ptr> unevaluated_properties_val_; std::unique_ptr> unevaluated_items_val_; std::map defs_; Json default_value_; bool recursive_anchor_; jsoncons::optional dynamic_anchor_; anchor_schema_map_type anchor_dict_; bool always_succeeds_; bool always_fails_; public: object_schema_validator(const object_schema_validator&) = delete; object_schema_validator& operator=(const object_schema_validator&) = delete; object_schema_validator(object_schema_validator&&) = default; object_schema_validator& operator=(object_schema_validator&&) = default; object_schema_validator(const uri& schema_location, const jsoncons::optional& id, std::vector&& validators, std::map&& defs, Json&& default_value) : schema_location_(schema_location), id_(id), validators_(std::move(validators)), defs_(std::move(defs)), default_value_(std::move(default_value)), recursive_anchor_(false), always_succeeds_(false), always_fails_(false) { init(); } object_schema_validator(const uri& schema_location, const jsoncons::optional& id, std::vector&& validators, std::unique_ptr>&& unevaluated_properties_val, std::unique_ptr>&& unevaluated_items_val, std::map&& defs, Json&& default_value, bool recursive_anchor) : schema_location_(schema_location), id_(id), validators_(std::move(validators)), unevaluated_properties_val_(std::move(unevaluated_properties_val)), unevaluated_items_val_(std::move(unevaluated_items_val)), defs_(std::move(defs)), default_value_(std::move(default_value)), recursive_anchor_(recursive_anchor), always_succeeds_(false), always_fails_(false) { init(); } object_schema_validator(const uri& schema_location, const jsoncons::optional& id, std::vector&& validators, std::unique_ptr>&& unevaluated_properties_val, std::unique_ptr>&& unevaluated_items_val, std::map&& defs, Json&& default_value, jsoncons::optional&& dynamic_anchor, anchor_schema_map_type&& anchor_dict) : schema_location_(schema_location), id_(std::move(id)), validators_(std::move(validators)), unevaluated_properties_val_(std::move(unevaluated_properties_val)), unevaluated_items_val_(std::move(unevaluated_items_val)), defs_(std::move(defs)), default_value_(std::move(default_value)), recursive_anchor_(false), dynamic_anchor_(std::move(dynamic_anchor)), anchor_dict_(std::move(anchor_dict)), always_succeeds_(false), always_fails_(false) { init(); } jsoncons::optional get_default_value() const override { return default_value_; } const uri& schema_location() const override { return schema_location_; } bool recursive_anchor() const final { return recursive_anchor_; } const jsoncons::optional& id() const final { return id_; } const schema_validator* get_schema_for_dynamic_anchor(const std::string& anchor) const final { auto it = anchor_dict_.find(anchor); return (it == anchor_dict_.end()) ? nullptr : (*it).second->referred_schema(); } const jsoncons::optional& dynamic_anchor() const final { return dynamic_anchor_; } bool always_fails() const final { return always_fails_; } bool always_succeeds() const final { return always_succeeds_; } private: void init() { if (!(unevaluated_properties_val_ || unevaluated_items_val_)) { std::size_t always_fails_count = 0; std::size_t always_succeeds_count = 0; for (const auto& val : validators_) { if (val->always_fails()) { ++always_fails_count; } if (val->always_succeeds()) { ++always_succeeds_count; } } always_succeeds_ = always_succeeds_count == validators_.size(); // empty schema always succeeds always_fails_ = validators_.size() > 0 && (always_fails_count == validators_.size()); } } walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const final { //std::cout << "object_schema_validator begin[" << context.eval_path().string() << "," << this->schema_location().string() << "]"; //std::cout << "results:\n"; //for (const auto& s : results) //{ // std::cout << " " << s << "\n"; //} //std::cout << "\n"; evaluation_results local_results; evaluation_flags flags = context.eval_flags(); if (unevaluated_properties_val_) { flags |= evaluation_flags::require_evaluated_properties; } if (unevaluated_items_val_) { flags |= evaluation_flags::require_evaluated_items; } eval_context this_context{context, this, flags}; //std::cout << "validators:\n"; for (auto& val : validators_) { //std::cout << " " << val->keyword_name() << "\n"; walk_result result = val->validate(this_context, instance, instance_location, local_results, reporter, patch); if (result == walk_result::abort) { return result; } } if (unevaluated_properties_val_) { walk_result result = unevaluated_properties_val_->validate(this_context, instance, instance_location, local_results, reporter, patch); if (result == walk_result::abort) { return result; } } if (unevaluated_items_val_) { walk_result result = unevaluated_items_val_->validate(this_context, instance, instance_location, local_results, reporter, patch); if (result == walk_result::abort) { return result; } } if ((context.eval_flags() & evaluation_flags::require_evaluated_properties) == evaluation_flags::require_evaluated_properties) { results.merge(std::move(local_results.evaluated_properties)); } if ((context.eval_flags() & evaluation_flags::require_evaluated_items) == evaluation_flags::require_evaluated_items) { results.merge(std::move(local_results.evaluated_items)); } //std::cout << "object_schema_validator end[" << context.eval_path().string() << "," << this->schema_location().string() << "]"; //std::cout << "results:\n"; //for (const auto& s : results) //{ // std::cout << " " << s << "\n"; //} //std::cout << "\n"; return walk_result::advance; } walk_result do_walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const final { eval_context this_context{context, this}; for (auto& val : validators_) { //std::cout << " " << val->keyword_name() << "\n"; walk_result result = val->walk(this_context, instance, instance_location, reporter); if (result == walk_result::abort) { return result; } } if (unevaluated_properties_val_) { walk_result result = unevaluated_properties_val_->walk(this_context, instance, instance_location, reporter); if (result == walk_result::abort) { return result; } } if (unevaluated_items_val_) { walk_result result = unevaluated_items_val_->walk(this_context, instance, instance_location, reporter); if (result == walk_result::abort) { return result; } } return walk_result::advance; } }; } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_KEYWORD_VALIDATOR_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/common/schema_validator_factory_base.hpp000066400000000000000000000347221477700171100317060ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_COMMON_SCHEMA_VALIDATOR_FACTORY_BASE_HPP #define JSONCONS_EXT_JSONSCHEMA_COMMON_SCHEMA_VALIDATOR_FACTORY_BASE_HPP #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace jsonschema { template using resolve_uri_type = std::function; template class schema_validator_factory_base { public: using schema_store_type = std::map*>; using validator_factory_factory_type = std::function>(const Json&, const evaluation_options&,schema_store_type*,const std::vector>&, const std::unordered_map&)>; using schema_validator_ptr_type = typename std::unique_ptr>; using ref_validator_type = ref_validator; using ref_type = ref; using anchor_uri_map_type = std::unordered_map; private: std::string spec_version_; std::unique_ptr root_schema_; validator_factory_factory_type factory_factory_; evaluation_options options_; schema_store_type* schema_store_ptr_; std::vector> resolve_funcs_; std::unordered_map vocabulary_; schema_validator_ptr_type root_; // Owns external schemas std::vector schema_validators_; protected: std::vector> unresolved_refs_; std::map unknown_keywords_; public: schema_validator_factory_base(const std::string& version, Json&& root_schema, const validator_factory_factory_type& factory_factory, evaluation_options options, schema_store_type* schema_store_ptr, const std::vector>& resolve_funcs) : spec_version_(version), factory_factory_(factory_factory), options_(std::move(options)), schema_store_ptr_(schema_store_ptr), resolve_funcs_(resolve_funcs) { JSONCONS_ASSERT(schema_store_ptr != nullptr); root_schema_ = jsoncons::make_unique(std::move(root_schema)); } schema_validator_factory_base(const std::string& version, Json&& root_schema, const validator_factory_factory_type& factory_factory, evaluation_options options, schema_store_type* schema_store_ptr, const std::vector>& resolve_funcs, const std::unordered_map& vocabulary) : spec_version_(version), factory_factory_(factory_factory), options_(std::move(options)), schema_store_ptr_(schema_store_ptr), resolve_funcs_(resolve_funcs), vocabulary_(vocabulary) { JSONCONS_ASSERT(schema_store_ptr != nullptr); root_schema_ = jsoncons::make_unique(std::move(root_schema)); } virtual ~schema_validator_factory_base() = default; const std::unordered_map& vocabulary() const {return vocabulary_;} void save_schema(schema_validator_ptr_type&& schema) { schema_validators_.emplace_back(std::move(schema)); } const std::string& schema() const { return spec_version_; } void build_schema() { anchor_uri_map_type anchor_dict; root_ = make_schema_validator(compilation_context(uri_wrapper(options_.default_base_uri())), *root_schema_, {}, anchor_dict); } void build_schema(const std::string& retrieval_uri) { anchor_uri_map_type anchor_dict; root_ = make_schema_validator(compilation_context(uri_wrapper(retrieval_uri)), *root_schema_, {}, anchor_dict); } evaluation_options options() const { return options_; } schema_validator_ptr_type make_boolean_schema(const compilation_context& context, const Json& sch) { uri schema_location = context.get_base_uri(); schema_validator_ptr_type schema_validator_ptr = jsoncons::make_unique>( schema_location, sch.template as()); return schema_validator_ptr; } std::unique_ptr> get_schema_validator() { //std::cout << "schema_store:\n"; //for (auto& member : *schema_store_ptr_) //{ // std::cout << " " << member.first.string() << "\n"; //} // load all external schemas that have not already been loaded // new unresolved refs may be added to the end as earlier ones are resolved for (std::size_t i = 0; i < unresolved_refs_.size(); ++i) { auto loc = unresolved_refs_[i].first; //std::cout << "unresolved: " << loc.string() << "\n"; if (schema_store_ptr_->find(loc) == schema_store_ptr_->end()) // registry for this file is empty { bool found = false; for (auto it = resolve_funcs_.begin(); it != resolve_funcs_.end() && !found; ++it) { Json external_sch = (*it)(loc); if (external_sch.is_object() || external_sch.is_bool()) { anchor_uri_map_type anchor_dict2; this->save_schema(make_cross_draft_schema_validator(compilation_context(uri_wrapper(loc.base())), std::move(external_sch), {}, anchor_dict2)); found = true; } } if (found) { // Try resolving again if (schema_store_ptr_->find(loc) == schema_store_ptr_->end()) { JSONCONS_THROW(jsonschema::schema_error("Unresolved reference '" + loc.string() + "'")); } } else { JSONCONS_THROW(jsonschema::schema_error("Don't know how to load JSON Schema '" + loc.base().string() + "'" )); } } } resolve_references(); return jsoncons::make_unique>(std::move(root_schema_), std::move(root_), std::move(schema_validators_)); } void resolve_references() { for (auto& ref : unresolved_refs_) { auto it = schema_store_ptr_->find(ref.first); if (it == schema_store_ptr_->end()) { JSONCONS_THROW(schema_error("Undefined reference " + ref.first.string())); } if ((*it).second == nullptr) { JSONCONS_THROW(schema_error("Null referred schema " + ref.first.string())); } ref.second->set_referred_schema((*it).second); } } void insert_schema(const uri_wrapper& identifier, schema_validator* s) { this->schema_store_ptr_->emplace(identifier.uri(), s); } void insert_unknown_keyword(const uri_wrapper& uri, const std::string& key, const Json& value) { auto new_u = uri.append(key); uri_wrapper new_uri(new_u); if (new_uri.has_fragment() && !new_uri.has_plain_name_fragment()) { // is there a reference looking for this unknown-keyword, which is thus no longer a unknown keyword but a schema auto unresolved_refs = std::find_if(this->unresolved_refs_.begin(), this->unresolved_refs_.end(), [new_uri](const std::pair*>& pr) {return pr.first == new_uri.uri();}); if (unresolved_refs != this->unresolved_refs_.end()) { anchor_uri_map_type anchor_dict2; this->save_schema(make_cross_draft_schema_validator(compilation_context(new_uri), value, {}, anchor_dict2)); } else // no, nothing ref'd it, keep for later { //file.unknown_keywords.emplace(fragment, value); this->unknown_keywords_.emplace(new_uri.uri(), value); } // recursively add possible subschemas of unknown keywords if (value.type() == json_type::object_value) { for (const auto& subsch : value.object_range()) { insert_unknown_keyword(new_uri, subsch.key(), subsch.value()); } } } } std::unique_ptr> get_or_create_reference(const Json& schema, const uri_wrapper& identifier) { // a schema already exists auto it = this->schema_store_ptr_->find(identifier.uri()); if (it != this->schema_store_ptr_->end()) { return jsoncons::make_unique(schema, identifier.uri(), (*it).second); } // referencing an unknown keyword, turn it into schema // // an unknown keyword can only be referenced by a JSONPointer, // not by a plain name identifier if (identifier.has_fragment() && !identifier.has_plain_name_fragment()) { //std::string fragment = std::string(identifier.fragment()); auto it2 = this->unknown_keywords_.find(identifier.uri()); if (it2 != this->unknown_keywords_.end()) { auto& subsch = it2->second; anchor_uri_map_type anchor_dict2; auto s = make_cross_draft_schema_validator(compilation_context(identifier), subsch, {}, anchor_dict2); this->unknown_keywords_.erase(it2); auto orig = jsoncons::make_unique(schema, identifier.uri(), s.get()); this->save_schema(std::move(s)); return orig; } } // get or create a ref_validator auto orig = jsoncons::make_unique(schema, identifier.uri()); this->unresolved_refs_.emplace_back(identifier.uri(), orig.get()); return orig; } static bool validate_anchor(const std::string& s) { if (s.empty()) { return false; } if (!((s[0] >= 'a' && s[0] <= 'z') || (s[0] >= 'A' && s[0] <= 'Z'))) { return false; } for (std::size_t i = 1; i < s.size(); ++i) { switch (s[i]) { case '-': case '_': case ':': case '.': break; default: if (!((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z') || (s[i] >= '0' && s[i] <= '9'))) { return false; } break; } } return true; } virtual compilation_context make_compilation_context(const compilation_context& parent, const Json& sch, jsoncons::span keys) const = 0; virtual schema_validator_ptr_type make_schema_validator(const compilation_context& context, const Json& sch, jsoncons::span keys, anchor_uri_map_type& anchor_dict) = 0; schema_validator_ptr_type make_cross_draft_schema_validator(const compilation_context& context, const Json& sch, jsoncons::span keys, anchor_uri_map_type& anchor_dict) { schema_validator_ptr_type schema_val = schema_validator_ptr_type{}; switch (sch.type()) { case json_type::object_value: { auto it = sch.find("$schema"); if (it != sch.object_range().end()) { if ((*it).value().as_string_view() == schema()) { return make_schema_validator(context, std::move(sch), keys, anchor_dict); } else { auto schema_validator_factory_base = factory_factory_(std::move(sch), options_, schema_store_ptr_, resolve_funcs_, vocabulary_); schema_validator_factory_base->build_schema(context.get_base_uri().string()); schema_val = schema_validator_factory_base->get_schema_validator(); } } else { return make_schema_validator(context, std::move(sch), keys, anchor_dict); } break; } case json_type::bool_value: { return make_schema_validator(context, std::move(sch), keys, anchor_dict); } default: JSONCONS_THROW(schema_error("Schema must be object or boolean")); } return schema_val; } }; } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_COMMON_SCHEMA_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/common/uri_wrapper.hpp000066400000000000000000000111761477700171100262150ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_COMMON_URI_WRAPPER_HPP #define JSONCONS_EXT_JSONSCHEMA_COMMON_URI_WRAPPER_HPP #include #include #include #include #include #include #include #include namespace jsoncons { namespace jsonschema { class uri_wrapper { jsoncons::uri uri_; std::string identifier_; bool has_plain_name_fragment_; public: uri_wrapper() : has_plain_name_fragment_(false) { } explicit uri_wrapper(const std::string& uri) { uri_ = jsoncons::uri(uri); if (!uri_.encoded_fragment().empty()) { identifier_ = uri_.fragment(); std::error_code ec; jsonpointer::json_pointer::parse(identifier_, ec); has_plain_name_fragment_ = ec ? true : false; } else { has_plain_name_fragment_ = false; } } explicit uri_wrapper(const uri& uri) : uri_{uri} { uri_ = jsoncons::uri(uri); if (!uri_.encoded_fragment().empty()) { identifier_ = uri_.fragment(); std::error_code ec; jsonpointer::json_pointer::parse(identifier_, ec); has_plain_name_fragment_ = ec ? true : false; } else { has_plain_name_fragment_ = false; } } const jsoncons::uri& uri() const { return uri_; } bool has_fragment() const { return !uri_.encoded_fragment().empty(); } bool has_plain_name_fragment() const { return has_plain_name_fragment_; } jsoncons::uri base() const { return uri_.base(); } std::string path() const { return uri_.path(); } bool is_absolute() const { return uri_.is_absolute(); } std::string fragment() const { return identifier_; } int compare(const uri_wrapper& other) const { int result = uri_.compare(other.uri_); if (result != 0) { return result; } return result; } uri_wrapper append(const std::string& field) const { if (has_plain_name_fragment()) return *this; jsoncons::jsonpointer::json_pointer pointer(std::string(uri_.fragment())); pointer /= field; jsoncons::uri new_uri(uri_, uri_fragment_part, pointer.to_string()); return uri_wrapper(std::move(new_uri)); } uri_wrapper append(std::size_t index) const { if (has_plain_name_fragment()) return *this; jsoncons::jsonpointer::json_pointer pointer(std::string(uri_.encoded_fragment())); pointer /= index; jsoncons::uri new_uri(uri_, uri_fragment_part, pointer.to_string()); return uri_wrapper(std::move(new_uri)); } std::string string() const { std::string s = uri_.string(); return s; } friend bool operator==(const uri_wrapper& lhs, const uri_wrapper& rhs) { return lhs.compare(rhs) == 0; } friend bool operator!=(const uri_wrapper& lhs, const uri_wrapper& rhs) { return lhs.compare(rhs) != 0; } friend bool operator<(const uri_wrapper& lhs, const uri_wrapper& rhs) { return lhs.compare(rhs) < 0; } friend bool operator<=(const uri_wrapper& lhs, const uri_wrapper& rhs) { return lhs.compare(rhs) <= 0; } friend bool operator>(const uri_wrapper& lhs, const uri_wrapper& rhs) { return lhs.compare(rhs) > 0; } friend bool operator>=(const uri_wrapper& lhs, const uri_wrapper& rhs) { return lhs.compare(rhs) >= 0; } private: }; } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_COMMON_URI_WRAPPER_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/common/validator.hpp000066400000000000000000000162601477700171100256420ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_COMMON_VALIDATOR_HPP #define JSONCONS_EXT_JSONSCHEMA_COMMON_VALIDATOR_HPP #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace jsonschema { enum class walk_result {advance, abort}; template struct json_schema_traits { using walk_reporter_type = std::function; }; // Interface for validation error handlers class error_reporter { std::size_t error_count_{0}; public: error_reporter() { } virtual ~error_reporter() = default; walk_result error(const validation_message& msg) { ++error_count_; return do_error(msg); } std::size_t error_count() const { return error_count_; } private: virtual walk_result do_error(const validation_message& /* e */) = 0; }; struct collecting_error_listener : public error_reporter { std::vector errors; private: walk_result do_error(const validation_message& msg) final { errors.push_back(msg); return walk_result::advance; } }; class range { std::size_t start_{0}; std::size_t end_{0}; public: range() { } range(std::size_t start, std::size_t end) : start_(start), end_(end) { } std::size_t start() const { return start_; } std::size_t end() const { return end_; } bool contains(std::size_t index) const { return index >= start_ && index < end_; } }; class range_collection { std::vector ranges_; public: using const_iterator = std::vector::const_iterator; using value_type = range; range_collection() { } range_collection(const range_collection& other) = default; range_collection(range_collection&& other) = default; range_collection& operator=(const range_collection& other) = default; range_collection& operator=(range_collection&& other) = default; std::size_t size() const { return ranges_.size(); } range operator[](std::size_t index) const { return ranges_[index]; } const_iterator begin() const { return ranges_.cbegin(); } const_iterator end() const { return ranges_.cend(); } void insert(range index_range) { ranges_.push_back(index_range); } bool contains(std::size_t index) const { bool found = false; std::size_t length = ranges_.size(); for (std::size_t i = 0; i < length && !found; ++i) { if (ranges_[i].contains(index)) { found = true; } } return found; } }; struct evaluation_results { std::unordered_set evaluated_properties; range_collection evaluated_items; void merge(const evaluation_results& results) { for (auto&& name : results.evaluated_properties) { evaluated_properties.insert(name); } for (auto index_range : results.evaluated_items) { evaluated_items.insert(index_range); } } void merge(std::unordered_set&& properties) { auto end = std::make_move_iterator(properties.end()); for (auto it = std::make_move_iterator(properties.begin()); it != end; ++it) { evaluated_properties.insert(*it); } } void merge(const range_collection& ranges) { for (auto index_range : ranges) { evaluated_items.insert(index_range); } } }; template class validator_base { public: using walk_reporter_type = typename json_schema_traits::walk_reporter_type; virtual ~validator_base() = default; virtual const uri& schema_location() const = 0; walk_result validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const { return do_validate(context, instance, instance_location, results, reporter, patch); } walk_result walk(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const { return do_walk(context, instance, instance_location, reporter); } virtual bool always_fails() const = 0; virtual bool always_succeeds() const = 0; private: virtual walk_result do_validate(const eval_context& context, const Json& instance, const jsonpointer::json_pointer& instance_location, evaluation_results& results, error_reporter& reporter, Json& patch) const = 0; virtual walk_result do_walk(const eval_context& /*context*/, const Json& instance, const jsonpointer::json_pointer& instance_location, const walk_reporter_type& reporter) const = 0; }; class validation_message_factory { public: virtual ~validation_message_factory() = default; virtual validation_message make_validation_message(const jsonpointer::json_pointer& eval_path, const jsonpointer::json_pointer& instance_location, const std::string& message) const = 0; virtual validation_message make_validation_message(const jsonpointer::json_pointer& eval_path, const jsonpointer::json_pointer& instance_location, const std::string& message, const std::vector& details) const = 0; }; } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_KEYWORD_VALIDATOR_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/draft201909/000077500000000000000000000000001477700171100234345ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons_ext/jsonschema/draft201909/schema_draft201909.hpp000066400000000000000000000256631477700171100272660ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_DRAFT201909_SCHEMA_DRAFT201909_HPP #define JSONCONS_EXT_JSONSCHEMA_DRAFT201909_SCHEMA_DRAFT201909_HPP namespace jsoncons { namespace jsonschema { namespace draft201909 { template struct schema_draft201909 { static Json get_schema() { static Json sch = Json::parse(R"( { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://json-schema.org/draft/2019-09/schema", "$vocabulary": { "https://json-schema.org/draft/2019-09/vocab/core": true, "https://json-schema.org/draft/2019-09/vocab/applicator": true, "https://json-schema.org/draft/2019-09/vocab/validation": true, "https://json-schema.org/draft/2019-09/vocab/meta-data": true, "https://json-schema.org/draft/2019-09/vocab/format": false, "https://json-schema.org/draft/2019-09/vocab/content": true }, "$recursiveAnchor": true, "title": "Core and Validation specifications meta-schema", "allOf": [ { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://json-schema.org/draft/2019-09/meta/core", "$vocabulary": { "https://json-schema.org/draft/2019-09/vocab/core": true }, "$recursiveAnchor": true, "title": "Core vocabulary meta-schema", "type": ["object", "boolean"], "properties": { "$id": { "type": "string", "format": "uri-reference", "$comment": "Non-empty fragments not allowed.", "pattern": "^[^#]*#?$" }, "$schema": { "type": "string", "format": "uri" }, "$anchor": { "type": "string", "pattern": "^[A-Za-z][-A-Za-z0-9.:_]*$" }, "$ref": { "type": "string", "format": "uri-reference" }, "$recursiveRef": { "type": "string", "format": "uri-reference" }, "$recursiveAnchor": { "type": "boolean", "default": false }, "$vocabulary": { "type": "object", "propertyNames": { "type": "string", "format": "uri" }, "additionalProperties": { "type": "boolean" } }, "$comment": { "type": "string" }, "$defs": { "type": "object", "additionalProperties": {"$recursiveRef": "#"}, "default": {} } } }, { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://json-schema.org/draft/2019-09/meta/applicator", "$vocabulary": { "https://json-schema.org/draft/2019-09/vocab/applicator": true }, "$recursiveAnchor": true, "title": "Applicator vocabulary meta-schema", "type": ["object", "boolean"], "properties": { "additionalItems": {"$recursiveRef": "#"}, "unevaluatedItems": {"$recursiveRef": "#"}, "items": { "anyOf": [{"$recursiveRef": "#"}, {"$ref": "#/$defs/schemaArray"}] }, "contains": {"$recursiveRef": "#"}, "additionalProperties": {"$recursiveRef": "#"}, "unevaluatedProperties": {"$recursiveRef": "#"}, "properties": { "type": "object", "additionalProperties": {"$recursiveRef": "#"}, "default": {} }, "patternProperties": { "type": "object", "additionalProperties": {"$recursiveRef": "#"}, "propertyNames": {"format": "regex"}, "default": {} }, "dependentSchemas": { "type": "object", "additionalProperties": { "$recursiveRef": "#" } }, "propertyNames": {"$recursiveRef": "#"}, "if": {"$recursiveRef": "#"}, "then": {"$recursiveRef": "#"}, "else": {"$recursiveRef": "#"}, "allOf": {"$ref": "#/$defs/schemaArray"}, "anyOf": {"$ref": "#/$defs/schemaArray"}, "oneOf": {"$ref": "#/$defs/schemaArray"}, "not": {"$recursiveRef": "#"} }, "$defs": { "schemaArray": { "type": "array", "minItems": 1, "items": {"$recursiveRef": "#"} } } }, { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://json-schema.org/draft/2019-09/meta/validation", "$vocabulary": { "https://json-schema.org/draft/2019-09/vocab/validation": true }, "$recursiveAnchor": true, "title": "Validation vocabulary meta-schema", "type": ["object", "boolean"], "properties": { "multipleOf": { "type": "number", "exclusiveMinimum": 0 }, "maximum": { "type": "number" }, "exclusiveMaximum": { "type": "number" }, "minimum": { "type": "number" }, "exclusiveMinimum": { "type": "number" }, "maxLength": {"$ref": "#/$defs/nonNegativeInteger"}, "minLength": {"$ref": "#/$defs/nonNegativeIntegerDefault0"}, "pattern": { "type": "string", "format": "regex" }, "maxItems": {"$ref": "#/$defs/nonNegativeInteger"}, "minItems": {"$ref": "#/$defs/nonNegativeIntegerDefault0"}, "uniqueItems": { "type": "boolean", "default": false }, "maxContains": {"$ref": "#/$defs/nonNegativeInteger"}, "minContains": { "$ref": "#/$defs/nonNegativeInteger", "default": 1 }, "maxProperties": {"$ref": "#/$defs/nonNegativeInteger"}, "minProperties": {"$ref": "#/$defs/nonNegativeIntegerDefault0"}, "required": {"$ref": "#/$defs/stringArray"}, "dependentRequired": { "type": "object", "additionalProperties": { "$ref": "#/$defs/stringArray" } }, "const": true, "enum": { "type": "array", "items": true }, "type": { "anyOf": [ {"$ref": "#/$defs/simpleTypes"}, { "type": "array", "items": {"$ref": "#/$defs/simpleTypes"}, "minItems": 1, "uniqueItems": true } ] } }, "$defs": { "nonNegativeInteger": { "type": "integer", "minimum": 0 }, "nonNegativeIntegerDefault0": { "$ref": "#/$defs/nonNegativeInteger", "default": 0 }, "simpleTypes": { "enum": ["array", "boolean", "integer", "null", "number", "object", "string"] }, "stringArray": { "type": "array", "items": {"type": "string"}, "uniqueItems": true, "default": [] } } }, { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://json-schema.org/draft/2019-09/meta/meta-data", "$vocabulary": { "https://json-schema.org/draft/2019-09/vocab/meta-data": true }, "$recursiveAnchor": true, "title": "Meta-data vocabulary meta-schema", "type": ["object", "boolean"], "properties": { "title": { "type": "string" }, "description": { "type": "string" }, "default": true, "deprecated": { "type": "boolean", "default": false }, "readOnly": { "type": "boolean", "default": false }, "writeOnly": { "type": "boolean", "default": false }, "examples": { "type": "array", "items": true } } }, { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://json-schema.org/draft/2019-09/meta/format", "$vocabulary": { "https://json-schema.org/draft/2019-09/vocab/format": true }, "$recursiveAnchor": true, "title": "Format vocabulary meta-schema", "type": ["object", "boolean"], "properties": { "format": {"type": "string"} } }, { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://json-schema.org/draft/2019-09/meta/content", "$vocabulary": { "https://json-schema.org/draft/2019-09/vocab/content": true }, "$recursiveAnchor": true, "title": "Content vocabulary meta-schema", "type": ["object", "boolean"], "properties": { "contentMediaType": {"type": "string"}, "contentEncoding": {"type": "string"}, "contentSchema": {"$recursiveRef": "#"} } } ], "type": ["object", "boolean"], "properties": { "definitions": { "$comment": "While no longer an official keyword as it is replaced by $defs, this keyword is retained in the meta-schema to prevent incompatible extensions as it remains in common use.", "type": "object", "additionalProperties": { "$recursiveRef": "#" }, "default": {} }, "dependencies": { "$comment": "\"dependencies\" is no longer a keyword, but schema authors should avoid redefining it to facilitate a smooth transition to \"dependentSchemas\" and \"dependentRequired\"", "type": "object", "additionalProperties": { "anyOf": [ { "$recursiveRef": "#" }, { "$ref": "meta/validation#/$defs/stringArray" } ] } } } } )"); return sch; } }; } // namespace draft201909 } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_DRAFT201909_SCHEMA_DRAFT201909_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/draft201909/schema_validator_factory_201909.hpp000066400000000000000000000672621477700171100320420ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_DRAFT201909_SCHEMA_VALIDATOR_FACTORY_201909_HPP #define JSONCONS_EXT_JSONSCHEMA_DRAFT201909_SCHEMA_VALIDATOR_FACTORY_201909_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(JSONCONS_HAS_STD_REGEX) #include #endif namespace jsoncons { namespace jsonschema { namespace draft201909 { template class schema_validator_factory_201909 : public schema_validator_factory_base { public: using schema_store_type = typename schema_validator_factory_base::schema_store_type; using validator_factory_factory_type = typename schema_validator_factory_base::validator_factory_factory_type; using keyword_validator_ptr_type = typename std::unique_ptr>; using schema_validator_ptr_type = typename std::unique_ptr>; using recursive_ref_validator_type = recursive_ref_validator; using anchor_uri_map_type = std::unordered_map; using keyword_factory_type = std::function& context, const Json& sch, const Json& parent, anchor_uri_map_type&)>; std::unordered_map validation_factory_map_; static const std::string& core_id() { static std::string id = "https://json-schema.org/draft/2019-09/vocab/core"; return id; } static const std::string& applicator_id() { static std::string id = "https://json-schema.org/draft/2019-09/vocab/applicator"; return id; } static const std::string& unevaluated_id() { static std::string id = "https://json-schema.org/draft/2019-09/vocab/unevaluated"; return id; } static const std::string& validation_id() { static std::string id = "https://json-schema.org/draft/2019-09/vocab/validation"; return id; } static const std::string& meta_data_id() { static std::string id = "https://json-schema.org/draft/2019-09/vocab/meta-data"; return id; } static const std::string& format_annotation_id() { static std::string id = "https://json-schema.org/draft/2019-09/format-annotation"; return id; } static const std::string& content_id() { static std::string id = "https://json-schema.org/draft/2019-09/vocab/content"; return id; } bool include_applicator_{true}; bool include_unevaluated_{true}; bool include_validation_{true}; bool include_format_{true}; keyword_validator_factory factory_; public: schema_validator_factory_201909(Json&& sch, const validator_factory_factory_type& factory_factory, evaluation_options options, schema_store_type* schema_store_ptr, const std::vector>& resolve_funcs, const std::unordered_map& vocabulary) noexcept : schema_validator_factory_base(schema_version::draft201909(), std::move(sch), factory_factory, options, schema_store_ptr, resolve_funcs, vocabulary), factory_(this) { if (!vocabulary.empty()) { auto it = vocabulary.find(applicator_id()); if (it == vocabulary.end() || !((*it).second)) { include_applicator_ = false; } it = vocabulary.find(unevaluated_id()); if (it == vocabulary.end() || !((*it).second)) { include_unevaluated_ = false; } it = vocabulary.find(validation_id()); if (it == vocabulary.end() || !((*it).second)) { include_validation_ = false; } it = vocabulary.find(format_annotation_id()); if (it == vocabulary.end() || !((*it).second)) { include_format_ = false; } } init(); } schema_validator_factory_201909(const schema_validator_factory_201909&) = delete; schema_validator_factory_201909& operator=(const schema_validator_factory_201909&) = delete; schema_validator_factory_201909(schema_validator_factory_201909&&) = default; schema_validator_factory_201909& operator=(schema_validator_factory_201909&&) = default; void init() { validation_factory_map_.emplace("type", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_type_validator(context, sch, parent);}); /* validation_factory_map_.emplace("contentEncoding", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_content_encoding_validator(context, sch, parent);}); validation_factory_map_.emplace("contentMediaType", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_content_media_type_validator(context, sch, parent);}); */ #if defined(JSONCONS_HAS_STD_REGEX) validation_factory_map_.emplace("pattern", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_pattern_validator(context, sch, parent);}); #endif validation_factory_map_.emplace("maxItems", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_max_items_validator(context, sch, parent);}); validation_factory_map_.emplace("minItems", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_min_items_validator(context, sch, parent);}); validation_factory_map_.emplace("maxProperties", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_max_properties_validator(context, sch, parent);}); validation_factory_map_.emplace("minProperties", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_min_properties_validator(context, sch, parent);}); validation_factory_map_.emplace("contains", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict) {return factory_.make_contains_validator(context, sch, parent, anchor_dict);}); validation_factory_map_.emplace("uniqueItems", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_unique_items_validator(context, sch, parent);}); validation_factory_map_.emplace("maxLength", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_max_length_validator(context, sch, parent);}); validation_factory_map_.emplace("minLength", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_min_length_validator(context, sch, parent);}); validation_factory_map_.emplace("not", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_not_validator(context, sch, parent, anchor_dict);}); validation_factory_map_.emplace("maximum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_maximum_validator(context, sch, parent);}); validation_factory_map_.emplace("exclusiveMaximum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_exclusive_maximum_validator(context, sch, parent);}); validation_factory_map_.emplace("minimum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_minimum_validator(context, sch, parent);}); validation_factory_map_.emplace("exclusiveMinimum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_exclusive_minimum_validator(context, sch, parent);}); validation_factory_map_.emplace("multipleOf", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_multiple_of_validator(context, sch, parent);}); validation_factory_map_.emplace("const", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_const_validator(context, sch, parent);}); validation_factory_map_.emplace("enum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_enum_validator(context, sch, parent);}); validation_factory_map_.emplace("allOf", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_all_of_validator(context, sch, parent, anchor_dict);}); validation_factory_map_.emplace("anyOf", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_any_of_validator(context, sch, parent, anchor_dict);}); validation_factory_map_.emplace("oneOf", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_one_of_validator(context, sch, parent, anchor_dict);}); if (this->options().compatibility_mode()) { validation_factory_map_.emplace("dependencies", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_dependencies_validator(context, sch, parent, anchor_dict);}); } validation_factory_map_.emplace("required", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_required_validator(context, sch, parent);}); validation_factory_map_.emplace("dependentRequired", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_dependent_required_validator(context, sch, parent);}); } schema_validator_ptr_type make_schema_validator(const compilation_context& context, const Json& sch, jsoncons::span keys, anchor_uri_map_type& anchor_dict) override { auto new_context = make_compilation_context(context, sch, keys); //std::cout << "make_schema_validator " << context.get_base_uri().string() << ", " << new_context.get_base_uri().string() << "\n\n"; schema_validator_ptr_type schema_validator_ptr; switch (sch.type()) { case json_type::bool_value: { schema_validator_ptr = this->make_boolean_schema(new_context, sch); schema_validator* p = schema_validator_ptr.get(); for (const auto& uri : new_context.uris()) { this->insert_schema(uri, p); } break; } case json_type::object_value: { std::set known_keywords; schema_validator_ptr = make_object_schema_validator(new_context, sch, anchor_dict); schema_validator* p = schema_validator_ptr.get(); for (const auto& uri : new_context.uris()) { this->insert_schema(uri, p); /*for (const auto& item : sch.object_range()) { if (known_keywords.find(item.key()) == known_keywords.end()) { this->insert_unknown_keyword(uri, item.key(), item.value()); // save unknown keywords for later reference } }*/ } break; } default: JSONCONS_THROW(schema_error("invalid JSON-type for a schema for " + new_context.get_base_uri().string() + ", expected: boolean or object")); break; } return schema_validator_ptr; } schema_validator_ptr_type make_object_schema_validator( const compilation_context& context, const Json& sch, anchor_uri_map_type& anchor_dict) { jsoncons::optional id = context.id(); Json default_value{ jsoncons::null_type()}; std::vector validators; std::unique_ptr> unevaluated_properties_val; std::unique_ptr> unevaluated_items_val; std::set known_keywords; bool recursive_anchor = false; std::map defs; if (this->options().compatibility_mode()) { auto it = sch.find("definitions"); if (it != sch.object_range().end()) { for (const auto& def : (*it).value().object_range()) { std::string sub_keys[] = { "definitions", def.key() }; defs.emplace(def.key(), make_schema_validator(context, def.value(), sub_keys, anchor_dict)); } known_keywords.insert("definitions"); } } auto it = sch.find("$defs"); if (it != sch.object_range().end()) { for (const auto& def : (*it).value().object_range()) { std::string sub_keys[] = { "$defs", def.key() }; defs.emplace(def.key(), make_schema_validator(context, def.value(), sub_keys, anchor_dict)); } known_keywords.insert("$defs"); } it = sch.find("$recursiveAnchor"); if (it != sch.object_range().end()) { recursive_anchor = (*it).value().template as(); } it = sch.find("default"); if (it != sch.object_range().end()) { default_value = (*it).value(); known_keywords.insert("default"); } it = sch.find("$ref"); if (it != sch.object_range().end()) // this schema has a reference { uri relative{(*it).value().template as()}; auto resolved = context.get_base_uri().resolve(relative); validators.push_back(this->get_or_create_reference(sch, uri_wrapper{resolved})); } it = sch.find("$recursiveRef"); if (it != sch.object_range().end()) // this schema has a reference { std::string custom_message = context.get_custom_message("$recursiveRef"); uri relative((*it).value().template as()); auto ref = context.get_base_uri().resolve(relative); auto orig = jsoncons::make_unique(sch, ref.base(), custom_message); this->unresolved_refs_.emplace_back(ref, orig.get()); validators.push_back(std::move(orig)); } if (include_applicator_) { it = sch.find("propertyNames"); if (it != sch.object_range().end()) { validators.emplace_back(factory_.make_property_names_validator(context, (*it).value(), sch, anchor_dict)); } it = sch.find("dependentSchemas"); if (it != sch.object_range().end()) { validators.emplace_back(factory_.make_dependent_schemas_validator(context, (*it).value(), sch, anchor_dict)); } schema_validator_ptr_type if_validator; schema_validator_ptr_type then_validator; schema_validator_ptr_type else_validator; it = sch.find("if"); if (it != sch.object_range().end()) { std::string sub_keys[] = { "if" }; if_validator = make_schema_validator(context, (*it).value(), sub_keys, anchor_dict); } it = sch.find("then"); if (it != sch.object_range().end()) { std::string sub_keys[] = { "then" }; then_validator = make_schema_validator(context, (*it).value(), sub_keys, anchor_dict); } it = sch.find("else"); if (it != sch.object_range().end()) { std::string sub_keys[] = { "else" }; else_validator = make_schema_validator(context, (*it).value(), sub_keys, anchor_dict); } if (if_validator || then_validator || else_validator) { validators.emplace_back(jsoncons::make_unique>( sch, context.get_base_uri(), context.get_custom_message("conditional"), std::move(if_validator), std::move(then_validator), std::move(else_validator))); } // Object validators std::unique_ptr> properties; it = sch.find("properties"); if (it != sch.object_range().end()) { properties = factory_.make_properties_validator(context, (*it).value(), sch, anchor_dict); } std::unique_ptr> pattern_properties; #if defined(JSONCONS_HAS_STD_REGEX) it = sch.find("patternProperties"); if (it != sch.object_range().end()) { pattern_properties = factory_.make_pattern_properties_validator(context, (*it).value(), sch, anchor_dict); } #endif it = sch.find("additionalProperties"); if (it != sch.object_range().end()) { validators.emplace_back(factory_.make_additional_properties_validator(context, (*it).value(), sch, std::move(properties), std::move(pattern_properties), anchor_dict)); } else { if (properties) { validators.emplace_back(std::move(properties)); } #if defined(JSONCONS_HAS_STD_REGEX) if (pattern_properties) { validators.emplace_back(std::move(pattern_properties)); } #endif } it = sch.find("items"); if (it != sch.object_range().end()) { if ((*it).value().type() == json_type::array_value) { validators.emplace_back(factory_.make_prefix_items_validator_07(context, (*it).value(), sch, anchor_dict)); } else if ((*it).value().type() == json_type::object_value || (*it).value().type() == json_type::bool_value) { validators.emplace_back(factory_.make_items_validator("items", context, (*it).value(), sch, anchor_dict)); } } } if (include_validation_) { for (const auto& key_value : sch.object_range()) { auto factory_it = validation_factory_map_.find(key_value.key()); if (factory_it != validation_factory_map_.end()) { auto validator = (*factory_it).second(context, key_value.value(), sch, anchor_dict); if (validator) { validators.emplace_back(std::move(validator)); } } } } if (include_format_) { if (this->options().require_format_validation()) { it = sch.find("format"); if (it != sch.object_range().end()) { validators.emplace_back(factory_.make_format_validator(context, (*it).value(), sch)); } } } if (include_unevaluated_) { it = sch.find("unevaluatedProperties"); if (it != sch.object_range().end()) { unevaluated_properties_val = factory_.make_unevaluated_properties_validator(context, (*it).value(), sch, anchor_dict); } it = sch.find("unevaluatedItems"); if (it != sch.object_range().end()) { unevaluated_items_val = factory_.make_unevaluated_items_validator(context, (*it).value(), sch, anchor_dict); } } return jsoncons::make_unique>(context.get_base_uri(), std::move(id), std::move(validators), std::move(unevaluated_properties_val), std::move(unevaluated_items_val), std::move(defs), std::move(default_value), recursive_anchor); } private: compilation_context make_compilation_context(const compilation_context& parent, const Json& sch, jsoncons::span keys) const override { // Exclude uri's that are not plain name identifiers std::vector new_uris; for (const auto& uri : parent.uris()) { if (!uri.has_plain_name_fragment()) { new_uris.push_back(uri); } } // Append the keys for this sub-schema to the uri's for (const auto& key : keys) { for (auto& uri : new_uris) { auto new_u = uri.append(key); uri = uri_wrapper(new_u); } } jsoncons::optional id; std::unordered_map custom_messages{ parent.custom_messages() }; std::string custom_message; if (sch.is_object()) { auto it = sch.find("$id"); // If $id is found, this schema can be referenced by the id if (it != sch.object_range().end()) { uri relative((*it).value().template as()); if (relative.has_fragment()) { JSONCONS_THROW(schema_error("Draft 2019-09 does not allow $id with fragment")); } auto resolved = parent.get_base_uri().resolve(relative); id = resolved; uri_wrapper new_uri{resolved}; //std::cout << "$id: " << id << ", " << new_uri.string() << "\n"; // Add it to the list if it is not already there if (std::find(new_uris.begin(), new_uris.end(), new_uri) == new_uris.end()) { new_uris.emplace_back(new_uri); } } it = sch.find("$anchor"); if (it != sch.object_range().end()) { auto anchor = (*it).value().template as(); if (!this->validate_anchor(anchor)) { JSONCONS_THROW(schema_error("Invalid $anchor " + anchor)); } auto uri = !new_uris.empty() ? new_uris.back().uri() : jsoncons::uri{"#"}; jsoncons::uri new_uri(uri, uri_fragment_part, anchor); uri_wrapper identifier{ new_uri }; if (std::find(new_uris.begin(), new_uris.end(), identifier) == new_uris.end()) { new_uris.emplace_back(std::move(identifier)); } } if (this->options().enable_custom_error_message()) { it = sch.find("errorMessage"); if (it != sch.object_range().end()) { const auto& value = it->value(); if (value.is_object()) { for (const auto& item : value.object_range()) { custom_messages[item.key()] = item.value().template as(); } } else if (value.is_string()) { custom_message = value.template as(); } } } } /* std::cout << "Absolute URI: " << parent.get_base_uri().string() << "\n"; for (const auto& uri : new_uris) { std::cout << " " << uri.string() << "\n"; } */ return compilation_context(new_uris, id, custom_messages, custom_message); } }; } // namespace draft201909 } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_DRAFT7_KEYWORD_FACTORY_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/draft202012/000077500000000000000000000000001477700171100234165ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons_ext/jsonschema/draft202012/schema_draft202012.hpp000066400000000000000000000257221477700171100272260ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_DRAFT202012_SCHEMA_DRAFT202012_HPP #define JSONCONS_EXT_JSONSCHEMA_DRAFT202012_SCHEMA_DRAFT202012_HPP namespace jsoncons { namespace jsonschema { namespace draft202012 { template struct schema_draft202012 { static Json get_schema() { static Json sch = Json::parse(R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/schema", "$vocabulary": { "https://json-schema.org/draft/2020-12/vocab/core": true, "https://json-schema.org/draft/2020-12/vocab/applicator": true, "https://json-schema.org/draft/2020-12/vocab/unevaluated": true, "https://json-schema.org/draft/2020-12/vocab/validation": true, "https://json-schema.org/draft/2020-12/vocab/meta-data": true, "https://json-schema.org/draft/2020-12/vocab/format-annotation": true, "https://json-schema.org/draft/2020-12/vocab/content": true }, "$dynamicAnchor": "meta", "title": "Core and Validation specifications meta-schema", "allOf": [ { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/meta/core", "$vocabulary": { "https://json-schema.org/draft/2020-12/vocab/core": true }, "$dynamicAnchor": "meta", "title": "Core vocabulary meta-schema", "type": ["object", "boolean"], "properties": { "$id": { "$ref": "#/$defs/uriReferenceString", "$comment": "Non-empty fragments not allowed.", "pattern": "^[^#]*#?$" }, "$schema": { "$ref": "#/$defs/uriString" }, "$ref": { "$ref": "#/$defs/uriReferenceString" }, "$anchor": { "$ref": "#/$defs/anchorString" }, "$dynamicRef": { "$ref": "#/$defs/uriReferenceString" }, "$dynamicAnchor": { "$ref": "#/$defs/anchorString" }, "$vocabulary": { "type": "object", "propertyNames": { "$ref": "#/$defs/uriString" }, "additionalProperties": { "type": "boolean" } }, "$comment": { "type": "string" }, "$defs": { "type": "object", "additionalProperties": { "$dynamicRef": "#meta" } } }, "$defs": { "anchorString": { "type": "string", "pattern": "^[A-Za-z_][-A-Za-z0-9._]*$" }, "uriString": { "type": "string", "format": "uri" }, "uriReferenceString": { "type": "string", "format": "uri-reference" } } }, { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/meta/applicator", "$vocabulary": { "https://json-schema.org/draft/2020-12/vocab/applicator": true }, "$dynamicAnchor": "meta", "title": "Applicator vocabulary meta-schema", "type": ["object", "boolean"], "properties": { "prefixItems": { "$ref": "#/$defs/schemaArray" }, "items": { "$dynamicRef": "#meta" }, "contains": { "$dynamicRef": "#meta" }, "additionalProperties": { "$dynamicRef": "#meta" }, "properties": { "type": "object", "additionalProperties": { "$dynamicRef": "#meta" }, "default": {} }, "patternProperties": { "type": "object", "additionalProperties": { "$dynamicRef": "#meta" }, "propertyNames": { "format": "regex" }, "default": {} }, "dependentSchemas": { "type": "object", "additionalProperties": { "$dynamicRef": "#meta" }, "default": {} }, "propertyNames": { "$dynamicRef": "#meta" }, "if": { "$dynamicRef": "#meta" }, "then": { "$dynamicRef": "#meta" }, "else": { "$dynamicRef": "#meta" }, "allOf": { "$ref": "#/$defs/schemaArray" }, "anyOf": { "$ref": "#/$defs/schemaArray" }, "oneOf": { "$ref": "#/$defs/schemaArray" }, "not": { "$dynamicRef": "#meta" } }, "$defs": { "schemaArray": { "type": "array", "minItems": 1, "items": { "$dynamicRef": "#meta" } } } }, { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/meta/unevaluated", "$vocabulary": { "https://json-schema.org/draft/2020-12/vocab/unevaluated": true }, "$dynamicAnchor": "meta", "title": "Unevaluated applicator vocabulary meta-schema", "type": ["object", "boolean"], "properties": { "unevaluatedItems": { "$dynamicRef": "#meta" }, "unevaluatedProperties": { "$dynamicRef": "#meta" } } }, { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/meta/validation", "$vocabulary": { "https://json-schema.org/draft/2020-12/vocab/validation": true }, "$dynamicAnchor": "meta", "title": "Validation vocabulary meta-schema", "type": ["object", "boolean"], "properties": { "type": { "anyOf": [ { "$ref": "#/$defs/simpleTypes" }, { "type": "array", "items": { "$ref": "#/$defs/simpleTypes" }, "minItems": 1, "uniqueItems": true } ] }, "const": true, "enum": { "type": "array", "items": true }, "multipleOf": { "type": "number", "exclusiveMinimum": 0 }, "maximum": { "type": "number" }, "exclusiveMaximum": { "type": "number" }, "minimum": { "type": "number" }, "exclusiveMinimum": { "type": "number" }, "maxLength": { "$ref": "#/$defs/nonNegativeInteger" }, "minLength": { "$ref": "#/$defs/nonNegativeIntegerDefault0" }, "pattern": { "type": "string", "format": "regex" }, "maxItems": { "$ref": "#/$defs/nonNegativeInteger" }, "minItems": { "$ref": "#/$defs/nonNegativeIntegerDefault0" }, "uniqueItems": { "type": "boolean", "default": false }, "maxContains": { "$ref": "#/$defs/nonNegativeInteger" }, "minContains": { "$ref": "#/$defs/nonNegativeInteger", "default": 1 }, "maxProperties": { "$ref": "#/$defs/nonNegativeInteger" }, "minProperties": { "$ref": "#/$defs/nonNegativeIntegerDefault0" }, "required": { "$ref": "#/$defs/stringArray" }, "dependentRequired": { "type": "object", "additionalProperties": { "$ref": "#/$defs/stringArray" } } }, "$defs": { "nonNegativeInteger": { "type": "integer", "minimum": 0 }, "nonNegativeIntegerDefault0": { "$ref": "#/$defs/nonNegativeInteger", "default": 0 }, "simpleTypes": { "enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ] }, "stringArray": { "type": "array", "items": { "type": "string" }, "uniqueItems": true, "default": [] } } }, { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/meta/meta-data", "$vocabulary": { "https://json-schema.org/draft/2020-12/vocab/meta-data": true }, "$dynamicAnchor": "meta", "title": "Meta-data vocabulary meta-schema", "type": ["object", "boolean"], "properties": { "title": { "type": "string" }, "description": { "type": "string" }, "default": true, "deprecated": { "type": "boolean", "default": false }, "readOnly": { "type": "boolean", "default": false }, "writeOnly": { "type": "boolean", "default": false }, "examples": { "type": "array", "items": true } } }, { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/meta/format-annotation", "$vocabulary": { "https://json-schema.org/draft/2020-12/vocab/format-annotation": true }, "$dynamicAnchor": "meta", "title": "Format vocabulary meta-schema for annotation results", "type": ["object", "boolean"], "properties": { "format": { "type": "string" } } }, { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/meta/content", "$vocabulary": { "https://json-schema.org/draft/2020-12/vocab/content": true }, "$dynamicAnchor": "meta", "title": "Content vocabulary meta-schema", "type": ["object", "boolean"], "properties": { "contentEncoding": { "type": "string" }, "contentMediaType": { "type": "string" }, "contentSchema": { "$dynamicRef": "#meta" } } } ], "type": ["object", "boolean"], "$comment": "This meta-schema also defines keywords that have appeared in previous drafts in order to prevent incompatible extensions as they remain in common use.", "properties": { "definitions": { "$comment": "\"definitions\" has been replaced by \"$defs\".", "type": "object", "additionalProperties": { "$dynamicRef": "#meta" }, "deprecated": true, "default": {} }, "dependencies": { "$comment": "\"dependencies\" has been split and replaced by \"dependentSchemas\" and \"dependentRequired\" in order to serve their differing semantics.", "type": "object", "additionalProperties": { "anyOf": [ { "$dynamicRef": "#meta" }, { "$ref": "meta/validation#/$defs/stringArray" } ] }, "deprecated": true, "default": {} }, "$recursiveAnchor": { "$comment": "\"$recursiveAnchor\" has been replaced by \"$dynamicAnchor\".", "$ref": "meta/core#/$defs/anchorString", "deprecated": true }, "$recursiveRef": { "$comment": "\"$recursiveRef\" has been replaced by \"$dynamicRef\".", "$ref": "meta/core#/$defs/uriReferenceString", "deprecated": true } } } )"); return sch; } }; } // namespace draft202012 } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_DRAFT202012_SCHEMA_DRAFT202012_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/draft202012/schema_validator_factory_202012.hpp000066400000000000000000000772571477700171100320130ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_DRAFT202012_SCHEMA_VALIDATOR_FACTORY_202012_HPP #define JSONCONS_EXT_JSONSCHEMA_DRAFT202012_SCHEMA_VALIDATOR_FACTORY_202012_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(JSONCONS_HAS_STD_REGEX) #include #endif namespace jsoncons { namespace jsonschema { namespace draft202012 { template class schema_validator_factory_202012 : public schema_validator_factory_base { public: using schema_store_type = typename schema_validator_factory_base::schema_store_type; using validator_factory_factory_type = typename schema_validator_factory_base::validator_factory_factory_type; using keyword_validator_ptr_type = typename std::unique_ptr>; using schema_validator_ptr_type = typename std::unique_ptr>; using dynamic_ref_validator_type = dynamic_ref_validator; using anchor_uri_map_type = std::unordered_map; using keyword_factory_type = std::function& context, const Json& sch, const Json& parent, anchor_uri_map_type&)>; std::unordered_map validation_factory_map_; static const std::string& core_id() { static std::string id = "https://json-schema.org/draft/2020-12/vocab/core"; return id; } static const std::string& applicator_id() { static std::string id = "https://json-schema.org/draft/2020-12/vocab/applicator"; return id; } static const std::string& unevaluated_id() { static std::string id = "https://json-schema.org/draft/2020-12/vocab/unevaluated"; return id; } static const std::string& validation_id() { static std::string id = "https://json-schema.org/draft/2020-12/vocab/validation"; return id; } static const std::string& meta_data_id() { static std::string id = "https://json-schema.org/draft/2020-12/vocab/meta-data"; return id; } static const std::string& format_annotation_id() { static std::string id = "https://json-schema.org/draft/2020-12/format-annotation"; return id; } static const std::string& content_id() { static std::string id = "https://json-schema.org/draft/2020-12/vocab/content"; return id; } bool include_applicator_{true}; bool include_unevaluated_{true}; bool include_validation_{true}; bool include_format_{true}; keyword_validator_factory factory_; public: schema_validator_factory_202012(Json&& sch, const validator_factory_factory_type& factory_factory, evaluation_options options, schema_store_type* schema_store_ptr, const std::vector>& resolve_funcs, const std::unordered_map& vocabulary) : schema_validator_factory_base(schema_version::draft202012(), std::move(sch), factory_factory, options, schema_store_ptr, resolve_funcs, vocabulary), factory_(this) { if (!vocabulary.empty()) { auto it = vocabulary.find(applicator_id()); if (it == vocabulary.end() || !((*it).second)) { include_applicator_ = false; } it = vocabulary.find(unevaluated_id()); if (it == vocabulary.end() || !((*it).second)) { include_unevaluated_ = false; } it = vocabulary.find(validation_id()); if (it == vocabulary.end() || !((*it).second)) { include_validation_ = false; } it = vocabulary.find(format_annotation_id()); if (it == vocabulary.end() || !((*it).second)) { include_format_ = false; } } init(); } schema_validator_factory_202012(const schema_validator_factory_202012&) = delete; schema_validator_factory_202012& operator=(const schema_validator_factory_202012&) = delete; schema_validator_factory_202012(schema_validator_factory_202012&&) = default; schema_validator_factory_202012& operator=(schema_validator_factory_202012&&) = default; void init() { // validation validation_factory_map_.emplace("type", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_type_validator(context, sch, parent);}); /* validation_factory_map_.emplace("contentEncoding", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_content_encoding_validator(context, sch, parent);}); validation_factory_map_.emplace("contentMediaType", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_content_media_type_validator(context, sch, parent);}); */ #if defined(JSONCONS_HAS_STD_REGEX) validation_factory_map_.emplace("pattern", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_pattern_validator(context, sch, parent);}); #endif validation_factory_map_.emplace("maxItems", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_max_items_validator(context, sch, parent);}); validation_factory_map_.emplace("minItems", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_min_items_validator(context, sch, parent);}); validation_factory_map_.emplace("maxProperties", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_max_properties_validator(context, sch, parent);}); validation_factory_map_.emplace("minProperties", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_min_properties_validator(context, sch, parent);}); validation_factory_map_.emplace("contains", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict) {return factory_.make_contains_validator(context, sch, parent, anchor_dict);}); validation_factory_map_.emplace("uniqueItems", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_unique_items_validator(context, sch, parent);}); validation_factory_map_.emplace("maxLength", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_max_length_validator(context, sch, parent);}); validation_factory_map_.emplace("minLength", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_min_length_validator(context, sch, parent);}); validation_factory_map_.emplace("not", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_not_validator(context, sch, parent, anchor_dict);}); validation_factory_map_.emplace("maximum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_maximum_validator(context, sch, parent);}); validation_factory_map_.emplace("exclusiveMaximum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_exclusive_maximum_validator(context, sch, parent);}); validation_factory_map_.emplace("minimum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_minimum_validator(context, sch, parent);}); validation_factory_map_.emplace("exclusiveMinimum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_exclusive_minimum_validator(context, sch, parent);}); validation_factory_map_.emplace("multipleOf", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_multiple_of_validator(context, sch, parent);}); validation_factory_map_.emplace("const", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_const_validator(context, sch, parent);}); validation_factory_map_.emplace("enum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_enum_validator(context, sch, parent);}); validation_factory_map_.emplace("allOf", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_all_of_validator(context, sch, parent, anchor_dict);}); validation_factory_map_.emplace("anyOf", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_any_of_validator(context, sch, parent, anchor_dict);}); validation_factory_map_.emplace("oneOf", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_one_of_validator(context, sch, parent, anchor_dict);}); if (this->options().compatibility_mode()) { validation_factory_map_.emplace("dependencies", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_dependencies_validator(context, sch, parent, anchor_dict);}); } validation_factory_map_.emplace("required", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_required_validator(context, sch, parent);}); validation_factory_map_.emplace("dependentRequired", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_dependent_required_validator(context, sch, parent);}); } schema_validator_ptr_type make_schema_validator(const compilation_context& context, const Json& sch, jsoncons::span keys, anchor_uri_map_type& anchor_dict) override { auto new_context = make_compilation_context(context, sch, keys); //std::cout << "this->make_cross_draft_schema_validator " << context.get_base_uri().string() << ", " << new_context.get_base_uri().string() << "\n\n"; schema_validator_ptr_type schema_validator_ptr; switch (sch.type()) { case json_type::bool_value: { schema_validator_ptr = this->make_boolean_schema(new_context, sch); schema_validator* p = schema_validator_ptr.get(); for (const auto& uri : new_context.uris()) { this->insert_schema(uri, p); } break; } case json_type::object_value: { schema_validator_ptr = make_object_schema_validator(new_context, sch, anchor_dict); schema_validator* p = schema_validator_ptr.get(); for (const auto& uri : new_context.uris()) { this->insert_schema(uri, p); /*for (const auto& item : sch.object_range()) { if (known_keywords().find(item.key()) == known_keywords().end()) { std::cout << " " << item.key() << "\n"; this->insert_unknown_keyword(uri, item.key(), item.value()); // save unknown keywords for later reference } }*/ } break; } default: JSONCONS_THROW(schema_error(new_context.get_base_uri().string() + ": Invalid JSON-type for a schema, expected: boolean or object")); break; } return schema_validator_ptr; } schema_validator_ptr_type make_object_schema_validator(const compilation_context& context, const Json& sch, anchor_uri_map_type& anchor_dict) { jsoncons::optional id = context.id(); Json default_value{jsoncons::null_type()}; std::vector validators; std::unique_ptr> unevaluated_properties_val; std::unique_ptr> unevaluated_items_val; jsoncons::optional dynamic_anchor; std::map defs; anchor_uri_map_type local_anchor_dict; auto it = sch.find("$dynamicAnchor"); if (it != sch.object_range().end()) { std::string value = (*it).value().template as(); jsoncons::uri new_uri(context.get_base_uri(), uri_fragment_part, value); dynamic_anchor = jsoncons::optional(new_uri); local_anchor_dict.emplace(value, context.get_base_uri()); } if (this->options().compatibility_mode()) { it = sch.find("definitions"); if (it != sch.object_range().end()) { for (const auto& def : (*it).value().object_range()) { std::string sub_keys[] = { "definitions", def.key() }; defs.emplace(def.key(), this->make_cross_draft_schema_validator(context, def.value(), sub_keys, local_anchor_dict)); } } } it = sch.find("$defs"); if (it != sch.object_range().end()) { for (const auto& def : (*it).value().object_range()) { std::string sub_keys[] = { "$defs", def.key() }; defs.emplace(def.key(), this->make_cross_draft_schema_validator(context, def.value(), sub_keys, local_anchor_dict)); } } it = sch.find("default"); if (it != sch.object_range().end()) { default_value = (*it).value(); } it = sch.find("$ref"); if (it != sch.object_range().end()) // this schema has a reference { uri relative((*it).value().template as()); auto ref = context.get_base_uri().resolve(relative) ; validators.push_back(this->get_or_create_reference(sch, uri_wrapper(ref))); } it = sch.find("$dynamicRef"); if (it != sch.object_range().end()) // this schema has a reference { std::string value = (*it).value().template as(); uri relative(value); auto ref = context.get_base_uri().resolve(relative) ; auto orig = jsoncons::make_unique(sch, ref.base(), context.get_custom_message("$dynamicRef"), uri_wrapper{ref}); this->unresolved_refs_.emplace_back(ref, orig.get()); validators.push_back(std::move(orig)); } if (include_applicator_) { it = sch.find("propertyNames"); if (it != sch.object_range().end()) { validators.emplace_back(factory_.make_property_names_validator(context, (*it).value(), sch, local_anchor_dict)); } it = sch.find("dependentSchemas"); if (it != sch.object_range().end()) { validators.emplace_back(factory_.make_dependent_schemas_validator(context, (*it).value(), sch, local_anchor_dict)); } schema_validator_ptr_type if_validator; schema_validator_ptr_type then_validator; schema_validator_ptr_type else_validator; it = sch.find("if"); if (it != sch.object_range().end()) { std::string sub_keys[] = { "if" }; if_validator = this->make_cross_draft_schema_validator(context, (*it).value(), sub_keys, local_anchor_dict); } it = sch.find("then"); if (it != sch.object_range().end()) { std::string sub_keys[] = { "then" }; then_validator = this->make_cross_draft_schema_validator(context, (*it).value(), sub_keys, local_anchor_dict); } it = sch.find("else"); if (it != sch.object_range().end()) { std::string sub_keys[] = { "else" }; else_validator = this->make_cross_draft_schema_validator(context, (*it).value(), sub_keys, local_anchor_dict); } if (if_validator || then_validator || else_validator) { validators.emplace_back(jsoncons::make_unique>( sch, context.get_base_uri(), context.get_custom_message("conditional"), std::move(if_validator), std::move(then_validator), std::move(else_validator))); } // Object validators std::unique_ptr> properties; it = sch.find("properties"); if (it != sch.object_range().end()) { properties = factory_.make_properties_validator(context, (*it).value(), sch, local_anchor_dict); } std::unique_ptr> pattern_properties; #if defined(JSONCONS_HAS_STD_REGEX) it = sch.find("patternProperties"); if (it != sch.object_range().end()) { pattern_properties = factory_.make_pattern_properties_validator(context, (*it).value(), sch, local_anchor_dict); } #endif it = sch.find("additionalProperties"); if (it != sch.object_range().end()) { validators.emplace_back(factory_.make_additional_properties_validator(context, (*it).value(), sch, std::move(properties), std::move(pattern_properties), local_anchor_dict)); } else { if (properties) { validators.emplace_back(std::move(properties)); } #if defined(JSONCONS_HAS_STD_REGEX) if (pattern_properties) { validators.emplace_back(std::move(pattern_properties)); } #endif } it = sch.find("prefixItems"); if (it != sch.object_range().end()) { if ((*it).value().type() == json_type::array_value) { validators.emplace_back(factory_.make_prefix_items_validator(context, (*it).value(), sch, local_anchor_dict)); } } else { it = sch.find("items"); if (it != sch.object_range().end()) { if ((*it).value().type() == json_type::object_value || (*it).value().type() == json_type::bool_value) { validators.emplace_back(factory_.make_items_validator("items", context, (*it).value(), sch, local_anchor_dict)); } } } } if (include_validation_) { for (const auto& key_value : sch.object_range()) { auto factory_it = validation_factory_map_.find(key_value.key()); if (factory_it != validation_factory_map_.end()) { auto validator = (*factory_it).second(context, key_value.value(), sch, local_anchor_dict); if (validator) { validators.emplace_back(std::move(validator)); } } } } if (include_format_) { if (this->options().require_format_validation()) { it = sch.find("format"); if (it != sch.object_range().end()) { validators.emplace_back(factory_.make_format_validator(context, (*it).value(), sch)); } } } if (include_unevaluated_) { it = sch.find("unevaluatedProperties"); if (it != sch.object_range().end()) { unevaluated_properties_val = factory_.make_unevaluated_properties_validator(context, (*it).value(), sch, local_anchor_dict); } it = sch.find("unevaluatedItems"); if (it != sch.object_range().end()) { unevaluated_items_val = factory_.make_unevaluated_items_validator(context, (*it).value(), sch, local_anchor_dict); } } if (!id) { for (const auto& member : local_anchor_dict) { anchor_dict[member.first] = member.second; } } std::unordered_map>> anchor_schema_map; for (const auto& member : local_anchor_dict) { anchor_schema_map.emplace(member.first, this->get_or_create_reference(sch, member.second)); } return jsoncons::make_unique>(context.get_base_uri(), std::move(id), std::move(validators), std::move(unevaluated_properties_val), std::move(unevaluated_items_val), std::move(defs), std::move(default_value), std::move(dynamic_anchor), std::move(anchor_schema_map)); } private: compilation_context make_compilation_context(const compilation_context& parent, const Json& sch, jsoncons::span keys) const override { // Exclude uri's that are not plain name identifiers std::vector new_uris; for (const auto& uri : parent.uris()) { if (!uri.has_plain_name_fragment()) { new_uris.push_back(uri); } } // Append the keys for this sub-schema to the uri's for (const auto& key : keys) { for (auto& uri : new_uris) { auto new_u = uri.append(key); uri = uri_wrapper(new_u); } } jsoncons::optional id; std::unordered_map custom_messages{parent.custom_messages()}; std::string custom_message; if (sch.is_object()) { auto it = sch.find("$id"); // If $id is found, this schema can be referenced by the id if (it != sch.object_range().end()) { std::string str = (*it).value().template as(); uri relative(str); if (relative.has_fragment()) { JSONCONS_THROW(schema_error(str + ": Draft 2019-09 does not allow $id with fragment")); } auto resolved = parent.get_base_uri().resolve(relative); id = resolved; uri_wrapper new_uri{resolved}; //std::cout << "$id: " << id << ", " << new_uri.string() << "\n"; // Add it to the list if it is not already there if (std::find(new_uris.begin(), new_uris.end(), new_uri) == new_uris.end()) { new_uris.emplace_back(new_uri); } } it = sch.find("$anchor"); if (it != sch.object_range().end()) { auto anchor = (*it).value().template as(); if (!this->validate_anchor(anchor)) { JSONCONS_THROW(schema_error("Invalid $anchor " + anchor)); } auto uri = !new_uris.empty() ? new_uris.back().uri() : jsoncons::uri{"#"}; jsoncons::uri new_uri(uri, uri_fragment_part, anchor); uri_wrapper identifier{ new_uri }; if (std::find(new_uris.begin(), new_uris.end(), identifier) == new_uris.end()) { new_uris.emplace_back(std::move(identifier)); } } it = sch.find("$dynamicAnchor"); if (it != sch.object_range().end()) { auto anchor = (*it).value().template as(); if (!this->validate_anchor(anchor)) { JSONCONS_THROW(schema_error("Invalid $dynamicAnchor " + anchor)); } auto uri = !new_uris.empty() ? new_uris.back().uri() : jsoncons::uri{"#"}; jsoncons::uri new_uri(uri, uri_fragment_part, anchor); uri_wrapper identifier{ new_uri }; if (std::find(new_uris.begin(), new_uris.end(), identifier) == new_uris.end()) { new_uris.emplace_back(std::move(identifier)); } } if (this->options().enable_custom_error_message()) { it = sch.find("errorMessage"); if (it != sch.object_range().end()) { const auto& value = it->value(); if (value.is_object()) { for (const auto& item : value.object_range()) { custom_messages[item.key()] = item.value().template as(); } } else if (value.is_string()) { custom_message = value.template as(); } } } } //std::cout << "Absolute URI: " << parent.get_base_uri().string() << "\n"; //for (const auto& uri : new_uris) //{ // std::cout << " " << uri.string() << "\n"; //} return compilation_context(new_uris, id, custom_messages, custom_message); } private: static const std::unordered_set& known_keywords() { static std::unordered_set keywords{ "$anchor", "$dynamicAnchor", "$dynamicRef", "$id", "$ref", "additionalItems", "additionalProperties", "allOf", "anyOf", "const", "contains", "contentEncoding", "contentMediaType", "default", "$defs", "dependencies", "dependentRequired", "dependentSchemas", "description", "enum", "exclusiveMaximum", "exclusiveMinimum", "if", "then", "else", "items", "maximum", "maxItems", "maxLength", "maxProperties", "minimum", "minItems", "minLength", "minProperties", "multipleOf", "not", "oneOf", "pattern", "patternProperties", "prefixItems", "properties", "propertyNames", "readOnly", "required", "title", "type", "uniqueItems", "unevaluatedItems", "unevaluatedProperties", "writeOnly" }; return keywords; } }; } // namespace draft202012 } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_DRAFT7_KEYWORD_FACTORY_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/draft4/000077500000000000000000000000001477700171100230335ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons_ext/jsonschema/draft4/schema_draft4.hpp000066400000000000000000000120171477700171100262510ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_DRAFT4_SCHEMA_DRAFT4_HPP #define JSONCONS_EXT_JSONSCHEMA_DRAFT4_SCHEMA_DRAFT4_HPP namespace jsoncons { namespace jsonschema { namespace draft4 { template struct schema_draft4 { static Json get_schema() { static Json sch = Json::parse(R"( { "id": "http://json-schema.org/draft-04/schema#", "$schema": "http://json-schema.org/draft-04/schema#", "description": "Core schema meta-schema", "definitions": { "schemaArray": { "type": "array", "minItems": 1, "items": { "$ref": "#" } }, "positiveInteger": { "type": "integer", "minimum": 0 }, "positiveIntegerDefault0": { "allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ] }, "simpleTypes": { "enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ] }, "stringArray": { "type": "array", "items": { "type": "string" }, "minItems": 1, "uniqueItems": true } }, "type": "object", "properties": { "id": { "type": "string" }, "$schema": { "type": "string" }, "title": { "type": "string" }, "description": { "type": "string" }, "default": {}, "multipleOf": { "type": "number", "minimum": 0, "exclusiveMinimum": true }, "maximum": { "type": "number" }, "exclusiveMaximum": { "type": "boolean", "default": false }, "minimum": { "type": "number" }, "exclusiveMinimum": { "type": "boolean", "default": false }, "maxLength": { "$ref": "#/definitions/positiveInteger" }, "minLength": { "$ref": "#/definitions/positiveIntegerDefault0" }, "pattern": { "type": "string", "format": "regex" }, "additionalItems": { "anyOf": [ { "type": "boolean" }, { "$ref": "#" } ], "default": {} }, "items": { "anyOf": [ { "$ref": "#" }, { "$ref": "#/definitions/schemaArray" } ], "default": {} }, "maxItems": { "$ref": "#/definitions/positiveInteger" }, "minItems": { "$ref": "#/definitions/positiveIntegerDefault0" }, "uniqueItems": { "type": "boolean", "default": false }, "maxProperties": { "$ref": "#/definitions/positiveInteger" }, "minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" }, "required": { "$ref": "#/definitions/stringArray" }, "additionalProperties": { "anyOf": [ { "type": "boolean" }, { "$ref": "#" } ], "default": {} }, "definitions": { "type": "object", "additionalProperties": { "$ref": "#" }, "default": {} }, "properties": { "type": "object", "additionalProperties": { "$ref": "#" }, "default": {} }, "patternProperties": { "type": "object", "additionalProperties": { "$ref": "#" }, "default": {} }, "dependencies": { "type": "object", "additionalProperties": { "anyOf": [ { "$ref": "#" }, { "$ref": "#/definitions/stringArray" } ] } }, "enum": { "type": "array", "minItems": 1, "uniqueItems": true }, "type": { "anyOf": [ { "$ref": "#/definitions/simpleTypes" }, { "type": "array", "items": { "$ref": "#/definitions/simpleTypes" }, "minItems": 1, "uniqueItems": true } ] }, "format": { "type": "string" }, "allOf": { "$ref": "#/definitions/schemaArray" }, "anyOf": { "$ref": "#/definitions/schemaArray" }, "oneOf": { "$ref": "#/definitions/schemaArray" }, "not": { "$ref": "#" } }, "dependencies": { "exclusiveMaximum": [ "maximum" ], "exclusiveMinimum": [ "minimum" ] }, "default": {} } )"); return sch; } }; } // namespace draft4 } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_DRAFT4_SCHEMA_DRAFT4_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/draft4/schema_validator_factory_4.hpp000066400000000000000000000555321477700171100310350ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_DRAFT4_SCHEMA_VALIDATOR_FACTORY_4_HPP #define JSONCONS_EXT_JSONSCHEMA_DRAFT4_SCHEMA_VALIDATOR_FACTORY_4_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(JSONCONS_HAS_STD_REGEX) #include #endif namespace jsoncons { namespace jsonschema { namespace draft4 { template class schema_validator_factory_4 : public schema_validator_factory_base { public: using schema_store_type = typename schema_validator_factory_base::schema_store_type; using validator_factory_factory_type = typename schema_validator_factory_base::validator_factory_factory_type; using keyword_validator_ptr_type = typename std::unique_ptr>; using schema_validator_ptr_type = typename std::unique_ptr>; using anchor_uri_map_type = std::unordered_map; private: using keyword_factory_type = std::function& context, const Json& sch, const Json& parent, anchor_uri_map_type&)>; std::unordered_map keyword_factory_map_; keyword_validator_factory factory_; public: schema_validator_factory_4(Json&& sch, const validator_factory_factory_type& factory_factory, evaluation_options options, schema_store_type* schema_store_ptr, const std::vector>& resolve_funcs) : schema_validator_factory_base(schema_version::draft4(), std::move(sch), factory_factory, options, schema_store_ptr, resolve_funcs), factory_(this) { init(); } schema_validator_factory_4(const schema_validator_factory_4&) = delete; schema_validator_factory_4& operator=(const schema_validator_factory_4&) = delete; schema_validator_factory_4(schema_validator_factory_4&&) = default; schema_validator_factory_4& operator=(schema_validator_factory_4&&) = default; void init() { keyword_factory_map_.emplace("type", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_type_validator(context, sch, parent);}); keyword_factory_map_.emplace("contentEncoding", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_content_encoding_validator(context, sch, parent);}); keyword_factory_map_.emplace("contentMediaType", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_content_media_type_validator(context, sch, parent);}); if (this->options().require_format_validation()) { keyword_factory_map_.emplace("format", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_format_validator(context, sch, parent);}); } #if defined(JSONCONS_HAS_STD_REGEX) keyword_factory_map_.emplace("pattern", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_pattern_validator(context, sch, parent);}); #endif keyword_factory_map_.emplace("maxItems", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_max_items_validator(context, sch, parent);}); keyword_factory_map_.emplace("minItems", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_min_items_validator(context, sch, parent);}); keyword_factory_map_.emplace("maxProperties", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_max_properties_validator(context, sch, parent);}); keyword_factory_map_.emplace("minProperties", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_min_properties_validator(context, sch, parent);}); keyword_factory_map_.emplace("uniqueItems", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_unique_items_validator(context, sch, parent);}); keyword_factory_map_.emplace("maxLength", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_max_length_validator(context, sch, parent);}); keyword_factory_map_.emplace("minLength", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_min_length_validator(context, sch, parent);}); keyword_factory_map_.emplace("not", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_not_validator(context, sch, parent, anchor_dict);}); keyword_factory_map_.emplace("maximum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return make_maximum_validator_4(context, sch, parent);}); keyword_factory_map_.emplace("minimum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return make_minimum_validator_4(context, sch, parent);}); keyword_factory_map_.emplace("multipleOf", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_multiple_of_validator(context, sch, parent);}); keyword_factory_map_.emplace("enum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_enum_validator(context, sch, parent);}); keyword_factory_map_.emplace("allOf", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_all_of_validator(context, sch, parent, anchor_dict);}); keyword_factory_map_.emplace("anyOf", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_any_of_validator(context, sch, parent, anchor_dict);}); keyword_factory_map_.emplace("oneOf", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_one_of_validator(context, sch, parent, anchor_dict);}); keyword_factory_map_.emplace("dependencies", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_dependencies_validator(context, sch, parent, anchor_dict);}); keyword_factory_map_.emplace("required", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_required_validator(context, sch, parent);}); } schema_validator_ptr_type make_schema_validator( const compilation_context& context, const Json& sch, jsoncons::span keys, anchor_uri_map_type& anchor_dict) override { auto new_context = make_compilation_context(context, sch, keys); //std::cout << "make_schema_validator " << context.get_base_uri().string() << ", " << new_context.get_base_uri().string() << "\n\n"; schema_validator_ptr_type schema_validator_ptr; switch (sch.type()) { case json_type::bool_value: { schema_validator_ptr = this->make_boolean_schema(new_context, sch); schema_validator* p = schema_validator_ptr.get(); for (const auto& uri : new_context.uris()) { this->insert_schema(uri, p); } break; } case json_type::object_value: { auto it = sch.find("$ref"); if (it != sch.object_range().end()) // this schema is a reference { std::vector validators; std::map defs; auto it2 = sch.find("definitions"); if (it2 != sch.object_range().end()) { for (const auto& def : it2->value().object_range()) { std::string sub_keys[] = { "definitions", def.key() }; defs.emplace(def.key(), make_schema_validator(context, def.value(), sub_keys, anchor_dict)); } } Json default_value{ jsoncons::null_type() }; uri relative((*it).value().template as()); auto id = context.get_base_uri().resolve(relative); validators.push_back(this->get_or_create_reference(sch, uri_wrapper{id})); schema_validator_ptr = jsoncons::make_unique>( new_context.get_base_uri(), context.id(), std::move(validators), std::move(defs), std::move(default_value)); } else { schema_validator_ptr = make_object_schema_validator(new_context, sch, anchor_dict); } schema_validator* p = schema_validator_ptr.get(); for (const auto& uri : new_context.uris()) { this->insert_schema(uri, p); for (const auto& item : sch.object_range()) { if (known_keywords().find(item.key()) == known_keywords().end()) { this->insert_unknown_keyword(uri, item.key(), item.value()); // save unknown keywords for later reference } } } break; } default: JSONCONS_THROW(schema_error("invalid JSON-type for a schema for " + new_context.get_base_uri().string() + ", expected: boolean or object")); break; } return schema_validator_ptr; } schema_validator_ptr_type make_object_schema_validator(const compilation_context& context, const Json& sch, anchor_uri_map_type& anchor_dict) { jsoncons::optional id = context.id(); Json default_value{ jsoncons::null_type() }; std::vector validators; std::map defs; auto it = sch.find("definitions"); if (it != sch.object_range().end()) { for (const auto& def : (*it).value().object_range()) { std::string sub_keys[] = { "definitions", def.key() }; defs.emplace(def.key(), make_schema_validator(context, def.value(), sub_keys, anchor_dict)); } } it = sch.find("default"); if (it != sch.object_range().end()) { default_value = (*it).value(); } for (const auto& key_value : sch.object_range()) { auto factory_it = keyword_factory_map_.find(key_value.key()); if (factory_it != keyword_factory_map_.end()) { auto validator = (*factory_it).second(context, key_value.value(), sch, anchor_dict); if (validator) { validators.emplace_back(std::move(validator)); } } } std::unique_ptr> properties; it = sch.find("properties"); if (it != sch.object_range().end()) { properties = factory_.make_properties_validator(context, (*it).value(), sch, anchor_dict); } std::unique_ptr> pattern_properties; #if defined(JSONCONS_HAS_STD_REGEX) it = sch.find("patternProperties"); if (it != sch.object_range().end()) { pattern_properties = factory_.make_pattern_properties_validator(context, (*it).value(), sch, anchor_dict); } #endif it = sch.find("additionalProperties"); if (it != sch.object_range().end()) { validators.emplace_back(factory_.make_additional_properties_validator(context, (*it).value(), sch, std::move(properties), std::move(pattern_properties), anchor_dict)); } else { if (properties) { validators.emplace_back(std::move(properties)); } #if defined(JSONCONS_HAS_STD_REGEX) if (pattern_properties) { validators.emplace_back(std::move(pattern_properties)); } #endif } it = sch.find("items"); if (it != sch.object_range().end()) { if ((*it).value().type() == json_type::array_value) { validators.emplace_back(factory_.make_prefix_items_validator_07(context, (*it).value(), sch, anchor_dict)); } else if ((*it).value().type() == json_type::object_value || (*it).value().type() == json_type::bool_value) { validators.emplace_back(factory_.make_items_validator("items", context, (*it).value(), sch, anchor_dict)); } } return jsoncons::make_unique>(context.get_base_uri(), std::move(id), std::move(validators), std::move(defs), std::move(default_value)); } std::unique_ptr> make_maximum_validator_4(const compilation_context& context, const Json& sch, const Json& parent) { uri schema_location = context.make_schema_location("maximum"); if (!sch.is_number()) { const std::string message("maximum must be a number value"); JSONCONS_THROW(schema_error(message)); } bool is_exclusive = false; if (parent.is_object()) { auto it = parent.find("exclusiveMaximum"); if (it != parent.object_range().end()) { is_exclusive = (*it).value().as_bool(); } } if (is_exclusive) { return jsoncons::make_unique>(parent, schema_location, context.get_custom_message("maximum"), sch); } else { return jsoncons::make_unique>(parent, schema_location, context.get_custom_message("maximum"), sch); } } virtual std::unique_ptr> make_minimum_validator_4(const compilation_context& context, const Json& sch, const Json& parent) { uri schema_location = context.make_schema_location("minimum"); if (!sch.is_number()) { const std::string message("minimum must be an integer"); JSONCONS_THROW(schema_error(message)); } bool is_exclusive = false; if (parent.is_object()) { auto it = parent.find("exclusiveMinimum"); if (it != parent.object_range().end()) { is_exclusive = (*it).value().as_bool(); } } if (is_exclusive) { return jsoncons::make_unique>(parent, schema_location, context.get_custom_message("minimum"), sch); } else { return jsoncons::make_unique>(parent, schema_location, context.get_custom_message("minimum"), sch); } } private: compilation_context make_compilation_context(const compilation_context& parent, const Json& sch, jsoncons::span keys) const override { // Exclude uri's that are not plain name identifiers std::vector new_uris; for (const auto& uri : parent.uris()) { if (!uri.has_plain_name_fragment()) { new_uris.push_back(uri); } } // Append the keys for this sub-schema to the uri's for (const auto& key : keys) { for (auto& uri : new_uris) { auto new_u = uri.append(key); uri = uri_wrapper(new_u); } } jsoncons::optional id; std::unordered_map custom_messages{parent.custom_messages()}; std::string custom_message; if (sch.is_object()) { auto it = sch.find("id"); // If id is found, this schema can be referenced by the id if (it != sch.object_range().end()) { uri relative((*it).value().template as()); auto resolved = parent.get_base_uri().resolve(relative); id = resolved; uri_wrapper new_uri{ resolved }; //std::cout << "id: " << id << ", " << new_uri.string() << "\n"; // Add it to the list if it is not already there if (std::find(new_uris.begin(), new_uris.end(), new_uri) == new_uris.end()) { new_uris.emplace_back(new_uri); } } if (this->options().enable_custom_error_message()) { it = sch.find("errorMessage"); if (it != sch.object_range().end()) { const auto& value = it->value(); if (value.is_object()) { for (const auto& item : value.object_range()) { custom_messages[item.key()] = item.value().template as(); } } else if (value.is_string()) { custom_message = value.template as(); } } } } /* std::cout << "Absolute URI: " << parent.get_base_uri().string() << "\n"; for (const auto& uri : new_uris) { std::cout << " " << uri.string() << "\n"; } */ return compilation_context(new_uris, id, custom_messages, custom_message); } private: static const std::unordered_set& known_keywords() { static std::unordered_set keywords{ "id", "$ref", "additionalItems", "additionalProperties", "allOf", "anyOf", "const", "contains", "contentEncoding", "contentMediaType", "default", "definitions", "dependencies", "enum", "exclusiveMaximum", "exclusiveMaximum", "exclusiveMinimum", "exclusiveMinimum", "items", "maximum", "maxItems", "maxLength", "maxProperties", "minimum", "minItems", "minLength", "minProperties", "multipleOf", "not", "oneOf", "pattern", "patternProperties", "properties", "propertyNames", "readOnly", "required", "type", "uniqueItems", "writeOnly" }; return keywords; } }; } // namespace draft4 } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_DRAFT4_KEYWORD_FACTORY_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/draft6/000077500000000000000000000000001477700171100230355ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons_ext/jsonschema/draft6/schema_draft6.hpp000066400000000000000000000121361477700171100262570ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_DRAFT6_SCHEMA_DRAFT6_HPP #define JSONCONS_EXT_JSONSCHEMA_DRAFT6_SCHEMA_DRAFT6_HPP namespace jsoncons { namespace jsonschema { namespace draft6 { template struct schema_draft6 { static Json get_schema() { static Json sch = Json::parse(R"( { "$schema": "http://json-schema.org/draft-06/schema#", "$id": "http://json-schema.org/draft-06/schema#", "title": "Core schema meta-schema", "definitions": { "schemaArray": { "type": "array", "minItems": 1, "items": { "$ref": "#" } }, "nonNegativeInteger": { "type": "integer", "minimum": 0 }, "nonNegativeIntegerDefault0": { "allOf": [ { "$ref": "#/definitions/nonNegativeInteger" }, { "default": 0 } ] }, "simpleTypes": { "enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ] }, "stringArray": { "type": "array", "items": { "type": "string" }, "uniqueItems": true, "default": [] } }, "type": ["object", "boolean"], "properties": { "$id": { "type": "string", "format": "uri-reference" }, "$schema": { "type": "string", "format": "uri" }, "$ref": { "type": "string", "format": "uri-reference" }, "title": { "type": "string" }, "description": { "type": "string" }, "default": {}, "examples": { "type": "array", "items": {} }, "multipleOf": { "type": "number", "exclusiveMinimum": 0 }, "maximum": { "type": "number" }, "exclusiveMaximum": { "type": "number" }, "minimum": { "type": "number" }, "exclusiveMinimum": { "type": "number" }, "maxLength": { "$ref": "#/definitions/nonNegativeInteger" }, "minLength": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, "pattern": { "type": "string", "format": "regex" }, "additionalItems": { "$ref": "#" }, "items": { "anyOf": [ { "$ref": "#" }, { "$ref": "#/definitions/schemaArray" } ], "default": {} }, "maxItems": { "$ref": "#/definitions/nonNegativeInteger" }, "minItems": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, "uniqueItems": { "type": "boolean", "default": false }, "contains": { "$ref": "#" }, "maxProperties": { "$ref": "#/definitions/nonNegativeInteger" }, "minProperties": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, "required": { "$ref": "#/definitions/stringArray" }, "additionalProperties": { "$ref": "#" }, "definitions": { "type": "object", "additionalProperties": { "$ref": "#" }, "default": {} }, "properties": { "type": "object", "additionalProperties": { "$ref": "#" }, "default": {} }, "patternProperties": { "type": "object", "additionalProperties": { "$ref": "#" }, "propertyNames": { "format": "regex" }, "default": {} }, "dependencies": { "type": "object", "additionalProperties": { "anyOf": [ { "$ref": "#" }, { "$ref": "#/definitions/stringArray" } ] } }, "propertyNames": { "$ref": "#" }, "const": {}, "enum": { "type": "array" }, "type": { "anyOf": [ { "$ref": "#/definitions/simpleTypes" }, { "type": "array", "items": { "$ref": "#/definitions/simpleTypes" }, "minItems": 1, "uniqueItems": true } ] }, "format": { "type": "string" }, "allOf": { "$ref": "#/definitions/schemaArray" }, "anyOf": { "$ref": "#/definitions/schemaArray" }, "oneOf": { "$ref": "#/definitions/schemaArray" }, "not": { "$ref": "#" } }, "default": {} } )"); return sch; } }; } // namespace draft6 } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_DRAFT6_SCHEMA_DRAFT6_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/draft6/schema_validator_factory_6.hpp000066400000000000000000000533731477700171100310420ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_DRAFT6_SCHEMA_VALIDATOR_FACTORY_6_HPP #define JSONCONS_EXT_JSONSCHEMA_DRAFT6_SCHEMA_VALIDATOR_FACTORY_6_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(JSONCONS_HAS_STD_REGEX) #include #endif namespace jsoncons { namespace jsonschema { namespace draft6 { template class schema_validator_factory_6 : public schema_validator_factory_base { public: using schema_store_type = typename schema_validator_factory_base::schema_store_type; using validator_factory_factory_type = typename schema_validator_factory_base::validator_factory_factory_type; using keyword_validator_ptr_type = typename std::unique_ptr>; using schema_validator_ptr_type = typename std::unique_ptr>; using anchor_uri_map_type = std::unordered_map; private: using keyword_factory_type = std::function& context, const Json& sch, const Json& parent, anchor_uri_map_type&)>; std::unordered_map keyword_factory_map_; keyword_validator_factory factory_; public: schema_validator_factory_6(Json&& sch, const validator_factory_factory_type& factory_factory, evaluation_options options, schema_store_type* schema_store_ptr, const std::vector>& resolve_funcs) : schema_validator_factory_base(schema_version::draft6(), std::move(sch), factory_factory, options, schema_store_ptr, resolve_funcs), factory_(this) { init(); } schema_validator_factory_6(const schema_validator_factory_6&) = delete; schema_validator_factory_6& operator=(const schema_validator_factory_6&) = delete; schema_validator_factory_6(schema_validator_factory_6&&) = default; schema_validator_factory_6& operator=(schema_validator_factory_6&&) = default; void init() { keyword_factory_map_.emplace("type", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_type_validator(context, sch, parent);}); keyword_factory_map_.emplace("contentEncoding", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_content_encoding_validator(context, sch, parent);}); keyword_factory_map_.emplace("contentMediaType", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_content_media_type_validator(context, sch, parent);}); if (this->options().require_format_validation()) { keyword_factory_map_.emplace("format", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_format_validator(context, sch, parent);}); } #if defined(JSONCONS_HAS_STD_REGEX) keyword_factory_map_.emplace("pattern", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_pattern_validator(context, sch, parent);}); #endif keyword_factory_map_.emplace("maxItems", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_max_items_validator(context, sch, parent);}); keyword_factory_map_.emplace("minItems", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_min_items_validator(context, sch, parent);}); keyword_factory_map_.emplace("maxProperties", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_max_properties_validator(context, sch, parent);}); keyword_factory_map_.emplace("minProperties", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_min_properties_validator(context, sch, parent);}); keyword_factory_map_.emplace("contains", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict) {return factory_.make_contains_validator(context, sch, parent, anchor_dict);}); keyword_factory_map_.emplace("uniqueItems", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_unique_items_validator(context, sch, parent);}); keyword_factory_map_.emplace("maxLength", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_max_length_validator(context, sch, parent);}); keyword_factory_map_.emplace("minLength", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_min_length_validator(context, sch, parent);}); keyword_factory_map_.emplace("not", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_not_validator(context, sch, parent, anchor_dict);}); keyword_factory_map_.emplace("maximum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_maximum_validator(context, sch, parent);}); keyword_factory_map_.emplace("exclusiveMaximum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_exclusive_maximum_validator(context, sch, parent);}); keyword_factory_map_.emplace("minimum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_minimum_validator(context, sch, parent);}); keyword_factory_map_.emplace("exclusiveMinimum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_exclusive_minimum_validator(context, sch, parent);}); keyword_factory_map_.emplace("multipleOf", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_multiple_of_validator(context, sch, parent);}); keyword_factory_map_.emplace("const", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_const_validator(context, sch, parent);}); keyword_factory_map_.emplace("enum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_enum_validator(context, sch, parent);}); keyword_factory_map_.emplace("allOf", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_all_of_validator(context, sch, parent, anchor_dict);}); keyword_factory_map_.emplace("anyOf", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_any_of_validator(context, sch, parent, anchor_dict);}); keyword_factory_map_.emplace("oneOf", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_one_of_validator(context, sch, parent, anchor_dict);}); keyword_factory_map_.emplace("dependencies", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_dependencies_validator(context, sch, parent, anchor_dict);}); keyword_factory_map_.emplace("propertyNames", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_property_names_validator(context, sch, parent, anchor_dict);}); keyword_factory_map_.emplace("required", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_required_validator(context, sch, parent);}); } schema_validator_ptr_type make_schema_validator( const compilation_context& context, const Json& sch, jsoncons::span keys, anchor_uri_map_type& anchor_dict) override { auto new_context = make_compilation_context(context, sch, keys); //std::cout << "make_schema_validator " << context.get_base_uri().string() << ", " << new_context.get_base_uri().string() << "\n\n"; schema_validator_ptr_type schema_validator_ptr; switch (sch.type()) { case json_type::bool_value: { schema_validator_ptr = this->make_boolean_schema(new_context, sch); schema_validator* p = schema_validator_ptr.get(); for (const auto& uri : new_context.uris()) { this->insert_schema(uri, p); } break; } case json_type::object_value: { auto it = sch.find("$ref"); if (it != sch.object_range().end()) // this schema is a reference { std::vector validators; std::map defs; auto it2 = sch.find("definitions"); if (it2 != sch.object_range().end()) { for (const auto& def : it2->value().object_range()) { std::string sub_keys[] = { "definitions", def.key() }; defs.emplace(def.key(), make_schema_validator(context, def.value(), sub_keys, anchor_dict)); } } Json default_value{ jsoncons::null_type() }; uri relative((*it).value().template as()); auto id = context.get_base_uri().resolve(relative) ; validators.push_back(this->get_or_create_reference(sch, uri_wrapper{id})); schema_validator_ptr = jsoncons::make_unique>( new_context.get_base_uri(), context.id(), std::move(validators), std::move(defs), std::move(default_value)); } else { schema_validator_ptr = make_object_schema_validator(new_context, sch, anchor_dict); } schema_validator* p = schema_validator_ptr.get(); for (const auto& uri : new_context.uris()) { this->insert_schema(uri, p); for (const auto& item : sch.object_range()) { if (known_keywords().find(item.key()) == known_keywords().end()) { this->insert_unknown_keyword(uri, item.key(), item.value()); // save unknown keywords for later reference } } } break; } default: JSONCONS_THROW(schema_error("invalid JSON-type for a schema for " + new_context.get_base_uri().string() + ", expected: boolean or object")); break; } return schema_validator_ptr; } schema_validator_ptr_type make_object_schema_validator(const compilation_context& context, const Json& sch, anchor_uri_map_type& anchor_dict) { jsoncons::optional id = context.id(); Json default_value{ jsoncons::null_type() }; std::vector validators; std::map defs; auto it = sch.find("definitions"); if (it != sch.object_range().end()) { for (const auto& def : (*it).value().object_range()) { std::string sub_keys[] = { "definitions", def.key() }; defs.emplace(def.key(), make_schema_validator(context, def.value(), sub_keys, anchor_dict)); } } it = sch.find("default"); if (it != sch.object_range().end()) { default_value = (*it).value(); } for (const auto& key_value : sch.object_range()) { auto factory_it = keyword_factory_map_.find(key_value.key()); if (factory_it != keyword_factory_map_.end()) { auto validator = (*factory_it).second(context, key_value.value(), sch, anchor_dict); if (validator) { validators.emplace_back(std::move(validator)); } } } std::unique_ptr> properties; it = sch.find("properties"); if (it != sch.object_range().end()) { properties = factory_.make_properties_validator(context, (*it).value(), sch, anchor_dict); } std::unique_ptr> pattern_properties; #if defined(JSONCONS_HAS_STD_REGEX) it = sch.find("patternProperties"); if (it != sch.object_range().end()) { pattern_properties = factory_.make_pattern_properties_validator(context, (*it).value(), sch, anchor_dict); } #endif it = sch.find("additionalProperties"); if (it != sch.object_range().end()) { validators.emplace_back(factory_.make_additional_properties_validator(context, (*it).value(), sch, std::move(properties), std::move(pattern_properties), anchor_dict)); } else { if (properties) { validators.emplace_back(std::move(properties)); } #if defined(JSONCONS_HAS_STD_REGEX) if (pattern_properties) { validators.emplace_back(std::move(pattern_properties)); } #endif } it = sch.find("items"); if (it != sch.object_range().end()) { if ((*it).value().type() == json_type::array_value) { validators.emplace_back(factory_.make_prefix_items_validator_07(context, (*it).value(), sch, anchor_dict)); } else if ((*it).value().type() == json_type::object_value || (*it).value().type() == json_type::bool_value) { validators.emplace_back(factory_.make_items_validator("items", context, (*it).value(), sch, anchor_dict)); } } return jsoncons::make_unique>(context.get_base_uri(), std::move(id), std::move(validators), std::move(defs), std::move(default_value)); } private: compilation_context make_compilation_context(const compilation_context& parent, const Json& sch, jsoncons::span keys) const override { // Exclude uri's that are not plain name identifiers std::vector new_uris; for (const auto& uri : parent.uris()) { if (!uri.has_plain_name_fragment()) { new_uris.push_back(uri); } } // Append the keys for this sub-schema to the uri's for (const auto& key : keys) { for (auto& uri : new_uris) { auto new_u = uri.append(key); uri = uri_wrapper(new_u); } } jsoncons::optional id; std::unordered_map custom_messages{parent.custom_messages()}; std::string custom_message; if (sch.is_object()) { auto it = sch.find("$id"); // If $id is found, this schema can be referenced by the id if (it != sch.object_range().end()) { uri relative((*it).value().template as()); auto resolved = parent.get_base_uri().resolve(relative); id = resolved; uri_wrapper new_uri{resolved}; //std::cout << "$id: " << id << ", " << new_uri.string() << "\n"; // Add it to the list if it is not already there if (std::find(new_uris.begin(), new_uris.end(), new_uri) == new_uris.end()) { new_uris.emplace_back(new_uri); } } if (this->options().enable_custom_error_message()) { it = sch.find("errorMessage"); if (it != sch.object_range().end()) { const auto& value = it->value(); if (value.is_object()) { for (const auto& item : value.object_range()) { custom_messages[item.key()] = item.value().template as(); } } else if (value.is_string()) { custom_message = value.template as(); } } } } /* std::cout << "Absolute URI: " << parent.get_base_uri().string() << "\n"; for (const auto& uri : new_uris) { std::cout << " " << uri.string() << "\n"; } */ return compilation_context(new_uris, id, custom_messages, custom_message); } private: static const std::unordered_set& known_keywords() { static std::unordered_set keywords{ "$id", "$ref", "additionalItems", "additionalProperties", "allOf", "anyOf", "const", "contains", "contentEncoding", "contentMediaType", "default", "definitions", "dependencies", "enum", "exclusiveMaximum", "exclusiveMinimum", "items", "maximum", "maxItems", "maxLength", "maxProperties", "minimum", "minItems", "minLength", "minProperties", "multipleOf", "not", "oneOf", "pattern", "patternProperties", "properties", "propertyNames", "readOnly", "required", "type", "uniqueItems", "writeOnly" }; return keywords; } }; } // namespace draft6 } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_DRAFT7_KEYWORD_FACTORY_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/draft7/000077500000000000000000000000001477700171100230365ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons_ext/jsonschema/draft7/schema_draft7.hpp000066400000000000000000000142641477700171100262650ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_DRAFT7_SCHEMA_DRAFT7_HPP #define JSONCONS_EXT_JSONSCHEMA_DRAFT7_SCHEMA_DRAFT7_HPP namespace jsoncons { namespace jsonschema { namespace draft7 { template struct schema_draft7 { static Json get_schema() { static Json sch = Json::parse(R"( { "$schema": "http://json-schema.org/draft-07/schema#", "$id": "http://json-schema.org/draft-07/schema#", "title": "Core schema meta-schema", "definitions": { "schemaArray": { "type": "array", "minItems": 1, "items": { "$ref": "#" } }, "nonNegativeInteger": { "type": "integer", "minimum": 0 }, "nonNegativeIntegerDefault0": { "allOf": [ { "$ref": "#/definitions/nonNegativeInteger" }, { "default": 0 } ] }, "simpleTypes": { "enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ] }, "stringArray": { "type": "array", "items": { "type": "string" }, "uniqueItems": true, "default": [] } }, "type": ["object", "boolean"], "properties": { "$id": { "type": "string", "format": "uri-reference" }, "$schema": { "type": "string", "format": "uri" }, "$ref": { "type": "string", "format": "uri-reference" }, "$comment": { "type": "string" }, "title": { "type": "string" }, "description": { "type": "string" }, "default": true, "readOnly": { "type": "boolean", "default": false }, "examples": { "type": "array", "items": true }, "multipleOf": { "type": "number", "exclusiveMinimum": 0 }, "maximum": { "type": "number" }, "exclusiveMaximum": { "type": "number" }, "minimum": { "type": "number" }, "exclusiveMinimum": { "type": "number" }, "maxLength": { "$ref": "#/definitions/nonNegativeInteger" }, "minLength": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, "pattern": { "type": "string", "format": "regex" }, "additionalItems": { "$ref": "#" }, "items": { "anyOf": [ { "$ref": "#" }, { "$ref": "#/definitions/schemaArray" } ], "default": true }, "maxItems": { "$ref": "#/definitions/nonNegativeInteger" }, "minItems": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, "uniqueItems": { "type": "boolean", "default": false }, "contains": { "$ref": "#" }, "maxProperties": { "$ref": "#/definitions/nonNegativeInteger" }, "minProperties": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, "required": { "$ref": "#/definitions/stringArray" }, "additionalProperties": { "$ref": "#" }, "definitions": { "type": "object", "additionalProperties": { "$ref": "#" }, "default": {} }, "properties": { "type": "object", "additionalProperties": { "$ref": "#" }, "default": {} }, "patternProperties": { "type": "object", "additionalProperties": { "$ref": "#" }, "propertyNames": { "format": "regex" }, "default": {} }, "dependencies": { "type": "object", "additionalProperties": { "anyOf": [ { "$ref": "#" }, { "$ref": "#/definitions/stringArray" } ] } }, "propertyNames": { "$ref": "#" }, "const": true, "enum": { "type": "array", "items": true, "minItems": 1, "uniqueItems": true }, "type": { "anyOf": [ { "$ref": "#/definitions/simpleTypes" }, { "type": "array", "items": { "$ref": "#/definitions/simpleTypes" }, "minItems": 1, "uniqueItems": true } ] }, "format": { "type": "string" }, "contentMediaType": { "type": "string" }, "contentEncoding": { "type": "string" }, "if": { "$ref": "#" }, "then": { "$ref": "#" }, "else": { "$ref": "#" }, "allOf": { "$ref": "#/definitions/schemaArray" }, "anyOf": { "$ref": "#/definitions/schemaArray" }, "oneOf": { "$ref": "#/definitions/schemaArray" }, "not": { "$ref": "#" } }, "default": true } )"); return sch; } }; } // namespace draft7 } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_DRAFT7_SCHEMA_DRAFT7_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/draft7/schema_validator_factory_7.hpp000066400000000000000000000560171477700171100310420ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_DRAFT7_SCHEMA_VALIDATOR_FACTORY_7_HPP #define JSONCONS_EXT_JSONSCHEMA_DRAFT7_SCHEMA_VALIDATOR_FACTORY_7_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(JSONCONS_HAS_STD_REGEX) #include #endif namespace jsoncons { namespace jsonschema { namespace draft7 { template class schema_validator_factory_7 : public schema_validator_factory_base { public: using schema_store_type = typename schema_validator_factory_base::schema_store_type; using validator_factory_factory_type = typename schema_validator_factory_base::validator_factory_factory_type; using keyword_validator_ptr_type = typename std::unique_ptr>; using schema_validator_ptr_type = typename std::unique_ptr>; using anchor_uri_map_type = std::unordered_map; private: using keyword_factory_type = std::function& context, const Json& sch, const Json& parent, anchor_uri_map_type&)>; std::unordered_map keyword_factory_map_; keyword_validator_factory factory_; public: schema_validator_factory_7(Json&& sch, const validator_factory_factory_type& factory_factory, evaluation_options options, schema_store_type* schema_store_ptr, const std::vector>& resolve_funcs) : schema_validator_factory_base(schema_version::draft7(), std::move(sch), factory_factory, options, schema_store_ptr, resolve_funcs), factory_(this) { init(); } schema_validator_factory_7(const schema_validator_factory_7&) = delete; schema_validator_factory_7& operator=(const schema_validator_factory_7&) = delete; schema_validator_factory_7(schema_validator_factory_7&&) = default; schema_validator_factory_7& operator=(schema_validator_factory_7&&) = default; void init() { keyword_factory_map_.emplace("type", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_type_validator(context, sch, parent);}); keyword_factory_map_.emplace("contentEncoding", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&) { return factory_.make_content_encoding_validator(context, sch, parent);} ); keyword_factory_map_.emplace("contentMediaType", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_content_media_type_validator(context, sch, parent);}); if (this->options().require_format_validation()) { keyword_factory_map_.emplace("format", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_format_validator(context, sch, parent);}); } #if defined(JSONCONS_HAS_STD_REGEX) keyword_factory_map_.emplace("pattern", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_pattern_validator(context, sch, parent);}); #endif keyword_factory_map_.emplace("maxItems", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_max_items_validator(context, sch, parent);}); keyword_factory_map_.emplace("minItems", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_min_items_validator(context, sch, parent);}); keyword_factory_map_.emplace("maxProperties", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_max_properties_validator(context, sch, parent);}); keyword_factory_map_.emplace("minProperties", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_min_properties_validator(context, sch, parent);}); keyword_factory_map_.emplace("contains", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict) {return factory_.make_contains_validator(context, sch, parent, anchor_dict);}); keyword_factory_map_.emplace("uniqueItems", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_unique_items_validator(context, sch, parent);}); keyword_factory_map_.emplace("maxLength", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_max_length_validator(context, sch, parent);}); keyword_factory_map_.emplace("minLength", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_min_length_validator(context, sch, parent);}); keyword_factory_map_.emplace("not", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_not_validator(context, sch, parent, anchor_dict);}); keyword_factory_map_.emplace("maximum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_maximum_validator(context, sch, parent);}); keyword_factory_map_.emplace("exclusiveMaximum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_exclusive_maximum_validator(context, sch, parent);}); keyword_factory_map_.emplace("minimum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_minimum_validator(context, sch, parent);}); keyword_factory_map_.emplace("exclusiveMinimum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_exclusive_minimum_validator(context, sch, parent);}); keyword_factory_map_.emplace("multipleOf", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_multiple_of_validator(context, sch, parent);}); keyword_factory_map_.emplace("const", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_const_validator(context, sch, parent);}); keyword_factory_map_.emplace("enum", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_enum_validator(context, sch, parent);}); keyword_factory_map_.emplace("allOf", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_all_of_validator(context, sch, parent, anchor_dict);}); keyword_factory_map_.emplace("anyOf", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_any_of_validator(context, sch, parent, anchor_dict);}); keyword_factory_map_.emplace("oneOf", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_one_of_validator(context, sch, parent, anchor_dict);}); keyword_factory_map_.emplace("dependencies", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_dependencies_validator(context, sch, parent, anchor_dict);}); keyword_factory_map_.emplace("propertyNames", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type& anchor_dict){return factory_.make_property_names_validator(context, sch, parent, anchor_dict);}); keyword_factory_map_.emplace("required", [&](const compilation_context& context, const Json& sch, const Json& parent, anchor_uri_map_type&){return factory_.make_required_validator(context, sch, parent);}); } schema_validator_ptr_type make_schema_validator( const compilation_context& context, const Json& sch, jsoncons::span keys, anchor_uri_map_type& anchor_dict) override { auto new_context = make_compilation_context(context, sch, keys); schema_validator_ptr_type schema_validator_ptr; switch (sch.type()) { case json_type::bool_value: { schema_validator_ptr = this->make_boolean_schema(new_context, sch); schema_validator* p = schema_validator_ptr.get(); for (const auto& uri : new_context.uris()) { this->insert_schema(uri, p); } break; } case json_type::object_value: { auto it = sch.find("$ref"); if (it != sch.object_range().end()) // this schema is a reference { std::vector validators; std::map defs; auto it2 = sch.find("definitions"); if (it2 != sch.object_range().end()) { for (const auto& def : it2->value().object_range()) { std::string sub_keys[] = { "definitions", def.key() }; defs.emplace(def.key(), make_schema_validator(context, def.value(), sub_keys, anchor_dict)); } } Json default_value{ jsoncons::null_type() }; uri relative((*it).value().template as()); auto id = context.get_base_uri().resolve(relative); validators.push_back(this->get_or_create_reference(sch, uri_wrapper{id})); schema_validator_ptr = jsoncons::make_unique>( new_context.get_base_uri(), context.id(), std::move(validators), std::move(defs), std::move(default_value)); } else { schema_validator_ptr = make_object_schema_validator(new_context, sch, anchor_dict); } schema_validator* p = schema_validator_ptr.get(); for (const auto& uri : new_context.uris()) { this->insert_schema(uri, p); for (const auto& item : sch.object_range()) { if (known_keywords().find(item.key()) == known_keywords().end()) { this->insert_unknown_keyword(uri, item.key(), item.value()); // save unknown keywords for later reference } } } break; } default: JSONCONS_THROW(schema_error("invalid JSON-type for a schema for " + new_context.get_base_uri().string() + ", expected: boolean or object")); break; } return schema_validator_ptr; } schema_validator_ptr_type make_object_schema_validator(const compilation_context& context, const Json& sch, anchor_uri_map_type& anchor_dict) { jsoncons::optional id = context.id(); Json default_value{ jsoncons::null_type() }; std::vector validators; std::map defs; auto it = sch.find("definitions"); if (it != sch.object_range().end()) { for (const auto& def : (*it).value().object_range()) { std::string sub_keys[] = { "definitions", def.key() }; defs.emplace(def.key(), make_schema_validator(context, def.value(), sub_keys, anchor_dict)); } } it = sch.find("default"); if (it != sch.object_range().end()) { default_value = (*it).value(); } for (const auto& key_value : sch.object_range()) { auto factory_it = keyword_factory_map_.find(key_value.key()); if (factory_it != keyword_factory_map_.end()) { auto validator = (*factory_it).second(context, key_value.value(), sch, anchor_dict); if (validator) { validators.emplace_back(std::move(validator)); } } } schema_validator_ptr_type if_validator; schema_validator_ptr_type then_validator; schema_validator_ptr_type else_validator; it = sch.find("if"); if (it != sch.object_range().end()) { std::string sub_keys[] = { "if" }; if_validator = make_schema_validator(context, (*it).value(), sub_keys, anchor_dict); } it = sch.find("then"); if (it != sch.object_range().end()) { std::string sub_keys[] = { "then" }; then_validator = make_schema_validator(context, (*it).value(), sub_keys, anchor_dict); } it = sch.find("else"); if (it != sch.object_range().end()) { std::string sub_keys[] = { "else" }; else_validator = make_schema_validator(context, (*it).value(), sub_keys, anchor_dict); } if (if_validator || then_validator || else_validator) { validators.emplace_back(jsoncons::make_unique>( sch, context.get_base_uri(), context.get_custom_message("conditional"), std::move(if_validator), std::move(then_validator), std::move(else_validator))); } std::unique_ptr> properties; it = sch.find("properties"); if (it != sch.object_range().end()) { properties = factory_.make_properties_validator(context, (*it).value(), sch, anchor_dict); } std::unique_ptr> pattern_properties; #if defined(JSONCONS_HAS_STD_REGEX) it = sch.find("patternProperties"); if (it != sch.object_range().end()) { pattern_properties = factory_.make_pattern_properties_validator(context, (*it).value(), sch, anchor_dict); } #endif it = sch.find("additionalProperties"); if (it != sch.object_range().end()) { validators.emplace_back(factory_.make_additional_properties_validator(context, (*it).value(), sch, std::move(properties), std::move(pattern_properties), anchor_dict)); } else { if (properties) { validators.emplace_back(std::move(properties)); } #if defined(JSONCONS_HAS_STD_REGEX) if (pattern_properties) { validators.emplace_back(std::move(pattern_properties)); } #endif } it = sch.find("items"); if (it != sch.object_range().end()) { if ((*it).value().type() == json_type::array_value) { validators.emplace_back(factory_.make_prefix_items_validator_07(context, (*it).value(), sch, anchor_dict)); } else if ((*it).value().type() == json_type::object_value || (*it).value().type() == json_type::bool_value) { validators.emplace_back(factory_.make_items_validator("items", context, (*it).value(), sch, anchor_dict)); } } return jsoncons::make_unique>(context.get_base_uri(), std::move(id), std::move(validators), std::move(defs), std::move(default_value)); } private: compilation_context make_compilation_context(const compilation_context& parent, const Json& sch, jsoncons::span keys) const override { // Exclude uri's that are not plain name identifiers std::vector new_uris; for (const auto& uri : parent.uris()) { if (!uri.has_plain_name_fragment()) { new_uris.push_back(uri); } } // Append the keys for this sub-schema to the uri's for (const auto& key : keys) { for (auto& uri : new_uris) { auto new_u = uri.append(key); uri = uri_wrapper(new_u); } } jsoncons::optional id; std::unordered_map custom_messages{parent.custom_messages()}; std::string custom_message; if (sch.is_object()) { auto it = sch.find("$id"); // If $id is found, this schema can be referenced by the id if (it != sch.object_range().end()) { uri relative((*it).value().template as()); auto resolved = parent.get_base_uri().resolve(relative); id = resolved; //std::cout << "$id: " << id << ", " << new_uri.string() << "\n"; // Add it to the list if it is not already there uri_wrapper new_uri{resolved}; if (std::find(new_uris.begin(), new_uris.end(), new_uri) == new_uris.end()) { new_uris.emplace_back(new_uri); } } if (this->options().enable_custom_error_message()) { it = sch.find("errorMessage"); if (it != sch.object_range().end()) { const auto& value = it->value(); if (value.is_object()) { for (const auto& item : value.object_range()) { custom_messages[item.key()] = item.value().template as(); } } else if (value.is_string()) { custom_message = value.template as(); } } } } /* std::cout << "Absolute URI: " << parent.get_base_uri().string() << "\n"; for (const auto& uri : new_uris) { std::cout << " " << uri.string() << "\n"; } */ return compilation_context(new_uris, id, custom_messages, custom_message); } private: static const std::unordered_set& known_keywords() { static std::unordered_set keywords{ "$id", "$ref", "additionalItems", "additionalProperties", "allOf", "anyOf", "const", "contains", "contentEncoding", "contentMediaType", "default", "definitions", "dependencies", "enum", "exclusiveMaximum", "exclusiveMinimum", "if", "then", "else", "items", "maximum", "maxItems", "maxLength", "maxProperties", "minimum", "minItems", "minLength", "minProperties", "multipleOf", "not", "oneOf", "pattern", "patternProperties", "properties", "propertyNames", "readOnly", "required", "type", "uniqueItems", "writeOnly" }; return keywords; } }; } // namespace draft7 } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_DRAFT7_KEYWORD_FACTORY_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/evaluation_options.hpp000066400000000000000000000073461477700171100263140ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_EVALUATION_OPTIONS_HPP #define JSONCONS_EXT_JSONSCHEMA_EVALUATION_OPTIONS_HPP #include namespace jsoncons { namespace jsonschema { struct schema_version { static std::string draft4() { static std::string s{"http://json-schema.org/draft-04/schema#"}; return s; } static std::string draft6() { static std::string s{"http://json-schema.org/draft-06/schema#"}; return s; } static std::string draft7() { static std::string s{"http://json-schema.org/draft-07/schema#"}; return s; } static std::string draft201909() { static std::string s{"https://json-schema.org/draft/2019-09/schema"}; return s; } static std::string draft202012() { static std::string s{"https://json-schema.org/draft/2020-12/schema"}; return s; } }; class evaluation_options { std::string default_version_; bool require_format_validation_{false}; bool compatibility_mode_{false}; std::string default_base_uri_; bool enable_custom_error_message_{false}; public: evaluation_options() : default_version_{schema_version::draft202012()}, default_base_uri_("https://jsoncons.com") { } evaluation_options(const evaluation_options& other) = default; evaluation_options& operator=(const evaluation_options& other) = default; bool require_format_validation() const { return require_format_validation_; } evaluation_options& require_format_validation(bool value) { require_format_validation_ = value; return *this; } bool compatibility_mode() const { return compatibility_mode_; } evaluation_options& compatibility_mode(bool value) { compatibility_mode_ = value; return *this; } const std::string& default_version() const { return default_version_; } evaluation_options& default_version(const std::string& version) { default_version_ = version; return *this; } const std::string& default_base_uri() const { return default_base_uri_; } evaluation_options& default_base_uri(const std::string& base_uri) { default_base_uri_ = base_uri; return *this; } bool enable_custom_error_message() const { return enable_custom_error_message_; } evaluation_options& enable_custom_error_message(bool value) { enable_custom_error_message_ = value; return *this; } friend bool operator==(const evaluation_options& lhs, const evaluation_options& rhs) { return lhs.default_version_ == rhs.default_version_ && lhs.require_format_validation_ == rhs.require_format_validation_ && lhs.compatibility_mode_ == rhs.compatibility_mode_ && lhs.default_base_uri_ == rhs.default_base_uri_ && lhs.enable_custom_error_message_ == rhs.enable_custom_error_message_; } }; } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_COMMON_SCHEMA_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/json_schema.hpp000066400000000000000000000203261477700171100246540ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_JSON_SCHEMA_HPP #define JSONCONS_EXT_JSONSCHEMA_JSON_SCHEMA_HPP #include #include #include #include #include #include namespace jsoncons { namespace jsonschema { class validation_message_to_json_events { json_visitor* visitor_ptr_; public: validation_message_to_json_events(json_visitor& visitor) : visitor_ptr_(std::addressof(visitor)) { } walk_result operator()(const validation_message& message) { write_error(message); return walk_result::advance; } void write_error(const validation_message& message) { visitor_ptr_->begin_object(); visitor_ptr_->key("valid"); visitor_ptr_->bool_value(false); visitor_ptr_->key("evaluationPath"); visitor_ptr_->string_value(message.eval_path().string()); visitor_ptr_->key("schemaLocation"); visitor_ptr_->string_value(message.schema_location().string()); visitor_ptr_->key("instanceLocation"); visitor_ptr_->string_value(message.instance_location().string()); visitor_ptr_->key("error"); visitor_ptr_->string_value(message.message()); if (!message.details().empty()) { visitor_ptr_->key("details"); visitor_ptr_->begin_array(); for (const auto& detail : message.details()) { write_error(detail); } visitor_ptr_->end_array(); } visitor_ptr_->end_object(); } }; class throwing_error_listener : public error_reporter { walk_result do_error(const validation_message& msg) override { JSONCONS_THROW(validation_error(msg.instance_location().string() + ": " + msg.message())); } }; class fail_early_reporter : public error_reporter { walk_result do_error(const validation_message&) override { return walk_result::abort; } }; using error_reporter_t = std::function; struct error_reporter_adaptor : public error_reporter { error_reporter_t reporter_; error_reporter_adaptor(const error_reporter_t& reporter) : reporter_(reporter) { } private: walk_result do_error(const validation_message& e) override { return reporter_(e); } }; template class json_validator; template class json_schema { using keyword_validator_ptr_type = std::unique_ptr>; using document_schema_validator_type = std::unique_ptr>; document_schema_validator_type root_; friend class json_validator; public: json_schema(document_schema_validator_type&& root) : root_(std::move(root)) { if (root_ == nullptr) JSONCONS_THROW(schema_error("There is no root schema to validate an instance against")); } json_schema(const json_schema&) = delete; json_schema(json_schema&&) = default; json_schema& operator=(const json_schema&) = delete; json_schema& operator=(json_schema&&) = default; // Validate input JSON against a JSON Schema with a default throwing error reporter Json validate(const Json& instance) const { throwing_error_listener reporter; jsonpointer::json_pointer instance_location{}; Json patch(json_array_arg); eval_context context; evaluation_results results; root_->validate(context, instance, instance_location, results, reporter, patch); return patch; } // Validate input JSON against a JSON Schema bool is_valid(const Json& instance) const { fail_early_reporter reporter; jsonpointer::json_pointer instance_location{}; Json patch(json_array_arg); eval_context context; evaluation_results results; root_->validate(context, instance, instance_location, results, reporter, patch); return reporter.error_count() == 0; } // Validate input JSON against a JSON Schema with a provided error reporter template typename std::enable_if::value,void>::type validate(const Json& instance, const MsgReporter& reporter) const { jsonpointer::json_pointer instance_location{}; Json patch(json_array_arg); error_reporter_adaptor adaptor(reporter); eval_context context; evaluation_results results; root_->validate(context, instance, instance_location, results, adaptor, patch); } // Validate input JSON against a JSON Schema with a provided error reporter template typename std::enable_if::value,void>::type validate(const Json& instance, MsgReporter&& reporter, Json& patch) const { jsonpointer::json_pointer instance_location{}; patch = Json(json_array_arg); error_reporter_adaptor adaptor(std::forward(reporter)); eval_context context; evaluation_results results; root_->validate(context, instance, instance_location, results, adaptor, patch); } // Validate input JSON against a JSON Schema with a provided error reporter void validate(const Json& instance, Json& patch) const { jsonpointer::json_pointer instance_location{}; patch = Json(json_array_arg); fail_early_reporter reporter; eval_context context; evaluation_results results; root_->validate(context, instance, instance_location, results, reporter, patch); } // Validate input JSON against a JSON Schema with a provided json_visitor void validate(const Json& instance, json_visitor& visitor) const { visitor.begin_array(); jsonpointer::json_pointer instance_location{}; Json patch{json_array_arg}; validation_message_to_json_events adaptor{ visitor }; eval_context context; evaluation_results results; error_reporter_adaptor reporter(adaptor); root_->validate(context, instance, instance_location, results, reporter, patch); visitor.end_array(); visitor.flush(); } template void walk(const Json& instance, const WalkReporter& reporter) const { jsonpointer::json_pointer instance_location{}; root_->walk(eval_context{}, instance, instance_location, reporter); } private: // Validate input JSON against a JSON Schema with a provided error reporter void validate2(const Json& instance, error_reporter& reporter, Json& patch) const { jsonpointer::json_pointer instance_location{}; patch = Json(json_array_arg); eval_context context; evaluation_results results; root_->validate(context, instance, instance_location, results, reporter, patch); } }; } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_SCHEMA_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/json_schema_factory.hpp000066400000000000000000000320641477700171100264050ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_JSON_SCHEMA_FACTORY_HPP #define JSONCONS_EXT_JSONSCHEMA_JSON_SCHEMA_FACTORY_HPP #include #include #include #include #include #include #include #include namespace jsoncons { namespace jsonschema { template class validator_factory_factory { public: using schema_store_type = std::map*>; validator_factory_factory() { } std::unique_ptr> operator()(Json sch, const evaluation_options& options, schema_store_type* schema_store_ptr, const std::vector>& resolve_funcs, const std::unordered_map& vocabulary) const { std::unique_ptr> factory; if (sch.is_object()) { auto it = sch.find("$schema"); if (it != sch.object_range().end()) { factory = get_factory(std::move(sch), (*it).value().as_string_view(), options, schema_store_ptr, resolve_funcs, vocabulary); if (!factory) { std::string message("Unsupported schema version "); message.append((*it).value().template as()); JSONCONS_THROW(schema_error(message)); } } else { factory = get_default_schema_factory(std::move(sch), options, schema_store_ptr, resolve_funcs, vocabulary); } } else if (sch.is_bool()) { factory = get_default_schema_factory(std::move(sch), options, schema_store_ptr, resolve_funcs, vocabulary); } else { JSONCONS_THROW(schema_error("Schema must be object or boolean")); } return factory; } std::unique_ptr> get_default_schema_factory(Json&& sch, const evaluation_options& options, schema_store_type* schema_store_ptr, const std::vector>& resolve_funcs, const std::unordered_map& vocabulary) const { if (options.default_version() == schema_version::draft202012()) { return jsoncons::make_unique>(std::move(sch), *this, options, schema_store_ptr, resolve_funcs, vocabulary); } else if (options.default_version() == schema_version::draft201909()) { return jsoncons::make_unique>(std::move(sch), *this, options, schema_store_ptr, resolve_funcs, vocabulary); } else if (options.default_version() == schema_version::draft7()) { return jsoncons::make_unique>(std::move(sch), *this, options, schema_store_ptr, resolve_funcs); } else if (options.default_version() == schema_version::draft6()) { return jsoncons::make_unique>(std::move(sch), *this, options, schema_store_ptr, resolve_funcs); } else if (options.default_version() == schema_version::draft4()) { return jsoncons::make_unique>(std::move(sch), *this, options, schema_store_ptr, resolve_funcs); } else { JSONCONS_THROW(schema_error("Unsupported schema version " + options.default_version())); } } std::unique_ptr> get_factory(Json&& sch, const jsoncons::string_view& schema_id, const evaluation_options& options, schema_store_type* schema_store_ptr, const std::vector>& resolve_funcs, const std::unordered_map& vocabulary) const { std::unique_ptr> factory; if (schema_id == schema_version::draft202012()) { factory = jsoncons::make_unique>(std::move(sch), *this, options, schema_store_ptr, resolve_funcs, vocabulary); } else if (schema_id == schema_version::draft201909()) { factory = jsoncons::make_unique>(std::move(sch), *this, options, schema_store_ptr, resolve_funcs, vocabulary); } else if (schema_id == schema_version::draft7()) { factory = jsoncons::make_unique>(std::move(sch), *this, options, schema_store_ptr, resolve_funcs); } else if (schema_id == schema_version::draft6()) { factory = jsoncons::make_unique>(std::move(sch), *this, options, schema_store_ptr, resolve_funcs); } else if (schema_id == schema_version::draft4()) { factory = jsoncons::make_unique>(std::move(sch), *this, options, schema_store_ptr, resolve_funcs); } else { factory = get_factory_from_meta_schema(std::move(sch), schema_id, options, schema_store_ptr, resolve_funcs); } return factory; } std::unique_ptr> get_factory_from_meta_schema(Json&& sch, const jsoncons::string_view& schema_id, const evaluation_options& options, schema_store_type* schema_store_ptr, const std::vector>& resolve_funcs) const { std::unique_ptr> factory; bool found = false; jsoncons::uri uri{ std::string(schema_id) }; for (auto it = resolve_funcs.begin(); it != resolve_funcs.end() && !found; ++it) { Json meta_sch = (*it)(uri.base()); if (meta_sch.is_object()) { std::unordered_map vocabulary; auto vocab_it = meta_sch.find("$vocabulary"); if (vocab_it != meta_sch.object_range().end()) { const auto& vocab = (*vocab_it).value(); if (vocab.is_object()) { for (const auto& member : vocab.object_range()) { vocabulary.emplace(member.key(), member.value().as_bool()); } } } auto schema_it = meta_sch.find("$schema"); if (schema_it != meta_sch.object_range().end()) { factory = get_factory(std::move(sch), (*schema_it).value().as_string_view(), options, schema_store_ptr, resolve_funcs, vocabulary); found = true; } } } return factory; } }; template Json meta_resolver(const jsoncons::uri& uri) { if (uri.base() == jsoncons::uri{schema_version::draft202012()}) { return jsoncons::jsonschema::draft202012::schema_draft202012::get_schema(); } else if (uri.base() == jsoncons::uri{schema_version::draft201909()}) { return jsoncons::jsonschema::draft201909::schema_draft201909::get_schema(); } else if (uri.base() == jsoncons::uri{schema_version::draft7()}) { return jsoncons::jsonschema::draft7::schema_draft7::get_schema(); } else if (uri.base() == jsoncons::uri{schema_version::draft6()}) { return jsoncons::jsonschema::draft6::schema_draft6::get_schema(); } else if (uri.base() == jsoncons::uri{schema_version::draft4()}) { return jsoncons::jsonschema::draft4::schema_draft4::get_schema(); } else { return Json::null(); } } template typename std::enable_if::value,json_schema>::type make_json_schema(Json sch, const std::string& retrieval_uri, const SchemaResolver& resolver, evaluation_options options = evaluation_options{}) { using schema_store_type = std::map*>; schema_store_type schema_store; validator_factory_factory factory_factory{}; std::unordered_map vocabulary{}; std::vector> resolve_funcs = {{meta_resolver, resolver}}; auto schema_validator_factory_base = factory_factory(std::move(sch), options, &schema_store, resolve_funcs, vocabulary); schema_validator_factory_base->build_schema(retrieval_uri); return json_schema(schema_validator_factory_base->get_schema_validator()); } template json_schema make_json_schema(Json sch, const std::string& retrieval_uri, evaluation_options options = evaluation_options{}) { using schema_store_type = std::map*>; schema_store_type schema_store; validator_factory_factory factory_factory{}; std::unordered_map vocabulary{}; std::vector> resolve_funcs = {{meta_resolver}}; auto schema_validator_factory_base = factory_factory(std::move(sch), options, &schema_store, resolve_funcs, vocabulary); schema_validator_factory_base->build_schema(retrieval_uri); return json_schema(schema_validator_factory_base->get_schema_validator()); } template typename std::enable_if::value,json_schema>::type make_json_schema(Json sch, const SchemaResolver& resolver, evaluation_options options = evaluation_options{}) { using schema_store_type = std::map*>; schema_store_type schema_store; validator_factory_factory factory_factory{}; std::unordered_map vocabulary{}; std::vector> resolve_funcs = {{meta_resolver, resolver}}; auto schema_validator_factory_base = factory_factory(std::move(sch), options, &schema_store, resolve_funcs, vocabulary); schema_validator_factory_base->build_schema(); return json_schema(schema_validator_factory_base->get_schema_validator()); } template json_schema make_json_schema(Json sch, evaluation_options options = evaluation_options{}) { using schema_store_type = std::map*>; schema_store_type schema_store; validator_factory_factory factory_factory{}; std::unordered_map vocabulary{}; std::vector> resolve_funcs = {{meta_resolver}}; auto schema_validator_factory_base = factory_factory(std::move(sch), options, &schema_store, resolve_funcs, vocabulary); schema_validator_factory_base->build_schema(); return json_schema(schema_validator_factory_base->get_schema_validator()); } } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_SCHEMA_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/jsonschema.hpp000066400000000000000000000007071477700171100245160ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_JSONSCHEMA_HPP #define JSONCONS_EXT_JSONSCHEMA_JSONSCHEMA_HPP #include #endif // JSONCONS_EXT_JSONSCHEMA_JSONSCHEMA_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/jsonschema_error.hpp000066400000000000000000000024271477700171100257300ustar00rootroot00000000000000/// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_JSONSCHEMA_ERROR_HPP #define JSONCONS_EXT_JSONSCHEMA_JSONSCHEMA_ERROR_HPP #include #include #include #include namespace jsoncons { namespace jsonschema { class schema_error : public std::runtime_error, public virtual json_exception { public: schema_error(const std::string& message) : std::runtime_error(message) { } const char* what() const noexcept override { return std::runtime_error::what(); } }; class validation_error : public std::runtime_error, public virtual json_exception { public: validation_error(const std::string& message) : std::runtime_error(message) { } const char* what() const noexcept override { return std::runtime_error::what(); } }; } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_JSONSCHEMA_ERROR_HPP jsoncons-1.3.2/include/jsoncons_ext/jsonschema/validation_message.hpp000066400000000000000000000053511477700171100262220ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_JSONSCHEMA_VALIDATION_MESSAGE_HPP #define JSONCONS_EXT_JSONSCHEMA_VALIDATION_MESSAGE_HPP #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace jsonschema { class validation_message { std::string keyword_; jsonpointer::json_pointer eval_path_; uri schema_location_; jsonpointer::json_pointer instance_location_; std::string message_; std::vector details_; public: validation_message(std::string keyword, jsonpointer::json_pointer eval_path, uri schema_location, jsonpointer::json_pointer instance_location, std::string message) : keyword_(std::move(keyword)), eval_path_(std::move(eval_path)), schema_location_(std::move(schema_location)), instance_location_(std::move(instance_location)), message_(std::move(message)) { } validation_message(const std::string& keyword, const jsonpointer::json_pointer& eval_path, const uri& schema_location, const jsonpointer::json_pointer& instance_location, const std::string& message, const std::vector& details) : keyword_(keyword), eval_path_(eval_path), schema_location_(schema_location), instance_location_(instance_location), message_(message), details_(details) { } const jsonpointer::json_pointer& instance_location() const { return instance_location_; } const std::string& message() const { return message_; } const jsonpointer::json_pointer& eval_path() const { return eval_path_; } const uri& schema_location() const { return schema_location_; } const std::string& keyword() const { return keyword_; } const std::vector& details() const { return details_; } }; } // namespace jsonschema } // namespace jsoncons #endif // JSONCONS_EXT_JSONSCHEMA_JSON_VALIDATOR_HPP jsoncons-1.3.2/include/jsoncons_ext/mergepatch/000077500000000000000000000000001477700171100216345ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons_ext/mergepatch/mergepatch.hpp000066400000000000000000000056721477700171100244760ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_MERGEPATCH_MERGEPATCH_HPP #define JSONCONS_EXT_MERGEPATCH_MERGEPATCH_HPP #include namespace jsoncons { namespace mergepatch { template Json from_diff(const Json& source, const Json& target) { if (!source.is_object() || !target.is_object()) { return target; } Json result(json_object_arg); for (const auto& member : source.object_range()) { auto it = target.find(member.key()); if (it != target.object_range().end()) { if (member.value() != (*it).value()) { result.try_emplace(member.key(), from_diff(member.value(), (*it).value())); } } else { result.try_emplace(member.key(), Json::null()); } } for (const auto& member : target.object_range()) { auto it = source.find(member.key()); if (it == source.object_range().end()) { result.try_emplace(member.key(), member.value()); } } return result; } namespace detail { template Json apply_merge_patch_(Json& target, const Json& patch) { if (patch.is_object()) { if (!target.is_object()) { target = Json(json_object_arg); } for (auto& member : patch.object_range()) { auto it = target.find(member.key()); if (it != target.object_range().end()) { Json item = (*it).value(); target.erase(it); if (!member.value().is_null()) { target.try_emplace(member.key(), apply_merge_patch_(item, member.value())); } } else if (!member.value().is_null()) { Json item(json_object_arg); target.try_emplace(member.key(), apply_merge_patch_(item, member.value())); } } return target; } else { return patch; } } } // namespace detail template void apply_merge_patch(Json& target, const Json& patch) { target = detail::apply_merge_patch_(target, patch); } } // namespace mergepatch } // namespace jsoncons #endif // JSONCONS_EXT_MERGEPATCH_MERGEPATCH_HPP jsoncons-1.3.2/include/jsoncons_ext/msgpack/000077500000000000000000000000001477700171100211425ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons_ext/msgpack/decode_msgpack.hpp000066400000000000000000000214731477700171100246120ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_MSGPACK_DECODE_MSGPACK_HPP #define JSONCONS_EXT_MSGPACK_DECODE_MSGPACK_HPP #include // std::basic_istream #include // std::enable_if #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace msgpack { template typename std::enable_if::value && extension_traits::is_byte_sequence::value,T>::type decode_msgpack(const Source& v, const msgpack_decode_options& options = msgpack_decode_options()) { jsoncons::json_decoder decoder; auto adaptor = make_json_visitor_adaptor(decoder); basic_msgpack_reader reader(v, adaptor, options); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value && extension_traits::is_byte_sequence::value,T>::type decode_msgpack(const Source& v, const msgpack_decode_options& options = msgpack_decode_options()) { basic_msgpack_cursor cursor(v, options); json_decoder> decoder{}; std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } template typename std::enable_if::value,T>::type decode_msgpack(std::istream& is, const msgpack_decode_options& options = msgpack_decode_options()) { jsoncons::json_decoder decoder; auto adaptor = make_json_visitor_adaptor(decoder); msgpack_stream_reader reader(is, adaptor, options); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value,T>::type decode_msgpack(std::istream& is, const msgpack_decode_options& options = msgpack_decode_options()) { basic_msgpack_cursor cursor(is, options); json_decoder> decoder{}; std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } template typename std::enable_if::value,T>::type decode_msgpack(InputIt first, InputIt last, const msgpack_decode_options& options = msgpack_decode_options()) { jsoncons::json_decoder decoder; auto adaptor = make_json_visitor_adaptor(decoder); basic_msgpack_reader> reader(binary_iterator_source(first, last), adaptor, options); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value,T>::type decode_msgpack(InputIt first, InputIt last, const msgpack_decode_options& options = msgpack_decode_options()) { basic_msgpack_cursor> cursor(binary_iterator_source(first, last), options); json_decoder> decoder{}; std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } // With leading allocator_set parameter template typename std::enable_if::value && extension_traits::is_byte_sequence::value,T>::type decode_msgpack(const allocator_set& alloc_set, const Source& v, const msgpack_decode_options& options = msgpack_decode_options()) { json_decoder decoder(alloc_set.get_allocator(), alloc_set.get_temp_allocator()); auto adaptor = make_json_visitor_adaptor(decoder); basic_msgpack_reader reader(v, adaptor, options, alloc_set.get_temp_allocator()); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value && extension_traits::is_byte_sequence::value,T>::type decode_msgpack(const allocator_set& alloc_set, const Source& v, const msgpack_decode_options& options = msgpack_decode_options()) { basic_msgpack_cursor cursor(v, options, alloc_set.get_temp_allocator()); json_decoder,TempAllocator> decoder(alloc_set.get_temp_allocator(), alloc_set.get_temp_allocator()); std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } template typename std::enable_if::value,T>::type decode_msgpack(const allocator_set& alloc_set, std::istream& is, const msgpack_decode_options& options = msgpack_decode_options()) { json_decoder decoder(alloc_set.get_allocator(), alloc_set.get_temp_allocator()); auto adaptor = make_json_visitor_adaptor(decoder); basic_msgpack_reader reader(is, adaptor, options, alloc_set.get_temp_allocator()); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value,T>::type decode_msgpack(const allocator_set& alloc_set, std::istream& is, const msgpack_decode_options& options = msgpack_decode_options()) { basic_msgpack_cursor cursor(is, options, alloc_set.get_temp_allocator()); json_decoder,TempAllocator> decoder(alloc_set.get_temp_allocator(), alloc_set.get_temp_allocator()); std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } } // namespace msgpack } // namespace jsoncons #endif // JSONCONS_EXT_MSGPACK_DECODE_MSGPACK_HPP jsoncons-1.3.2/include/jsoncons_ext/msgpack/encode_msgpack.hpp000066400000000000000000000144771477700171100246320ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_MSGPACK_ENCODE_MSGPACK_HPP #define JSONCONS_EXT_MSGPACK_ENCODE_MSGPACK_HPP #include // std::basic_ostream #include #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace msgpack { template typename std::enable_if::value && extension_traits::is_back_insertable_byte_container::value,void>::type encode_msgpack(const T& j, ByteContainer& cont, const msgpack_encode_options& options = msgpack_encode_options()) { using char_type = typename T::char_type; basic_msgpack_encoder> encoder(cont, options); auto adaptor = make_json_visitor_adaptor>(encoder); j.dump(adaptor); } template typename std::enable_if::value && extension_traits::is_back_insertable_byte_container::value,void>::type encode_msgpack(const T& val, ByteContainer& cont, const msgpack_encode_options& options = msgpack_encode_options()) { basic_msgpack_encoder> encoder(cont, options); std::error_code ec; encode_traits::encode(val, encoder, json(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } template typename std::enable_if::value,void>::type encode_msgpack(const T& j, std::ostream& os, const msgpack_encode_options& options = msgpack_encode_options()) { using char_type = typename T::char_type; msgpack_stream_encoder encoder(os, options); auto adaptor = make_json_visitor_adaptor>(encoder); j.dump(adaptor); } template typename std::enable_if::value,void>::type encode_msgpack(const T& val, std::ostream& os, const msgpack_encode_options& options = msgpack_encode_options()) { msgpack_stream_encoder encoder(os, options); std::error_code ec; encode_traits::encode(val, encoder, json(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } // with temp_allocator_arg_t template typename std::enable_if::value && extension_traits::is_back_insertable_byte_container::value,void>::type encode_msgpack(const allocator_set& alloc_set, const T& j, ByteContainer& cont, const msgpack_encode_options& options = msgpack_encode_options()) { using char_type = typename T::char_type; basic_msgpack_encoder,TempAllocator> encoder(cont, options, alloc_set.get_temp_allocator()); auto adaptor = make_json_visitor_adaptor>(encoder); j.dump(adaptor); } template typename std::enable_if::value && extension_traits::is_back_insertable_byte_container::value,void>::type encode_msgpack(const allocator_set& alloc_set, const T& val, ByteContainer& cont, const msgpack_encode_options& options = msgpack_encode_options()) { basic_msgpack_encoder,TempAllocator> encoder(cont, options, alloc_set.get_temp_allocator()); std::error_code ec; encode_traits::encode(val, encoder, json(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } template typename std::enable_if::value,void>::type encode_msgpack(const allocator_set& alloc_set, const T& j, std::ostream& os, const msgpack_encode_options& options = msgpack_encode_options()) { using char_type = typename T::char_type; basic_msgpack_encoder encoder(os, options, alloc_set.get_temp_allocator()); auto adaptor = make_json_visitor_adaptor>(encoder); j.dump(adaptor); } template typename std::enable_if::value,void>::type encode_msgpack(const allocator_set& alloc_set, const T& val, std::ostream& os, const msgpack_encode_options& options = msgpack_encode_options()) { basic_msgpack_encoder encoder(os, options, alloc_set.get_temp_allocator()); std::error_code ec; encode_traits::encode(val, encoder, json(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } } // namespace msgpack } // namespace jsoncons #endif // JSONCONS_EXT_MSGPACK_ENCODE_MSGPACK_HPP jsoncons-1.3.2/include/jsoncons_ext/msgpack/msgpack.hpp000066400000000000000000000011731477700171100233020ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_MSGPACK_MSGPACK_HPP #define JSONCONS_EXT_MSGPACK_MSGPACK_HPP #include #include #include #include #include #endif // JSONCONS_EXT_MSGPACK_MSGPACK_HPP jsoncons-1.3.2/include/jsoncons_ext/msgpack/msgpack_cursor.hpp000066400000000000000000000202041477700171100246730ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_MSGPACK_MSGPACK_CURSOR_HPP #define JSONCONS_EXT_MSGPACK_MSGPACK_CURSOR_HPP #include #include #include // std::allocator #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace msgpack { template > class basic_msgpack_cursor : public basic_staj_cursor, private virtual ser_context { public: using source_type = Source; using char_type = char; using allocator_type = Allocator; private: basic_msgpack_parser parser_; basic_staj_visitor cursor_visitor_; basic_item_event_visitor_to_json_visitor cursor_handler_adaptor_; bool eof_{false}; public: using string_view_type = string_view; // Noncopyable and nonmoveable basic_msgpack_cursor(const basic_msgpack_cursor&) = delete; basic_msgpack_cursor(basic_msgpack_cursor&&) = delete; template basic_msgpack_cursor(Sourceable&& source, const msgpack_decode_options& options = msgpack_decode_options(), const Allocator& alloc = Allocator()) : parser_(std::forward(source), options, alloc), cursor_handler_adaptor_(cursor_visitor_, alloc) { parser_.cursor_mode(true); if (!done()) { next(); } } // Constructors that set parse error codes template basic_msgpack_cursor(Sourceable&& source, std::error_code& ec) : basic_msgpack_cursor(std::allocator_arg, Allocator(), std::forward(source), msgpack_decode_options(), ec) { } template basic_msgpack_cursor(Sourceable&& source, const msgpack_decode_options& options, std::error_code& ec) : basic_msgpack_cursor(std::allocator_arg, Allocator(), std::forward(source), options, ec) { } template basic_msgpack_cursor(std::allocator_arg_t, const Allocator& alloc, Sourceable&& source, const msgpack_decode_options& options, std::error_code& ec) : parser_(std::forward(source), options, alloc), cursor_handler_adaptor_(cursor_visitor_, alloc), eof_(false) { parser_.cursor_mode(true); if (!done()) { next(ec); } } basic_msgpack_cursor& operator=(const basic_msgpack_cursor&) = delete; basic_msgpack_cursor& operator=(basic_msgpack_cursor&&) = delete; ~basic_msgpack_cursor() = default; void reset() { parser_.reset(); cursor_visitor_.reset(); cursor_handler_adaptor_.reset(); eof_ = false; if (!done()) { next(); } } template void reset(Sourceable&& source) { parser_.reset(std::forward(source)); cursor_visitor_.reset(); cursor_handler_adaptor_.reset(); eof_ = false; if (!done()) { next(); } } void reset(std::error_code& ec) { parser_.reset(); cursor_visitor_.reset(); cursor_handler_adaptor_.reset(); eof_ = false; if (!done()) { next(ec); } } template void reset(Sourceable&& source, std::error_code& ec) { parser_.reset(std::forward(source)); cursor_visitor_.reset(); cursor_handler_adaptor_.reset(); eof_ = false; if (!done()) { next(ec); } } bool done() const override { return parser_.done(); } const staj_event& current() const override { return cursor_visitor_.event(); } void read_to(basic_json_visitor& visitor) override { std::error_code ec; read_to(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); } } void read_to(basic_json_visitor& visitor, std::error_code& ec) override { if (is_begin_container(current().event_type())) { parser_.cursor_mode(false); parser_.mark_level(parser_.level()); cursor_visitor_.event().send_json_event(visitor, *this, ec); if (JSONCONS_UNLIKELY(ec)) { return; } read_next(visitor, ec); parser_.cursor_mode(true); parser_.mark_level(0); if (current().event_type() == staj_event_type::begin_object) { cursor_visitor_.end_object(*this); } else { cursor_visitor_.end_array(*this); } } else { cursor_visitor_.event().send_json_event(visitor, *this, ec); } } void next() override { std::error_code ec; next(ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); } } void next(std::error_code& ec) override { read_next(ec); } const ser_context& context() const override { return *this; } bool eof() const { return eof_; } std::size_t line() const override { return parser_.line(); } std::size_t column() const override { return parser_.column(); } friend staj_filter_view operator|(basic_msgpack_cursor& cursor, std::function pred) { return staj_filter_view(cursor, pred); } private: void read_next(std::error_code& ec) { if (cursor_visitor_.in_available()) { cursor_visitor_.send_available(ec); } else { parser_.restart(); while (!parser_.stopped()) { parser_.parse(cursor_handler_adaptor_, ec); if (JSONCONS_UNLIKELY(ec)) {return;} } } } void read_next(basic_json_visitor& visitor, std::error_code& ec) { { struct resource_wrapper { basic_item_event_visitor_to_json_visitor& adaptor; basic_json_visitor& original; resource_wrapper(basic_item_event_visitor_to_json_visitor& adaptor, basic_json_visitor& visitor) : adaptor(adaptor), original(adaptor.destination()) { adaptor.destination(visitor); } ~resource_wrapper() { adaptor.destination(original); } } wrapper(cursor_handler_adaptor_, visitor); parser_.restart(); while (!parser_.stopped()) { parser_.parse(cursor_handler_adaptor_, ec); if (JSONCONS_UNLIKELY(ec)) {return;} } } } }; using msgpack_stream_cursor = basic_msgpack_cursor; using msgpack_bytes_cursor = basic_msgpack_cursor; } // namespace msgpack } // namespace jsoncons #endif // JSONCONS_EXT_MSGPACK_MSGPACK_CURSOR_HPP jsoncons-1.3.2/include/jsoncons_ext/msgpack/msgpack_encoder.hpp000066400000000000000000000723511477700171100250070ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_MSGPACK_MSGPACK_ENCODER_HPP #define JSONCONS_EXT_MSGPACK_MSGPACK_ENCODER_HPP #include #include #include #include // std::numeric_limits #include #include #include // std::move #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace msgpack { enum class msgpack_container_type {object, array}; template > class basic_msgpack_encoder final : public basic_json_visitor { enum class decimal_parse_state { start, integer, exp1, exp2, fraction1 }; static constexpr int64_t nanos_in_milli = 1000000; static constexpr int64_t nanos_in_second = 1000000000; static constexpr int64_t millis_in_second = 1000; public: using allocator_type = Allocator; using char_type = char; using typename basic_json_visitor::string_view_type; using sink_type = Sink; private: struct stack_item { msgpack_container_type type_; std::size_t length_; std::size_t index_{0}; stack_item(msgpack_container_type type, std::size_t length = 0) noexcept : type_(type), length_(length) { } std::size_t length() const { return length_; } std::size_t count() const { return is_object() ? index_/2 : index_; } bool is_object() const { return type_ == msgpack_container_type::object; } }; Sink sink_; const msgpack_encode_options options_; allocator_type alloc_; std::vector stack_; int nesting_depth_{0}; public: // Noncopyable and nonmoveable basic_msgpack_encoder(const basic_msgpack_encoder&) = delete; basic_msgpack_encoder(basic_msgpack_encoder&&) = delete; explicit basic_msgpack_encoder(Sink&& sink, const Allocator& alloc = Allocator()) : basic_msgpack_encoder(std::forward(sink), msgpack_encode_options(), alloc) { } explicit basic_msgpack_encoder(Sink&& sink, const msgpack_encode_options& options, const Allocator& alloc = Allocator()) : sink_(std::forward(sink)), options_(options), alloc_(alloc) { } ~basic_msgpack_encoder() noexcept { sink_.flush(); } basic_msgpack_encoder& operator=(const basic_msgpack_encoder&) = delete; basic_msgpack_encoder& operator=(basic_msgpack_encoder&&) = delete; void reset() { stack_.clear(); nesting_depth_ = 0; } void reset(Sink&& sink) { sink_ = std::move(sink); reset(); } private: // Implementing methods void visit_flush() final { sink_.flush(); } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag, const ser_context&, std::error_code& ec) final { ec = msgpack_errc::object_length_required; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(std::size_t length, semantic_tag, const ser_context&, std::error_code& ec) final { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = msgpack_errc::max_nesting_depth_exceeded; JSONCONS_VISITOR_RETURN; } stack_.emplace_back(msgpack_container_type::object, length); if (length <= 15) { // fixmap sink_.push_back(jsoncons::msgpack::msgpack_type::fixmap_base_type | (length & 0xf)); } else if (length <= 65535) { // map 16 sink_.push_back(jsoncons::msgpack::msgpack_type::map16_type); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } else if (length <= (std::numeric_limits::max)()) { // map 32 sink_.push_back(jsoncons::msgpack::msgpack_type::map32_type); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context&, std::error_code& ec) final { JSONCONS_ASSERT(!stack_.empty()); --nesting_depth_; if (stack_.back().count() < stack_.back().length()) { ec = msgpack_errc::too_few_items; JSONCONS_VISITOR_RETURN; } else if (stack_.back().count() > stack_.back().length()) { ec = msgpack_errc::too_many_items; JSONCONS_VISITOR_RETURN; } stack_.pop_back(); end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag, const ser_context&, std::error_code& ec) final { ec = msgpack_errc::array_length_required; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(std::size_t length, semantic_tag, const ser_context&, std::error_code& ec) final { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = msgpack_errc::max_nesting_depth_exceeded; JSONCONS_VISITOR_RETURN; } stack_.emplace_back(msgpack_container_type::array, length); if (length <= 15) { // fixarray sink_.push_back(jsoncons::msgpack::msgpack_type::fixarray_base_type | (length & 0xf)); } else if (length <= (std::numeric_limits::max)()) { // array 16 sink_.push_back(jsoncons::msgpack::msgpack_type::array16_type); binary::native_to_big(static_cast(length),std::back_inserter(sink_)); } else if (length <= (std::numeric_limits::max)()) { // array 32 sink_.push_back(jsoncons::msgpack::msgpack_type::array32_type); binary::native_to_big(static_cast(length),std::back_inserter(sink_)); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context&, std::error_code& ec) final { JSONCONS_ASSERT(!stack_.empty()); --nesting_depth_; if (stack_.back().count() < stack_.back().length()) { ec = msgpack_errc::too_few_items; JSONCONS_VISITOR_RETURN; } else if (stack_.back().count() > stack_.back().length()) { ec = msgpack_errc::too_many_items; JSONCONS_VISITOR_RETURN; } stack_.pop_back(); end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type& name, const ser_context& context, std::error_code& ec) override { visit_string(name, semantic_tag::none, context, ec); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag, const ser_context&, std::error_code&) final { // nil sink_.push_back(jsoncons::msgpack::msgpack_type::nil_type); end_value(); JSONCONS_VISITOR_RETURN; } void write_timestamp(int64_t seconds, int64_t nanoseconds) { if ((seconds >> 34) == 0) { uint64_t data64 = (nanoseconds << 34) | seconds; if ((data64 & 0xffffffff00000000L) == 0) { // timestamp 32 sink_.push_back(jsoncons::msgpack::msgpack_type::fixext4_type); sink_.push_back(0xff); binary::native_to_big(static_cast(data64), std::back_inserter(sink_)); } else { // timestamp 64 sink_.push_back(jsoncons::msgpack::msgpack_type::fixext8_type); sink_.push_back(0xff); binary::native_to_big(static_cast(data64), std::back_inserter(sink_)); } } else { // timestamp 96 sink_.push_back(jsoncons::msgpack::msgpack_type::ext8_type); sink_.push_back(0x0c); // 12 sink_.push_back(0xff); binary::native_to_big(static_cast(nanoseconds), std::back_inserter(sink_)); binary::native_to_big(static_cast(seconds), std::back_inserter(sink_)); } } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& sv, semantic_tag tag, const ser_context&, std::error_code& ec) final { switch (tag) { case semantic_tag::epoch_second: { int64_t seconds; auto result = jsoncons::detail::to_integer(sv.data(), sv.length(), seconds); if (!result) { ec = msgpack_errc::invalid_timestamp; JSONCONS_VISITOR_RETURN; } write_timestamp(seconds, 0); break; } case semantic_tag::epoch_milli: { bigint n = bigint::from_string(sv.data(), sv.length()); if (n != 0) { bigint q; bigint rem; n.divide(millis_in_second, q, rem, true); auto seconds = static_cast(q); auto nanoseconds = static_cast(rem) * nanos_in_milli; if (nanoseconds < 0) { nanoseconds = -nanoseconds; } write_timestamp(seconds, nanoseconds); } else { write_timestamp(0, 0); } break; } case semantic_tag::epoch_nano: { bigint n = bigint::from_string(sv.data(), sv.length()); if (n != 0) { bigint q; bigint rem; n.divide(nanos_in_second, q, rem, true); auto seconds = static_cast(q); auto nanoseconds = static_cast(rem); if (nanoseconds < 0) { nanoseconds = -nanoseconds; } write_timestamp(seconds, nanoseconds); } else { write_timestamp(0, 0); } break; } default: { write_string_value(sv); end_value(); break; } } JSONCONS_VISITOR_RETURN; } void write_string_value(const string_view_type& sv) { auto sink = unicode_traits::validate(sv.data(), sv.size()); if (sink.ec != unicode_traits::conv_errc()) { JSONCONS_THROW(ser_error(msgpack_errc::invalid_utf8_text_string)); } const size_t length = sv.length(); if (length <= 31) { // fixstr stores a byte array whose length is upto 31 bytes sink_.push_back(jsoncons::msgpack::msgpack_type::fixstr_base_type | static_cast(length)); } else if (length <= (std::numeric_limits::max)()) { // str 8 stores a byte array whose length is upto (2^8)-1 bytes sink_.push_back(jsoncons::msgpack::msgpack_type::str8_type); sink_.push_back(static_cast(length)); } else if (length <= (std::numeric_limits::max)()) { // str 16 stores a byte array whose length is upto (2^16)-1 bytes sink_.push_back(jsoncons::msgpack::msgpack_type::str16_type); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } else if (length <= (std::numeric_limits::max)()) { // str 32 stores a byte array whose length is upto (2^32)-1 bytes sink_.push_back(jsoncons::msgpack::msgpack_type::str32_type); binary::native_to_big(static_cast(length),std::back_inserter(sink_)); } for (auto c : sv) { sink_.push_back(c); } } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& b, semantic_tag, const ser_context&, std::error_code&) final { const std::size_t length = b.size(); if (length <= (std::numeric_limits::max)()) { // bin 8 stores a byte array whose length is upto (2^8)-1 bytes sink_.push_back(jsoncons::msgpack::msgpack_type::bin8_type); sink_.push_back(static_cast(length)); } else if (length <= (std::numeric_limits::max)()) { // bin 16 stores a byte array whose length is upto (2^16)-1 bytes sink_.push_back(jsoncons::msgpack::msgpack_type::bin16_type); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } else if (length <= (std::numeric_limits::max)()) { // bin 32 stores a byte array whose length is upto (2^32)-1 bytes sink_.push_back(jsoncons::msgpack::msgpack_type::bin32_type); binary::native_to_big(static_cast(length),std::back_inserter(sink_)); } for (auto c : b) { sink_.push_back(c); } end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& b, uint64_t ext_tag, const ser_context&, std::error_code&) final { const std::size_t length = b.size(); switch (length) { case 1: sink_.push_back(jsoncons::msgpack::msgpack_type::fixext1_type); sink_.push_back(static_cast(ext_tag)); break; case 2: sink_.push_back(jsoncons::msgpack::msgpack_type::fixext2_type); sink_.push_back(static_cast(ext_tag)); break; case 4: sink_.push_back(jsoncons::msgpack::msgpack_type::fixext4_type); sink_.push_back(static_cast(ext_tag)); break; case 8: sink_.push_back(jsoncons::msgpack::msgpack_type::fixext8_type); sink_.push_back(static_cast(ext_tag)); break; case 16: sink_.push_back(jsoncons::msgpack::msgpack_type::fixext16_type); sink_.push_back(static_cast(ext_tag)); break; default: if (length <= (std::numeric_limits::max)()) { sink_.push_back(jsoncons::msgpack::msgpack_type::ext8_type); sink_.push_back(static_cast(length)); sink_.push_back(static_cast(ext_tag)); } else if (length <= (std::numeric_limits::max)()) { sink_.push_back(jsoncons::msgpack::msgpack_type::ext16_type); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); sink_.push_back(static_cast(ext_tag)); } else if (length <= (std::numeric_limits::max)()) { sink_.push_back(jsoncons::msgpack::msgpack_type::ext32_type); binary::native_to_big(static_cast(length),std::back_inserter(sink_)); sink_.push_back(static_cast(ext_tag)); } break; } for (auto c : b) { sink_.push_back(c); } end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_double(double val, semantic_tag, const ser_context&, std::error_code&) final { float valf = (float)val; if ((double)valf == val) { // float 32 sink_.push_back(jsoncons::msgpack::msgpack_type::float32_type); binary::native_to_big(valf,std::back_inserter(sink_)); } else { // float 64 sink_.push_back(jsoncons::msgpack::msgpack_type::float64_type); binary::native_to_big(val,std::back_inserter(sink_)); } // write double end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t val, semantic_tag tag, const ser_context&, std::error_code&) final { switch (tag) { case semantic_tag::epoch_second: write_timestamp(val, 0); break; case semantic_tag::epoch_milli: { if (val != 0) { auto dv = std::div(val,millis_in_second); int64_t seconds = dv.quot; int64_t nanoseconds = dv.rem*nanos_in_milli; if (nanoseconds < 0) { nanoseconds = -nanoseconds; } write_timestamp(seconds, nanoseconds); } else { write_timestamp(0, 0); } break; } case semantic_tag::epoch_nano: { if (val != 0) { auto dv = std::div(val,static_cast(nanos_in_second)); int64_t seconds = dv.quot; int64_t nanoseconds = dv.rem; if (nanoseconds < 0) { nanoseconds = -nanoseconds; } write_timestamp(seconds, nanoseconds); } else { write_timestamp(0, 0); } break; } default: { if (val >= 0) { if (val <= 0x7f) { // positive fixnum stores 7-bit positive integer sink_.push_back(static_cast(val)); } else if (val <= (std::numeric_limits::max)()) { // uint 8 stores a 8-bit unsigned integer sink_.push_back(jsoncons::msgpack::msgpack_type::uint8_type); sink_.push_back(static_cast(val)); } else if (val <= (std::numeric_limits::max)()) { // uint 16 stores a 16-bit big-endian unsigned integer sink_.push_back(jsoncons::msgpack::msgpack_type::uint16_type); binary::native_to_big(static_cast(val),std::back_inserter(sink_)); } else if (val <= (std::numeric_limits::max)()) { // uint 32 stores a 32-bit big-endian unsigned integer sink_.push_back(jsoncons::msgpack::msgpack_type::uint32_type); binary::native_to_big(static_cast(val),std::back_inserter(sink_)); } else if (val <= (std::numeric_limits::max)()) { // int 64 stores a 64-bit big-endian signed integer sink_.push_back(jsoncons::msgpack::msgpack_type::uint64_type); binary::native_to_big(static_cast(val),std::back_inserter(sink_)); } } else { if (val >= -32) { // negative fixnum stores 5-bit negative integer binary::native_to_big(static_cast(val), std::back_inserter(sink_)); } else if (val >= (std::numeric_limits::lowest)()) { // int 8 stores a 8-bit signed integer sink_.push_back(jsoncons::msgpack::msgpack_type::int8_type); binary::native_to_big(static_cast(val),std::back_inserter(sink_)); } else if (val >= (std::numeric_limits::lowest)()) { // int 16 stores a 16-bit big-endian signed integer sink_.push_back(jsoncons::msgpack::msgpack_type::int16_type); binary::native_to_big(static_cast(val),std::back_inserter(sink_)); } else if (val >= (std::numeric_limits::lowest)()) { // int 32 stores a 32-bit big-endian signed integer sink_.push_back(jsoncons::msgpack::msgpack_type::int32_type); binary::native_to_big(static_cast(val),std::back_inserter(sink_)); } else if (val >= (std::numeric_limits::lowest)()) { // int 64 stores a 64-bit big-endian signed integer sink_.push_back(jsoncons::msgpack::msgpack_type::int64_type); binary::native_to_big(static_cast(val),std::back_inserter(sink_)); } } } break; } end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t val, semantic_tag tag, const ser_context&, std::error_code&) final { switch (tag) { case semantic_tag::epoch_second: write_timestamp(static_cast(val), 0); break; case semantic_tag::epoch_milli: { if (val != 0) { auto dv = std::div(static_cast(val), static_cast(millis_in_second)); int64_t seconds = dv.quot; int64_t nanoseconds = dv.rem*nanos_in_milli; if (nanoseconds < 0) { nanoseconds = -nanoseconds; } write_timestamp(seconds, nanoseconds); } else { write_timestamp(0, 0); } break; } case semantic_tag::epoch_nano: { if (val != 0) { auto dv = std::div(static_cast(val), static_cast(nanos_in_second)); int64_t seconds = dv.quot; int64_t nanoseconds = dv.rem; if (nanoseconds < 0) { nanoseconds = -nanoseconds; } write_timestamp(seconds, nanoseconds); } else { write_timestamp(0, 0); } break; } default: { if (val <= static_cast((std::numeric_limits::max)())) { // positive fixnum stores 7-bit positive integer sink_.push_back(static_cast(val)); } else if (val <= (std::numeric_limits::max)()) { // uint 8 stores a 8-bit unsigned integer sink_.push_back(jsoncons::msgpack::msgpack_type::uint8_type); sink_.push_back(static_cast(val)); } else if (val <= (std::numeric_limits::max)()) { // uint 16 stores a 16-bit big-endian unsigned integer sink_.push_back(jsoncons::msgpack::msgpack_type::uint16_type); binary::native_to_big(static_cast(val),std::back_inserter(sink_)); } else if (val <= (std::numeric_limits::max)()) { // uint 32 stores a 32-bit big-endian unsigned integer sink_.push_back(jsoncons::msgpack::msgpack_type::uint32_type); binary::native_to_big(static_cast(val),std::back_inserter(sink_)); } else if (val <= (std::numeric_limits::max)()) { // uint 64 stores a 64-bit big-endian unsigned integer sink_.push_back(jsoncons::msgpack::msgpack_type::uint64_type); binary::native_to_big(static_cast(val),std::back_inserter(sink_)); } break; } } end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool val, semantic_tag, const ser_context&, std::error_code&) final { // true and false sink_.push_back(static_cast(val ? jsoncons::msgpack::msgpack_type::true_type : jsoncons::msgpack::msgpack_type::false_type)); end_value(); JSONCONS_VISITOR_RETURN; } void end_value() { if (!stack_.empty()) { ++stack_.back().index_; } } }; using msgpack_stream_encoder = basic_msgpack_encoder; using msgpack_bytes_encoder = basic_msgpack_encoder>>; } // namespace msgpack } // namespace jsoncons #endif // JSONCONS_EXT_MSGPACK_MSGPACK_ENCODER_HPP jsoncons-1.3.2/include/jsoncons_ext/msgpack/msgpack_error.hpp000066400000000000000000000056051477700171100245170ustar00rootroot00000000000000/// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_MSGPACK_MSGPACK_ERROR_HPP #define JSONCONS_EXT_MSGPACK_MSGPACK_ERROR_HPP #include #include #include namespace jsoncons { namespace msgpack { enum class msgpack_errc { success = 0, unexpected_eof = 1, source_error, invalid_utf8_text_string, array_length_required, object_length_required, too_many_items, too_few_items, max_nesting_depth_exceeded, length_is_negative, invalid_timestamp, unknown_type }; class msgpack_error_category_impl : public std::error_category { public: const char* name() const noexcept override { return "jsoncons/msgpack"; } std::string message(int ev) const override { switch (static_cast(ev)) { case msgpack_errc::unexpected_eof: return "Unexpected end of file"; case msgpack_errc::source_error: return "Source error"; case msgpack_errc::invalid_utf8_text_string: return "Illegal UTF-8 encoding in text string"; case msgpack_errc::array_length_required: return "MessagePack encoder requires array length"; case msgpack_errc::object_length_required: return "MessagePack encoder requires object length"; case msgpack_errc::too_many_items: return "Too many items were added to a MessagePack object or array"; case msgpack_errc::too_few_items: return "Too few items were added to a MessagePack object or array"; case msgpack_errc::max_nesting_depth_exceeded: return "Data item nesting exceeds limit in options"; case msgpack_errc::length_is_negative: return "Request for the length of an array, map or string returned a negative result"; case msgpack_errc::invalid_timestamp: return "Invalid timestamp"; case msgpack_errc::unknown_type: return "An unknown type was found in the stream"; default: return "Unknown MessagePack parser error"; } } }; inline const std::error_category& msgpack_error_category() { static msgpack_error_category_impl instance; return instance; } inline std::error_code make_error_code(msgpack_errc e) { return std::error_code(static_cast(e),msgpack_error_category()); } } // namespace msgpack } // namespace jsoncons namespace std { template<> struct is_error_code_enum : public true_type { }; } // namespace std #endif // JSONCONS_EXT_MSGPACK_MSGPACK_ERROR_HPP jsoncons-1.3.2/include/jsoncons_ext/msgpack/msgpack_event_reader.hpp000066400000000000000000000174411477700171100260320ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_MSGPACK_MSGPACK_EVENT_READER_HPP #define JSONCONS_EXT_MSGPACK_MSGPACK_EVENT_READER_HPP #include #include #include // std::allocator #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace msgpack { template > class msgpack_event_reader : public basic_staj_event_reader, private virtual ser_context { public: using source_type = Source; using char_type = char; using allocator_type = Allocator; private: basic_msgpack_parser parser_; basic_item_event_receiver cursor_visitor_; bool eof_{false}; public: using string_view_type = string_view; template msgpack_event_reader(Sourceable&& source, const msgpack_decode_options& options = msgpack_decode_options(), const Allocator& alloc = Allocator()) : parser_(std::forward(source), options, alloc) { parser_.cursor_mode(true); if (!done()) { next(); } } // Noncopyable and nonmoveable msgpack_event_reader(const msgpack_event_reader&) = delete; msgpack_event_reader(msgpack_event_reader&&) = delete; // Constructors that set parse error codes template msgpack_event_reader(Sourceable&& source, std::error_code& ec) : msgpack_event_reader(std::allocator_arg, Allocator(), std::forward(source), msgpack_decode_options(), ec) { } template msgpack_event_reader(Sourceable&& source, const msgpack_decode_options& options, std::error_code& ec) : msgpack_event_reader(std::allocator_arg, Allocator(), std::forward(source), options, ec) { } template msgpack_event_reader(std::allocator_arg_t, const Allocator& alloc, Sourceable&& source, const msgpack_decode_options& options, std::error_code& ec) : parser_(std::forward(source), options, alloc), eof_(false) { parser_.cursor_mode(true); if (!done()) { next(ec); } } ~msgpack_event_reader() = default; msgpack_event_reader& operator=(const msgpack_event_reader&) = delete; msgpack_event_reader& operator=(msgpack_event_reader&&) = delete; void reset() { parser_.reset(); cursor_visitor_.reset(); eof_ = false; if (!done()) { next(); } } template void reset(Sourceable&& source) { parser_.reset(std::forward(source)); cursor_visitor_.reset(); eof_ = false; if (!done()) { next(); } } void reset(std::error_code& ec) { parser_.reset(); cursor_visitor_.reset(); eof_ = false; if (!done()) { next(ec); } } template void reset(Sourceable&& source, std::error_code& ec) { parser_.reset(std::forward(source)); cursor_visitor_.reset(); eof_ = false; if (!done()) { next(ec); } } bool done() const override { return parser_.done(); } const basic_staj_event& current() const override { return cursor_visitor_.event(); } void read_to(basic_item_event_visitor& visitor) override { std::error_code ec; read_to(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); } } void read_to(basic_item_event_visitor& visitor, std::error_code& ec) override { if (is_begin_container(current().event_type())) { parser_.cursor_mode(false); parser_.mark_level(parser_.level()); cursor_visitor_.dump(visitor, *this, ec); if (JSONCONS_UNLIKELY(ec)) { return; } read_next(visitor, ec); parser_.cursor_mode(true); parser_.mark_level(0); if (current().event_type() == staj_event_type::begin_object) { cursor_visitor_.end_object(*this); } else { cursor_visitor_.end_array(*this); } } else { cursor_visitor_.dump(visitor, *this, ec); } } void next() override { std::error_code ec; next(ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); } } void next(std::error_code& ec) override { read_next(ec); } const ser_context& context() const override { return *this; } bool eof() const { return eof_; } std::size_t line() const override { return parser_.line(); } std::size_t column() const override { return parser_.column(); } friend staj2_filter_view operator|(msgpack_event_reader& cursor, std::function pred) { return staj2_filter_view(cursor, pred); } private: void read_next(std::error_code& ec) { if (cursor_visitor_.in_available()) { cursor_visitor_.send_available(ec); } else { parser_.restart(); while (!parser_.stopped()) { parser_.parse(cursor_visitor_, ec); if (JSONCONS_UNLIKELY(ec)) {return;} } } } void read_next(basic_item_event_visitor& visitor, std::error_code& ec) { { parser_.restart(); while (!parser_.stopped()) { parser_.parse(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} } } } }; } // namespace msgpack } // namespace jsoncons #endif // JSONCONS_EXT_MSGPACK_MSGPACK_EVENT_READER_HPP jsoncons-1.3.2/include/jsoncons_ext/msgpack/msgpack_options.hpp000066400000000000000000000033251477700171100250560ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_MSGPACK_MSGPACK_OPTIONS_HPP #define JSONCONS_EXT_MSGPACK_MSGPACK_OPTIONS_HPP #include namespace jsoncons { namespace msgpack { class msgpack_options; class msgpack_options_common { friend class msgpack_options; int max_nesting_depth_; protected: virtual ~msgpack_options_common() = default; msgpack_options_common() : max_nesting_depth_(1024) { } msgpack_options_common(const msgpack_options_common&) = default; msgpack_options_common& operator=(const msgpack_options_common&) = default; msgpack_options_common(msgpack_options_common&&) = default; msgpack_options_common& operator=(msgpack_options_common&&) = default; public: int max_nesting_depth() const { return max_nesting_depth_; } }; class msgpack_decode_options : public virtual msgpack_options_common { friend class msgpack_options; public: msgpack_decode_options() { } }; class msgpack_encode_options : public virtual msgpack_options_common { friend class msgpack_options; public: msgpack_encode_options() { } }; class msgpack_options final : public msgpack_decode_options, public msgpack_encode_options { public: using msgpack_options_common::max_nesting_depth; msgpack_options& max_nesting_depth(int value) { this->max_nesting_depth_ = value; return *this; } }; } // namespace msgpack } // namespace jsoncons #endif // JSONCONS_EXT_MSGPACK_MSGPACK_OPTIONS_HPP jsoncons-1.3.2/include/jsoncons_ext/msgpack/msgpack_parser.hpp000066400000000000000000000712301477700171100246570ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_MSGPACK_MSGPACK_PARSER_HPP #define JSONCONS_EXT_MSGPACK_MSGPACK_PARSER_HPP #include #include #include #include #include #include // std::move #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace msgpack { enum class parse_mode {root,accept,array,map_key,map_value}; struct parse_state { parse_mode mode; std::size_t length{0}; std::size_t index{0}; parse_state(parse_mode mode, std::size_t length) noexcept : mode(mode), length(length) { } parse_state(const parse_state&) = default; parse_state(parse_state&&) = default; ~parse_state() = default; }; template > class basic_msgpack_parser : public ser_context { using char_type = char; using char_traits_type = std::char_traits; using temp_allocator_type = Allocator; using char_allocator_type = typename std::allocator_traits:: template rebind_alloc; using byte_allocator_type = typename std::allocator_traits:: template rebind_alloc; using int64_allocator_type = typename std::allocator_traits:: template rebind_alloc; using parse_state_allocator_type = typename std::allocator_traits:: template rebind_alloc; static constexpr int64_t nanos_in_second = 1000000000; bool more_{true}; bool done_{false}; int nesting_depth_{0}; bool cursor_mode_{false}; int mark_level_{0}; Source source_; msgpack_decode_options options_; std::basic_string,char_allocator_type> text_buffer_; std::vector bytes_buffer_; std::vector state_stack_; public: template basic_msgpack_parser(Sourceable&& source, const msgpack_decode_options& options = msgpack_decode_options(), const Allocator& alloc = Allocator()) : source_(std::forward(source)), options_(options), text_buffer_(alloc), bytes_buffer_(alloc), state_stack_(alloc) { state_stack_.emplace_back(parse_mode::root,0); } void restart() { more_ = true; } void reset() { more_ = true; done_ = false; text_buffer_.clear(); bytes_buffer_.clear(); state_stack_.clear(); state_stack_.emplace_back(parse_mode::root,0); nesting_depth_ = 0; } template void reset(Sourceable&& source) { source_ = std::forward(source); reset(); } void cursor_mode(bool value) { cursor_mode_ = value; } int level() const { return static_cast(state_stack_.size()); } int mark_level() const { return mark_level_; } void mark_level(int value) { mark_level_ = value; } bool done() const { return done_; } bool stopped() const { return !more_; } std::size_t line() const override { return 0; } std::size_t column() const override { return source_.position(); } void parse(item_event_visitor& visitor, std::error_code& ec) { while (!done_ && more_) { switch (state_stack_.back().mode) { case parse_mode::array: { if (state_stack_.back().index < state_stack_.back().length) { ++state_stack_.back().index; read_item(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { return; } } else { end_array(visitor, ec); } break; } case parse_mode::map_key: { if (state_stack_.back().index < state_stack_.back().length) { ++state_stack_.back().index; state_stack_.back().mode = parse_mode::map_value; read_item(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { return; } } else { end_object(visitor, ec); } break; } case parse_mode::map_value: { state_stack_.back().mode = parse_mode::map_key; read_item(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { return; } break; } case parse_mode::root: { state_stack_.back().mode = parse_mode::accept; read_item(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { return; } break; } case parse_mode::accept: { JSONCONS_ASSERT(state_stack_.size() == 1); state_stack_.clear(); more_ = false; done_ = true; visitor.flush(); break; } } } } private: void read_item(item_event_visitor& visitor, std::error_code& ec) { if (source_.is_error()) { ec = msgpack_errc::source_error; more_ = false; return; } uint8_t type; if (source_.read(&type, 1) == 0) { ec = msgpack_errc::unexpected_eof; more_ = false; return; } if (type <= 0xbf) { if (type <= 0x7f) { // positive fixint visitor.uint64_value(type, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else if (type <= 0x8f) { begin_object(visitor,type,ec); // fixmap } else if (type <= 0x9f) { begin_array(visitor,type,ec); // fixarray } else { // fixstr const size_t len = type & 0x1f; text_buffer_.clear(); if (source_reader::read(source_,text_buffer_,len) != static_cast(len)) { ec = msgpack_errc::unexpected_eof; more_ = false; return; } auto result = unicode_traits::validate(text_buffer_.data(),text_buffer_.size()); if (result.ec != unicode_traits::conv_errc()) { ec = msgpack_errc::invalid_utf8_text_string; more_ = false; return; } visitor.string_value(jsoncons::basic_string_view(text_buffer_.data(),text_buffer_.length()), semantic_tag::none, *this, ec); more_ = !cursor_mode_; } } else if (type >= 0xe0) { // negative fixint visitor.int64_value(static_cast(type), semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else { switch (type) { case jsoncons::msgpack::msgpack_type::nil_type: { visitor.null_value(semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::msgpack::msgpack_type::true_type: { visitor.bool_value(true, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::msgpack::msgpack_type::false_type: { visitor.bool_value(false, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::msgpack::msgpack_type::float32_type: { uint8_t buf[sizeof(float)]; if (source_.read(buf, sizeof(float)) != sizeof(float)) { ec = msgpack_errc::unexpected_eof; more_ = false; return; } float val = binary::big_to_native(buf, sizeof(buf)); visitor.double_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::msgpack::msgpack_type::float64_type: { uint8_t buf[sizeof(double)]; if (source_.read(buf, sizeof(double)) != sizeof(double)) { ec = msgpack_errc::unexpected_eof; more_ = false; return; } double val = binary::big_to_native(buf, sizeof(buf)); visitor.double_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::msgpack::msgpack_type::uint8_type: { uint8_t b; if (source_.read(&b, 1) == 0) { ec = msgpack_errc::unexpected_eof; more_ = false; return; } visitor.uint64_value(b, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::msgpack::msgpack_type::uint16_type: { uint8_t buf[sizeof(uint16_t)]; if (source_.read(buf, sizeof(uint16_t)) !=sizeof(uint16_t)) { ec = msgpack_errc::unexpected_eof; more_ = false; return; } uint16_t val = binary::big_to_native(buf, sizeof(buf)); visitor.uint64_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::msgpack::msgpack_type::uint32_type: { uint8_t buf[sizeof(uint32_t)]; if (source_.read(buf, sizeof(uint32_t)) != sizeof(uint32_t)) { ec = msgpack_errc::unexpected_eof; more_ = false; return; } uint32_t val = binary::big_to_native(buf, sizeof(buf)); visitor.uint64_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::msgpack::msgpack_type::uint64_type: { uint8_t buf[sizeof(uint64_t)]; if (source_.read(buf, sizeof(uint64_t)) != sizeof(uint64_t)) { ec = msgpack_errc::unexpected_eof; more_ = false; return; } uint64_t val = binary::big_to_native(buf, sizeof(buf)); visitor.uint64_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::msgpack::msgpack_type::int8_type: { uint8_t buf[sizeof(int8_t)]; if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t)) { ec = msgpack_errc::unexpected_eof; more_ = false; return; } int8_t val = binary::big_to_native(buf, sizeof(buf)); visitor.int64_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::msgpack::msgpack_type::int16_type: { uint8_t buf[sizeof(int16_t)]; if (source_.read(buf, sizeof(int16_t)) != sizeof(int16_t)) { ec = msgpack_errc::unexpected_eof; more_ = false; return; } int16_t val = binary::big_to_native(buf, sizeof(buf)); visitor.int64_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::msgpack::msgpack_type::int32_type: { uint8_t buf[sizeof(int32_t)]; if (source_.read(buf, sizeof(int32_t)) != sizeof(int32_t)) { ec = msgpack_errc::unexpected_eof; more_ = false; return; } int32_t val = binary::big_to_native(buf, sizeof(buf)); visitor.int64_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::msgpack::msgpack_type::int64_type: { uint8_t buf[sizeof(int64_t)]; if (source_.read(buf, sizeof(int64_t)) != sizeof(int64_t)) { ec = msgpack_errc::unexpected_eof; more_ = false; return; } int64_t val = binary::big_to_native(buf, sizeof(buf)); visitor.int64_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::msgpack::msgpack_type::str8_type: case jsoncons::msgpack::msgpack_type::str16_type: case jsoncons::msgpack::msgpack_type::str32_type: { std::size_t len = get_size(type, ec); if (!more_) { return; } text_buffer_.clear(); if (source_reader::read(source_,text_buffer_,len) != static_cast(len)) { ec = msgpack_errc::unexpected_eof; more_ = false; return; } auto result = unicode_traits::validate(text_buffer_.data(),text_buffer_.size()); if (result.ec != unicode_traits::conv_errc()) { ec = msgpack_errc::invalid_utf8_text_string; more_ = false; return; } visitor.string_value(jsoncons::basic_string_view(text_buffer_.data(),text_buffer_.length()), semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::msgpack::msgpack_type::bin8_type: case jsoncons::msgpack::msgpack_type::bin16_type: case jsoncons::msgpack::msgpack_type::bin32_type: { std::size_t len = get_size(type,ec); if (!more_) { return; } bytes_buffer_.clear(); if (source_reader::read(source_,bytes_buffer_,len) != static_cast(len)) { ec = msgpack_errc::unexpected_eof; more_ = false; return; } visitor.byte_string_value(byte_string_view(bytes_buffer_.data(),bytes_buffer_.size()), semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::msgpack::msgpack_type::fixext1_type: case jsoncons::msgpack::msgpack_type::fixext2_type: case jsoncons::msgpack::msgpack_type::fixext4_type: case jsoncons::msgpack::msgpack_type::fixext8_type: case jsoncons::msgpack::msgpack_type::fixext16_type: case jsoncons::msgpack::msgpack_type::ext8_type: case jsoncons::msgpack::msgpack_type::ext16_type: case jsoncons::msgpack::msgpack_type::ext32_type: { std::size_t len = get_size(type,ec); if (!more_) { return; } // type uint8_t buf[sizeof(int8_t)]; if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t)) { ec = msgpack_errc::unexpected_eof; more_ = false; return; } int8_t ext_type = binary::big_to_native(buf, sizeof(buf)); bool is_timestamp = false; if (ext_type == -1) { is_timestamp = true;; } // payload if (is_timestamp && len == 4) { uint8_t buf32[sizeof(uint32_t)]; if (source_.read(buf32, sizeof(uint32_t)) != sizeof(uint32_t)) { ec = msgpack_errc::unexpected_eof; more_ = false; return; } uint32_t val = binary::big_to_native(buf32, sizeof(buf32)); visitor.uint64_value(val, semantic_tag::epoch_second, *this, ec); more_ = !cursor_mode_; } else if (is_timestamp && len == 8) { uint8_t buf64[sizeof(uint64_t)]; if (source_.read(buf64, sizeof(uint64_t)) != sizeof(uint64_t)) { ec = msgpack_errc::unexpected_eof; more_ = false; return; } uint64_t data64 = binary::big_to_native(buf64, sizeof(buf64)); uint64_t sec = data64 & 0x00000003ffffffffL; uint64_t nsec = data64 >> 34; bigint nano(sec); nano *= uint64_t(nanos_in_second); nano += nsec; text_buffer_.clear(); nano.write_string(text_buffer_); visitor.string_value(text_buffer_, semantic_tag::epoch_nano, *this, ec); more_ = !cursor_mode_; if (!more_) return; } else if (is_timestamp && len == 12) { uint8_t buf1[sizeof(uint32_t)]; if (source_.read(buf1, sizeof(uint32_t)) != sizeof(uint32_t)) { ec = msgpack_errc::unexpected_eof; more_ = false; return; } uint32_t nsec = binary::big_to_native(buf1, sizeof(buf1)); uint8_t buf2[sizeof(int64_t)]; if (source_.read(buf2, sizeof(int64_t)) != sizeof(int64_t)) { ec = msgpack_errc::unexpected_eof; more_ = false; return; } int64_t sec = binary::big_to_native(buf2, sizeof(buf2)); bigint nano(sec); nano *= uint64_t(nanos_in_second); if (nano < 0) { nano -= nsec; } else { nano += nsec; } text_buffer_.clear(); nano.write_string(text_buffer_); visitor.string_value(text_buffer_, semantic_tag::epoch_nano, *this, ec); more_ = !cursor_mode_; if (!more_) return; } else { bytes_buffer_.clear(); if (source_reader::read(source_,bytes_buffer_,len) != static_cast(len)) { ec = msgpack_errc::unexpected_eof; more_ = false; return; } visitor.byte_string_value(byte_string_view(bytes_buffer_.data(),bytes_buffer_.size()), static_cast(ext_type), *this, ec); more_ = !cursor_mode_; } break; } case jsoncons::msgpack::msgpack_type::array16_type: case jsoncons::msgpack::msgpack_type::array32_type: { begin_array(visitor,type,ec); break; } case jsoncons::msgpack::msgpack_type::map16_type : case jsoncons::msgpack::msgpack_type::map32_type : { begin_object(visitor, type, ec); break; } default: { ec = msgpack_errc::unknown_type; more_ = false; return; } } } } void begin_array(item_event_visitor& visitor, uint8_t type, std::error_code& ec) { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = msgpack_errc::max_nesting_depth_exceeded; more_ = false; return; } std::size_t length = get_size(type, ec); if (!more_) { return; } state_stack_.emplace_back(parse_mode::array,length); visitor.begin_array(length, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } void end_array(item_event_visitor& visitor, std::error_code& ec) { --nesting_depth_; visitor.end_array(*this, ec); more_ = !cursor_mode_; state_stack_.pop_back(); } void begin_object(item_event_visitor& visitor, uint8_t type, std::error_code& ec) { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = msgpack_errc::max_nesting_depth_exceeded; more_ = false; return; } std::size_t length = get_size(type, ec); if (!more_) { return; } state_stack_.emplace_back(parse_mode::map_key,length); visitor.begin_object(length, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } void end_object(item_event_visitor& visitor, std::error_code& ec) { --nesting_depth_; visitor.end_object(*this, ec); more_ = !cursor_mode_; state_stack_.pop_back(); } std::size_t get_size(uint8_t type, std::error_code& ec) { switch (type) { case jsoncons::msgpack::msgpack_type::str8_type: case jsoncons::msgpack::msgpack_type::bin8_type: case jsoncons::msgpack::msgpack_type::ext8_type: { uint8_t buf[sizeof(int8_t)]; if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t)) { ec = msgpack_errc::unexpected_eof; more_ = false; return 0; } uint8_t len = binary::big_to_native(buf, sizeof(buf)); return static_cast(len); } case jsoncons::msgpack::msgpack_type::str16_type: case jsoncons::msgpack::msgpack_type::bin16_type: case jsoncons::msgpack::msgpack_type::ext16_type: case jsoncons::msgpack::msgpack_type::array16_type: case jsoncons::msgpack::msgpack_type::map16_type: { uint8_t buf[sizeof(int16_t)]; if (source_.read(buf, sizeof(int16_t)) != sizeof(int16_t)) { ec = msgpack_errc::unexpected_eof; more_ = false; return 0; } uint16_t len = binary::big_to_native(buf, sizeof(buf)); return static_cast(len); } case jsoncons::msgpack::msgpack_type::str32_type: case jsoncons::msgpack::msgpack_type::bin32_type: case jsoncons::msgpack::msgpack_type::ext32_type: case jsoncons::msgpack::msgpack_type::array32_type: case jsoncons::msgpack::msgpack_type::map32_type : { uint8_t buf[sizeof(int32_t)]; if (source_.read(buf, sizeof(int32_t)) != sizeof(int32_t)) { ec = msgpack_errc::unexpected_eof; more_ = false; return 0; } uint32_t len = binary::big_to_native(buf, sizeof(buf)); return static_cast(len); } case jsoncons::msgpack::msgpack_type::fixext1_type: return 1; case jsoncons::msgpack::msgpack_type::fixext2_type: return 2; case jsoncons::msgpack::msgpack_type::fixext4_type: return 4; case jsoncons::msgpack::msgpack_type::fixext8_type: return 8; case jsoncons::msgpack::msgpack_type::fixext16_type: return 16; default: if ((type > 0x8f && type <= 0x9f) // fixarray || (type > 0x7f && type <= 0x8f) // fixmap ) { return type & 0x0f; } else { ec = msgpack_errc::unknown_type; more_ = false; return 0; } break; } } }; } // namespace msgpack } // namespace jsoncons #endif // JSONCONS_EXT_MSGPACK_MSGPACK_PARSER_HPP jsoncons-1.3.2/include/jsoncons_ext/msgpack/msgpack_reader.hpp000066400000000000000000000064501477700171100246270ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_MSGPACK_MSGPACK_READER_HPP #define JSONCONS_EXT_MSGPACK_MSGPACK_READER_HPP #include #include #include #include // std::move #include #include #include #include #include #include namespace jsoncons { namespace msgpack { template > class basic_msgpack_reader { using char_type = char; basic_msgpack_parser parser_; basic_item_event_visitor_to_json_visitor adaptor_; item_event_visitor& visitor_; public: template basic_msgpack_reader(Sourceable&& source, json_visitor& visitor, const Allocator& alloc) : basic_msgpack_reader(std::forward(source), visitor, msgpack_decode_options(), alloc) { } template basic_msgpack_reader(Sourceable&& source, json_visitor& visitor, const msgpack_decode_options& options = msgpack_decode_options(), const Allocator& alloc=Allocator()) : parser_(std::forward(source), options, alloc), adaptor_(visitor, alloc), visitor_(adaptor_) { } template basic_msgpack_reader(Sourceable&& source, item_event_visitor& visitor, const Allocator& alloc) : basic_msgpack_reader(std::forward(source), visitor, msgpack_decode_options(), alloc) { } template basic_msgpack_reader(Sourceable&& source, item_event_visitor& visitor, const msgpack_decode_options& options = msgpack_decode_options(), const Allocator& alloc=Allocator()) : parser_(std::forward(source), options, alloc), visitor_(visitor) { } void read() { std::error_code ec; read(ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,line(),column())); } } void read(std::error_code& ec) { parser_.reset(); parser_.parse(visitor_, ec); if (JSONCONS_UNLIKELY(ec)) { return; } } std::size_t line() const { return parser_.line(); } std::size_t column() const { return parser_.column(); } }; using msgpack_stream_reader = basic_msgpack_reader; using msgpack_bytes_reader = basic_msgpack_reader; } // namespace msgpack } // namespace jsoncons #endif // JSONCONS_EXT_MSGPACK_MSGPACK_READER_HPP jsoncons-1.3.2/include/jsoncons_ext/msgpack/msgpack_type.hpp000066400000000000000000000040721477700171100243440ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_MSGPACK_MSGPACK_TYPE_HPP #define JSONCONS_EXT_MSGPACK_MSGPACK_TYPE_HPP #include namespace jsoncons { namespace msgpack { namespace msgpack_type { const uint8_t positive_fixint_base_type = 0x00; const uint8_t nil_type = 0xc0; const uint8_t false_type = 0xc2; const uint8_t true_type = 0xc3; const uint8_t float32_type = 0xca; const uint8_t float64_type = 0xcb; const uint8_t uint8_type = 0xcc; const uint8_t uint16_type = 0xcd; const uint8_t uint32_type = 0xce; const uint8_t uint64_type = 0xcf; const uint8_t int8_type = 0xd0; const uint8_t int16_type = 0xd1; const uint8_t int32_type = 0xd2; const uint8_t int64_type = 0xd3; const uint8_t fixmap_base_type = 0x80; const uint8_t fixarray_base_type = 0x90; const uint8_t fixstr_base_type = 0xa0; const uint8_t str8_type = 0xd9; const uint8_t str16_type = 0xda; const uint8_t str32_type = 0xdb; const uint8_t bin8_type = 0xc4; // 0xC4 const uint8_t bin16_type = 0xc5; const uint8_t bin32_type = 0xc6; const uint8_t fixext1_type = 0xd4; const uint8_t fixext2_type = 0xd5; const uint8_t fixext4_type = 0xd6; const uint8_t fixext8_type = 0xd7; const uint8_t fixext16_type = 0xd8; const uint8_t ext8_type = 0xc7; // 0xC4 const uint8_t ext16_type = 0xc8; const uint8_t ext32_type = 0xc9; const uint8_t array16_type = 0xdc; const uint8_t array32_type = 0xdd; const uint8_t map16_type = 0xde; const uint8_t map32_type = 0xdf; const uint8_t negative_fixint_base_type = 0xe0; } } // namespace msgpack } // namespace jsoncons #endif // JSONCONS_EXT_MSGPACK_MSGPACK_TYPE_HPP jsoncons-1.3.2/include/jsoncons_ext/ubjson/000077500000000000000000000000001477700171100210155ustar00rootroot00000000000000jsoncons-1.3.2/include/jsoncons_ext/ubjson/decode_ubjson.hpp000066400000000000000000000213521477700171100243340ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_UBJSON_DECODE_UBJSON_HPP #define JSONCONS_EXT_UBJSON_DECODE_UBJSON_HPP #include // std::basic_istream #include // std::enable_if #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace ubjson { template typename std::enable_if::value && extension_traits::is_byte_sequence::value,T>::type decode_ubjson(const Source& v, const ubjson_decode_options& options = ubjson_decode_options()) { jsoncons::json_decoder decoder; auto adaptor = make_json_visitor_adaptor(decoder); basic_ubjson_reader reader(v, adaptor, options); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value && extension_traits::is_byte_sequence::value,T>::type decode_ubjson(const Source& v, const ubjson_decode_options& options = ubjson_decode_options()) { basic_ubjson_cursor cursor(v, options); json_decoder> decoder{}; std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } template typename std::enable_if::value,T>::type decode_ubjson(std::istream& is, const ubjson_decode_options& options = ubjson_decode_options()) { jsoncons::json_decoder decoder; auto adaptor = make_json_visitor_adaptor(decoder); ubjson_stream_reader reader(is, adaptor, options); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value,T>::type decode_ubjson(std::istream& is, const ubjson_decode_options& options = ubjson_decode_options()) { basic_ubjson_cursor cursor(is, options); json_decoder> decoder{}; std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } template typename std::enable_if::value,T>::type decode_ubjson(InputIt first, InputIt last, const ubjson_decode_options& options = ubjson_decode_options()) { jsoncons::json_decoder decoder; auto adaptor = make_json_visitor_adaptor(decoder); basic_ubjson_reader> reader(binary_iterator_source(first, last), adaptor, options); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value,T>::type decode_ubjson(InputIt first, InputIt last, const ubjson_decode_options& options = ubjson_decode_options()) { basic_ubjson_cursor> cursor(binary_iterator_source(first, last), options); json_decoder> decoder{}; std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } // With leading allocator_set parameter template typename std::enable_if::value && extension_traits::is_byte_sequence::value,T>::type decode_ubjson(const allocator_set& alloc_set, const Source& v, const ubjson_decode_options& options = ubjson_decode_options()) { json_decoder decoder(alloc_set.get_allocator(), alloc_set.get_temp_allocator()); auto adaptor = make_json_visitor_adaptor(decoder); basic_ubjson_reader reader(v, adaptor, options, alloc_set.get_temp_allocator()); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value && extension_traits::is_byte_sequence::value,T>::type decode_ubjson(const allocator_set& alloc_set, const Source& v, const ubjson_decode_options& options = ubjson_decode_options()) { basic_ubjson_cursor cursor(v, options, alloc_set.get_temp_allocator()); json_decoder,TempAllocator> decoder(alloc_set.get_temp_allocator(), alloc_set.get_temp_allocator()); std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } template typename std::enable_if::value,T>::type decode_ubjson(const allocator_set& alloc_set, std::istream& is, const ubjson_decode_options& options = ubjson_decode_options()) { json_decoder decoder(alloc_set.get_allocator(), alloc_set.get_temp_allocator()); auto adaptor = make_json_visitor_adaptor(decoder); basic_ubjson_reader reader(is, adaptor, options, alloc_set.get_temp_allocator()); reader.read(); if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, reader.line(), reader.column())); } return decoder.get_result(); } template typename std::enable_if::value,T>::type decode_ubjson(const allocator_set& alloc_set, std::istream& is, const ubjson_decode_options& options = ubjson_decode_options()) { basic_ubjson_cursor cursor(is, options, alloc_set.get_temp_allocator()); json_decoder,TempAllocator> decoder(alloc_set.get_temp_allocator(), alloc_set.get_temp_allocator()); std::error_code ec; T val = decode_traits::decode(cursor, decoder, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); } return val; } } // namespace ubjson } // namespace jsoncons #endif // JSONCONS_EXT_UBJSON_DECODE_UBJSON_HPP jsoncons-1.3.2/include/jsoncons_ext/ubjson/encode_ubjson.hpp000066400000000000000000000141211477700171100243420ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_UBJSON_ENCODE_UBJSON_HPP #define JSONCONS_EXT_UBJSON_ENCODE_UBJSON_HPP #include // std::basic_ostream #include // std::enable_if #include #include #include #include #include #include namespace jsoncons { namespace ubjson { template typename std::enable_if::value && extension_traits::is_back_insertable_byte_container::value,void>::type encode_ubjson(const T& j, ByteContainer& cont, const ubjson_encode_options& options = ubjson_encode_options()) { using char_type = typename T::char_type; basic_ubjson_encoder> encoder(cont, options); auto adaptor = make_json_visitor_adaptor>(encoder); j.dump(adaptor); } template typename std::enable_if::value && extension_traits::is_back_insertable_byte_container::value,void>::type encode_ubjson(const T& val, ByteContainer& cont, const ubjson_encode_options& options = ubjson_encode_options()) { basic_ubjson_encoder> encoder(cont, options); std::error_code ec; encode_traits::encode(val, encoder, json(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } template typename std::enable_if::value,void>::type encode_ubjson(const T& j, std::ostream& os, const ubjson_encode_options& options = ubjson_encode_options()) { using char_type = typename T::char_type; ubjson_stream_encoder encoder(os, options); auto adaptor = make_json_visitor_adaptor>(encoder); j.dump(adaptor); } template typename std::enable_if::value,void>::type encode_ubjson(const T& val, std::ostream& os, const ubjson_encode_options& options = ubjson_encode_options()) { ubjson_stream_encoder encoder(os, options); std::error_code ec; encode_traits::encode(val, encoder, json(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } // with temp_allocator_arg_t template typename std::enable_if::value && extension_traits::is_back_insertable_byte_container::value,void>::type encode_ubjson(const allocator_set& alloc_set,const T& j, ByteContainer& cont, const ubjson_encode_options& options = ubjson_encode_options()) { using char_type = typename T::char_type; basic_ubjson_encoder,TempAllocator> encoder(cont, options, alloc_set.get_temp_allocator()); auto adaptor = make_json_visitor_adaptor>(encoder); j.dump(adaptor); } template typename std::enable_if::value && extension_traits::is_back_insertable_byte_container::value,void>::type encode_ubjson(const allocator_set& alloc_set,const T& val, ByteContainer& cont, const ubjson_encode_options& options = ubjson_encode_options()) { basic_ubjson_encoder,TempAllocator> encoder(cont, options, alloc_set.get_temp_allocator()); std::error_code ec; encode_traits::encode(val, encoder, json(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } template typename std::enable_if::value,void>::type encode_ubjson(const allocator_set& alloc_set, const T& j, std::ostream& os, const ubjson_encode_options& options = ubjson_encode_options()) { using char_type = typename T::char_type; basic_ubjson_encoder encoder(os, options, alloc_set.get_temp_allocator()); auto adaptor = make_json_visitor_adaptor>(encoder); j.dump(adaptor); } template typename std::enable_if::value,void>::type encode_ubjson(const allocator_set& alloc_set, const T& val, std::ostream& os, const ubjson_encode_options& options = ubjson_encode_options()) { basic_ubjson_encoder encoder(os, options, alloc_set.get_temp_allocator()); std::error_code ec; encode_traits::encode(val, encoder, json(), ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec)); } } } // namespace ubjson } // namespace jsoncons #endif // JSONCONS_EXT_UBJSON_ENCODE_UBJSON_HPP jsoncons-1.3.2/include/jsoncons_ext/ubjson/ubjson.hpp000066400000000000000000000011521477700171100230250ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_UBJSON_UBJSON_HPP #define JSONCONS_EXT_UBJSON_UBJSON_HPP #include #include #include #include #include #endif // JSONCONS_EXT_UBJSON_UBJSON_HPP jsoncons-1.3.2/include/jsoncons_ext/ubjson/ubjson_cursor.hpp000066400000000000000000000153101477700171100244230ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_UBJSON_UBJSON_CURSOR_HPP #define JSONCONS_EXT_UBJSON_UBJSON_CURSOR_HPP #include #include #include #include // std::allocator #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace ubjson { template > class basic_ubjson_cursor : public basic_staj_cursor, private virtual ser_context { public: using source_type = Source; using char_type = char; using allocator_type = Allocator; private: basic_ubjson_parser parser_; basic_staj_visitor cursor_visitor_; bool eof_{false}; public: using string_view_type = string_view; // Noncopyable and nonmoveable basic_ubjson_cursor(const basic_ubjson_cursor&) = delete; basic_ubjson_cursor(basic_ubjson_cursor&&) = delete; template basic_ubjson_cursor(Sourceable&& source, const ubjson_decode_options& options = ubjson_decode_options(), const Allocator& alloc = Allocator()) : parser_(std::forward(source), options, alloc) { parser_.cursor_mode(true); if (!done()) { next(); } } // Constructors that set parse error codes template basic_ubjson_cursor(Sourceable&& source, std::error_code& ec) : basic_ubjson_cursor(std::allocator_arg, Allocator(), std::forward(source), ubjson_decode_options(), ec) { } template basic_ubjson_cursor(Sourceable&& source, const ubjson_decode_options& options, std::error_code& ec) : basic_ubjson_cursor(std::allocator_arg, Allocator(), std::forward(source), options, ec) { } template basic_ubjson_cursor(std::allocator_arg_t, const Allocator& alloc, Sourceable&& source, const ubjson_decode_options& options, std::error_code& ec) : parser_(std::forward(source), options, alloc), eof_(false) { parser_.cursor_mode(true); if (!done()) { next(ec); } } ~basic_ubjson_cursor() = default; basic_ubjson_cursor& operator=(const basic_ubjson_cursor&) = delete; basic_ubjson_cursor& operator=(basic_ubjson_cursor&&) = delete; void reset() { parser_.reset(); cursor_visitor_.reset(); eof_ = false; if (!done()) { next(); } } template void reset(Sourceable&& source) { parser_.reset(std::forward(source)); cursor_visitor_.reset(); eof_ = false; if (!done()) { next(); } } void reset(std::error_code& ec) { parser_.reset(); cursor_visitor_.reset(); eof_ = false; if (!done()) { next(ec); } } template void reset(Sourceable&& source, std::error_code& ec) { parser_.reset(std::forward(source)); cursor_visitor_.reset(); eof_ = false; if (!done()) { next(ec); } } bool done() const override { return parser_.done(); } const staj_event& current() const override { return cursor_visitor_.event(); } void read_to(basic_json_visitor& visitor) override { std::error_code ec; read_to(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); } } void read_to(basic_json_visitor& visitor, std::error_code& ec) override { if (is_begin_container(current().event_type())) { parser_.cursor_mode(false); parser_.mark_level(parser_.level()); cursor_visitor_.event().send_json_event(visitor, *this, ec); if (JSONCONS_UNLIKELY(ec)) { return; } read_next(visitor, ec); parser_.cursor_mode(true); parser_.mark_level(0); if (current().event_type() == staj_event_type::begin_object) { cursor_visitor_.end_object(*this); } else { cursor_visitor_.end_array(*this); } } else { cursor_visitor_.event().send_json_event(visitor, *this, ec); } } void next() override { std::error_code ec; next(ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); } } void next(std::error_code& ec) override { read_next(ec); } const ser_context& context() const override { return *this; } bool eof() const { return eof_; } std::size_t line() const override { return parser_.line(); } std::size_t column() const override { return parser_.column(); } friend staj_filter_view operator|(basic_ubjson_cursor& cursor, std::function pred) { return staj_filter_view(cursor, pred); } private: void read_next(std::error_code& ec) { parser_.restart(); while (!parser_.stopped()) { parser_.parse(cursor_visitor_, ec); if (JSONCONS_UNLIKELY(ec)) {return;} } } void read_next(basic_json_visitor& visitor, std::error_code& ec) { parser_.restart(); while (!parser_.stopped()) { parser_.parse(visitor, ec); if (JSONCONS_UNLIKELY(ec)) {return;} } } }; using ubjson_stream_cursor = basic_ubjson_cursor; using ubjson_bytes_cursor = basic_ubjson_cursor; } // namespace ubjson } // namespace jsoncons #endif jsoncons-1.3.2/include/jsoncons_ext/ubjson/ubjson_encoder.hpp000066400000000000000000000414421477700171100245320ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_UBJSON_UBJSON_ENCODER_HPP #define JSONCONS_EXT_UBJSON_UBJSON_ENCODER_HPP #include #include #include // std::numeric_limits #include #include #include // std::move #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace ubjson { enum class ubjson_container_type {object, indefinite_length_object, array, indefinite_length_array}; template > class basic_ubjson_encoder final : public basic_json_visitor { enum class decimal_parse_state { start, integer, exp1, exp2, fraction1 }; public: using allocator_type = Allocator; using typename basic_json_visitor::string_view_type; using sink_type = Sink; private: struct stack_item { ubjson_container_type type_; std::size_t length_{0}; std::size_t count_{0}; stack_item(ubjson_container_type type, std::size_t length = 0) noexcept : type_(type), length_(length) { } ~stack_item() = default; std::size_t length() const { return length_; } std::size_t count() const { return count_; } bool is_object() const { return type_ == ubjson_container_type::object || type_ == ubjson_container_type::indefinite_length_object; } bool is_indefinite_length() const { return type_ == ubjson_container_type::indefinite_length_array || type_ == ubjson_container_type::indefinite_length_object; } }; Sink sink_; const ubjson_encode_options options_; allocator_type alloc_; std::vector stack_; int nesting_depth_{0}; public: // Noncopyable and nonmoveable basic_ubjson_encoder(const basic_ubjson_encoder&) = delete; basic_ubjson_encoder(basic_ubjson_encoder&&) = delete; basic_ubjson_encoder(Sink&& sink, const Allocator& alloc = Allocator()) : basic_ubjson_encoder(std::forward(sink), ubjson_encode_options(), alloc) { } explicit basic_ubjson_encoder(Sink&& sink, const ubjson_encode_options& options, const Allocator& alloc = Allocator()) : sink_(std::forward(sink)), options_(options), alloc_(alloc) { } ~basic_ubjson_encoder() noexcept { JSONCONS_TRY { sink_.flush(); } JSONCONS_CATCH(...) { } } basic_ubjson_encoder& operator=(const basic_ubjson_encoder&) = delete; basic_ubjson_encoder& operator=(basic_ubjson_encoder&&) = delete; void reset() { stack_.clear(); nesting_depth_ = 0; } void reset(Sink&& sink) { sink_ = std::move(sink); reset(); } private: // Implementing methods void visit_flush() override { sink_.flush(); } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag, const ser_context&, std::error_code& ec) override { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = ubjson_errc::max_nesting_depth_exceeded; JSONCONS_VISITOR_RETURN; } stack_.emplace_back(ubjson_container_type::indefinite_length_object); sink_.push_back(jsoncons::ubjson::ubjson_type::start_object_marker); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(std::size_t length, semantic_tag, const ser_context&, std::error_code& ec) override { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = ubjson_errc::max_nesting_depth_exceeded; JSONCONS_VISITOR_RETURN; } stack_.emplace_back(ubjson_container_type::object, length); sink_.push_back(jsoncons::ubjson::ubjson_type::start_object_marker); sink_.push_back(jsoncons::ubjson::ubjson_type::count_marker); put_length(length); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context&, std::error_code& ec) override { JSONCONS_ASSERT(!stack_.empty()); --nesting_depth_; if (stack_.back().is_indefinite_length()) { sink_.push_back(jsoncons::ubjson::ubjson_type::end_object_marker); } else { if (stack_.back().count() < stack_.back().length()) { ec = ubjson_errc::too_few_items; JSONCONS_VISITOR_RETURN; } if (stack_.back().count() > stack_.back().length()) { ec = ubjson_errc::too_many_items; JSONCONS_VISITOR_RETURN; } } stack_.pop_back(); end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag, const ser_context&, std::error_code& ec) override { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = ubjson_errc::max_nesting_depth_exceeded; JSONCONS_VISITOR_RETURN; } stack_.emplace_back(ubjson_container_type::indefinite_length_array); sink_.push_back(jsoncons::ubjson::ubjson_type::start_array_marker); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(std::size_t length, semantic_tag, const ser_context&, std::error_code& ec) override { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = ubjson_errc::max_nesting_depth_exceeded; JSONCONS_VISITOR_RETURN; } stack_.emplace_back(ubjson_container_type::array, length); sink_.push_back(jsoncons::ubjson::ubjson_type::start_array_marker); sink_.push_back(jsoncons::ubjson::ubjson_type::count_marker); put_length(length); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context&, std::error_code& ec) override { JSONCONS_ASSERT(!stack_.empty()); --nesting_depth_; if (stack_.back().is_indefinite_length()) { sink_.push_back(jsoncons::ubjson::ubjson_type::end_array_marker); } else { if (stack_.back().count() < stack_.back().length()) { ec = ubjson_errc::too_few_items; JSONCONS_VISITOR_RETURN; } if (stack_.back().count() > stack_.back().length()) { ec = ubjson_errc::too_many_items; JSONCONS_VISITOR_RETURN; } } stack_.pop_back(); end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type& name, const ser_context&, std::error_code& ec) override { auto sink = unicode_traits::validate(name.data(), name.size()); if (sink.ec != unicode_traits::conv_errc()) { ec = ubjson_errc::invalid_utf8_text_string; JSONCONS_VISITOR_RETURN; } put_length(name.length()); for (auto c : name) { sink_.push_back(c); } JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag, const ser_context&, std::error_code&) override { // nil binary::native_to_big(static_cast(jsoncons::ubjson::ubjson_type::null_type), std::back_inserter(sink_)); end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& sv, semantic_tag tag, const ser_context&, std::error_code& ec) override { switch (tag) { case semantic_tag::bigint: case semantic_tag::bigdec: { sink_.push_back(jsoncons::ubjson::ubjson_type::high_precision_number_type); break; } default: { sink_.push_back(jsoncons::ubjson::ubjson_type::string_type); break; } } auto sink = unicode_traits::validate(sv.data(), sv.size()); if (sink.ec != unicode_traits::conv_errc()) { ec = ubjson_errc::invalid_utf8_text_string; JSONCONS_VISITOR_RETURN; } put_length(sv.length()); for (auto c : sv) { sink_.push_back(c); } end_value(); JSONCONS_VISITOR_RETURN; } void put_length(std::size_t length) { if (length <= (std::numeric_limits::max)()) { sink_.push_back(ubjson_type::uint8_type); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } else if (length <= (std::size_t)(std::numeric_limits::max)()) { sink_.push_back(ubjson_type::int16_type); binary::native_to_big(static_cast(length), std::back_inserter(sink_)); } else if (length <= (std::size_t)(std::numeric_limits::max)()) { sink_.push_back(ubjson_type::int32_type); binary::native_to_big(static_cast(length),std::back_inserter(sink_)); } else if (length <= (std::size_t)(std::numeric_limits::max)()) { sink_.push_back(ubjson_type::int64_type); binary::native_to_big(static_cast(length),std::back_inserter(sink_)); } else { JSONCONS_THROW(ser_error(ubjson_errc::too_many_items)); } } JSONCONS_VISITOR_RETURN_TYPE visit_byte_string(const byte_string_view& b, semantic_tag, const ser_context&, std::error_code&) override { const size_t length = b.size(); sink_.push_back(jsoncons::ubjson::ubjson_type::start_array_marker); sink_.push_back(static_cast(jsoncons::ubjson::ubjson_type::type_marker)); sink_.push_back(static_cast(jsoncons::ubjson::ubjson_type::uint8_type)); sink_.push_back(jsoncons::ubjson::ubjson_type::count_marker); put_length(length); for (auto c : b) { sink_.push_back(c); } end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_double(double val, semantic_tag, const ser_context&, std::error_code&) override { float valf = (float)val; if ((double)valf == val) { // float 32 sink_.push_back(static_cast(jsoncons::ubjson::ubjson_type::float32_type)); binary::native_to_big(valf,std::back_inserter(sink_)); } else { // float 64 sink_.push_back(static_cast(jsoncons::ubjson::ubjson_type::float64_type)); binary::native_to_big(val,std::back_inserter(sink_)); } // write double end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t val, semantic_tag, const ser_context&, std::error_code&) override { if (val >= 0) { if (val <= (std::numeric_limits::max)()) { // uint 8 stores a 8-bit unsigned integer sink_.push_back(jsoncons::ubjson::ubjson_type::uint8_type); binary::native_to_big(static_cast(val),std::back_inserter(sink_)); } else if (val <= (std::numeric_limits::max)()) { // uint 16 stores a 16-bit big-endian unsigned integer sink_.push_back(jsoncons::ubjson::ubjson_type::int16_type); binary::native_to_big(static_cast(val),std::back_inserter(sink_)); } else if (val <= (std::numeric_limits::max)()) { // uint 32 stores a 32-bit big-endian unsigned integer sink_.push_back(jsoncons::ubjson::ubjson_type::int32_type); binary::native_to_big(static_cast(val),std::back_inserter(sink_)); } else if (val <= (std::numeric_limits::max)()) { // int 64 stores a 64-bit big-endian signed integer sink_.push_back(jsoncons::ubjson::ubjson_type::int64_type); binary::native_to_big(val,std::back_inserter(sink_)); } else { // big integer } } else { if (val >= (std::numeric_limits::lowest)()) { // int 8 stores a 8-bit signed integer sink_.push_back(jsoncons::ubjson::ubjson_type::int8_type); binary::native_to_big(static_cast(val),std::back_inserter(sink_)); } else if (val >= (std::numeric_limits::lowest)()) { // int 16 stores a 16-bit big-endian signed integer sink_.push_back(jsoncons::ubjson::ubjson_type::int16_type); binary::native_to_big(static_cast(val),std::back_inserter(sink_)); } else if (val >= (std::numeric_limits::lowest)()) { // int 32 stores a 32-bit big-endian signed integer sink_.push_back(jsoncons::ubjson::ubjson_type::int32_type); binary::native_to_big(static_cast(val),std::back_inserter(sink_)); } else if (val >= (std::numeric_limits::lowest)()) { // int 64 stores a 64-bit big-endian signed integer sink_.push_back(jsoncons::ubjson::ubjson_type::int64_type); binary::native_to_big(val,std::back_inserter(sink_)); } } end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t val, semantic_tag, const ser_context&, std::error_code&) override { if (val <= (std::numeric_limits::max)()) { sink_.push_back(jsoncons::ubjson::ubjson_type::uint8_type); binary::native_to_big(static_cast(val),std::back_inserter(sink_)); } else if (val <= static_cast((std::numeric_limits::max)())) { sink_.push_back(jsoncons::ubjson::ubjson_type::int16_type); binary::native_to_big(static_cast(val),std::back_inserter(sink_)); } else if (val <= static_cast((std::numeric_limits::max)())) { sink_.push_back(jsoncons::ubjson::ubjson_type::int32_type); binary::native_to_big(static_cast(val),std::back_inserter(sink_)); } else if (val <= static_cast((std::numeric_limits::max)())) { sink_.push_back(jsoncons::ubjson::ubjson_type::int64_type); binary::native_to_big(static_cast(val),std::back_inserter(sink_)); } end_value(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool val, semantic_tag, const ser_context&, std::error_code&) override { // true and false sink_.push_back(static_cast(val ? jsoncons::ubjson::ubjson_type::true_type : jsoncons::ubjson::ubjson_type::false_type)); end_value(); JSONCONS_VISITOR_RETURN; } void end_value() { if (!stack_.empty()) { ++stack_.back().count_; } } }; using ubjson_stream_encoder = basic_ubjson_encoder; using ubjson_bytes_encoder = basic_ubjson_encoder>>; } // namespace ubjson } // namespace jsoncons #endif // JSONCONS_EXT_UBJSON_UBJSON_ENCODER_HPP jsoncons-1.3.2/include/jsoncons_ext/ubjson/ubjson_error.hpp000066400000000000000000000063741477700171100242510ustar00rootroot00000000000000/// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_UBJSON_UBJSON_ERROR_HPP #define JSONCONS_EXT_UBJSON_UBJSON_ERROR_HPP #include #include #include #include namespace jsoncons { namespace ubjson { enum class ubjson_errc { success = 0, unexpected_eof = 1, source_error, count_required_after_type, length_is_negative, length_must_be_integer, unknown_type, invalid_utf8_text_string, too_many_items, too_few_items, number_too_large, max_nesting_depth_exceeded, key_expected, max_items_exceeded }; class ubjson_error_category_impl : public std::error_category { public: const char* name() const noexcept override { return "jsoncons/ubjson"; } std::string message(int ev) const override { switch (static_cast(ev)) { case ubjson_errc::unexpected_eof: return "Unexpected end of file"; case ubjson_errc::source_error: return "Source error"; case ubjson_errc::count_required_after_type: return "Type is specified for container, but count is not specified"; case ubjson_errc::length_is_negative: return "Request for the length of an array, map or string returned a negative result"; case ubjson_errc::length_must_be_integer: return "Length must be a integer numeric type (int8, uint8, int16, int32, int64)"; case ubjson_errc::unknown_type: return "Unknown type"; case ubjson_errc::invalid_utf8_text_string: return "Illegal UTF-8 encoding in text string"; case ubjson_errc::too_many_items: return "Too many items were added to a UBJSON object or array of known length"; case ubjson_errc::too_few_items: return "Too few items were added to a UBJSON object or array of known length"; case ubjson_errc::number_too_large: return "Number exceeds implementation limits"; case ubjson_errc::max_nesting_depth_exceeded: return "Data item nesting exceeds limit in options"; case ubjson_errc::key_expected: return "Text string key in a map expected"; case ubjson_errc::max_items_exceeded: return "Number of items in UBJSON object or array exceeds limit set in options"; default: return "Unknown UBJSON parser error"; } } }; inline const std::error_category& ubjson_error_category() { static ubjson_error_category_impl instance; return instance; } inline std::error_code make_error_code(ubjson_errc e) { return std::error_code(static_cast(e),ubjson_error_category()); } } // namespace ubjson } // namespace jsoncons namespace std { template<> struct is_error_code_enum : public true_type { }; } // namespace std #endif // JSONCONS_EXT_UBJSON_UBJSON_ERROR_HPP jsoncons-1.3.2/include/jsoncons_ext/ubjson/ubjson_options.hpp000066400000000000000000000037051477700171100246060ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_UBJSON_UBJSON_OPTIONS_HPP #define JSONCONS_EXT_UBJSON_UBJSON_OPTIONS_HPP #include namespace jsoncons { namespace ubjson { class ubjson_options; class ubjson_options_common { friend class ubjson_options; int max_nesting_depth_; protected: virtual ~ubjson_options_common() = default; ubjson_options_common() : max_nesting_depth_(1024) { } ubjson_options_common(const ubjson_options_common&) = default; ubjson_options_common& operator=(const ubjson_options_common&) = default; ubjson_options_common(ubjson_options_common&&) = default; ubjson_options_common& operator=(ubjson_options_common&&) = default; public: int max_nesting_depth() const { return max_nesting_depth_; } }; class ubjson_decode_options : public virtual ubjson_options_common { friend class ubjson_options; std::size_t max_items_{1 << 24}; public: ubjson_decode_options() { } ~ubjson_decode_options() = default; std::size_t max_items() const { return max_items_; } }; class ubjson_encode_options : public virtual ubjson_options_common { friend class ubjson_options; public: ubjson_encode_options() { } }; class ubjson_options final : public ubjson_decode_options, public ubjson_encode_options { public: using ubjson_options_common::max_nesting_depth; ubjson_options& max_nesting_depth(int value) { this->max_nesting_depth_ = value; return *this; } ubjson_options& max_items(std::size_t value) { this->max_items_ = value; return *this; } }; } // namespace ubjson } // namespace jsoncons #endif // JSONCONS_EXT_UBJSON_UBJSON_OPTIONS_HPP jsoncons-1.3.2/include/jsoncons_ext/ubjson/ubjson_parser.hpp000066400000000000000000000753121477700171100244120ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_UBJSON_UBJSON_PARSER_HPP #define JSONCONS_EXT_UBJSON_UBJSON_PARSER_HPP #include #include #include #include #include #include #include // std::move #include #include #include #include #include #include #include #include #include #include #include namespace jsoncons { namespace ubjson { enum class parse_mode {root,accept,array,indefinite_array,strongly_typed_array,map_key,map_value,strongly_typed_map_key,strongly_typed_map_value,indefinite_map_key,indefinite_map_value}; struct parse_state { parse_mode mode; std::size_t length{0}; uint8_t type; std::size_t index{0}; parse_state(parse_mode mode, std::size_t length, uint8_t type = 0) noexcept : mode(mode), length(length), type(type) { } parse_state(const parse_state&) = default; parse_state(parse_state&&) = default; }; template > class basic_ubjson_parser : public ser_context { using char_type = char; using char_traits_type = std::char_traits; using temp_allocator_type = Allocator; using char_allocator_type = typename std::allocator_traits:: template rebind_alloc; using byte_allocator_type = typename std::allocator_traits:: template rebind_alloc; using parse_state_allocator_type = typename std::allocator_traits:: template rebind_alloc; bool more_{true}; bool done_{false}; int nesting_depth_{0}; bool cursor_mode_{false}; int mark_level_{0}; Source source_; ubjson_decode_options options_; std::basic_string,char_allocator_type> text_buffer_; std::vector state_stack_; public: template basic_ubjson_parser(Sourceable&& source, const ubjson_decode_options& options = ubjson_decode_options(), const Allocator& alloc = Allocator()) : source_(std::forward(source)), options_(options), text_buffer_(alloc), state_stack_(alloc) { state_stack_.emplace_back(parse_mode::root,0); } void restart() { more_ = true; } void reset() { more_ = true; done_ = false; text_buffer_.clear(); state_stack_.clear(); state_stack_.emplace_back(parse_mode::root,0,uint8_t(0)); nesting_depth_ = 0; } template void reset(Sourceable&& source) { source_ = std::forward(source); reset(); } void cursor_mode(bool value) { cursor_mode_ = value; } int level() const { return static_cast(state_stack_.size()); } int mark_level() const { return mark_level_; } void mark_level(int value) { mark_level_ = value; } bool done() const { return done_; } bool stopped() const { return !more_; } std::size_t line() const override { return 0; } std::size_t column() const override { return source_.position(); } void parse(json_visitor& visitor, std::error_code& ec) { while (!done_ && more_) { switch (state_stack_.back().mode) { case parse_mode::array: { if (state_stack_.back().index < state_stack_.back().length) { ++state_stack_.back().index; read_type_and_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { return; } } else { end_array(visitor, ec); } break; } case parse_mode::strongly_typed_array: { if (state_stack_.back().index < state_stack_.back().length) { ++state_stack_.back().index; read_value(visitor, state_stack_.back().type, ec); if (JSONCONS_UNLIKELY(ec)) { return; } } else { end_array(visitor, ec); } break; } case parse_mode::indefinite_array: { auto c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = ubjson_errc::unexpected_eof; more_ = false; return; } if (c.value == jsoncons::ubjson::ubjson_type::end_array_marker) { source_.ignore(1); end_array(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { return; } } else { if (++state_stack_.back().index > options_.max_items()) { ec = ubjson_errc::max_items_exceeded; more_ = false; return; } read_type_and_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { return; } } break; } case parse_mode::map_key: { if (state_stack_.back().index < state_stack_.back().length) { ++state_stack_.back().index; read_key(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { return; } state_stack_.back().mode = parse_mode::map_value; } else { end_object(visitor, ec); } break; } case parse_mode::map_value: { state_stack_.back().mode = parse_mode::map_key; read_type_and_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { return; } break; } case parse_mode::strongly_typed_map_key: { if (state_stack_.back().index < state_stack_.back().length) { ++state_stack_.back().index; read_key(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { return; } state_stack_.back().mode = parse_mode::strongly_typed_map_value; } else { end_object(visitor, ec); } break; } case parse_mode::strongly_typed_map_value: { state_stack_.back().mode = parse_mode::strongly_typed_map_key; read_value(visitor, state_stack_.back().type, ec); if (JSONCONS_UNLIKELY(ec)) { return; } break; } case parse_mode::indefinite_map_key: { auto c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = ubjson_errc::unexpected_eof; more_ = false; return; } if (c.value == jsoncons::ubjson::ubjson_type::end_object_marker) { source_.ignore(1); end_object(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { return; } } else { if (++state_stack_.back().index > options_.max_items()) { ec = ubjson_errc::max_items_exceeded; more_ = false; return; } read_key(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { return; } state_stack_.back().mode = parse_mode::indefinite_map_value; } break; } case parse_mode::indefinite_map_value: { state_stack_.back().mode = parse_mode::indefinite_map_key; read_type_and_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { return; } break; } case parse_mode::root: { state_stack_.back().mode = parse_mode::accept; read_type_and_value(visitor, ec); if (JSONCONS_UNLIKELY(ec)) { return; } break; } case parse_mode::accept: { JSONCONS_ASSERT(state_stack_.size() == 1); state_stack_.clear(); more_ = false; done_ = true; visitor.flush(); break; } } } } private: void read_type_and_value(json_visitor& visitor, std::error_code& ec) { if (source_.is_error()) { ec = ubjson_errc::source_error; more_ = false; return; } uint8_t b; if (source_.read(&b, 1) == 0) { ec = ubjson_errc::unexpected_eof; more_ = false; return; } read_value(visitor, b, ec); } void read_value(json_visitor& visitor, uint8_t type, std::error_code& ec) { switch (type) { case jsoncons::ubjson::ubjson_type::null_type: { visitor.null_value(semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::ubjson::ubjson_type::no_op_type: { break; } case jsoncons::ubjson::ubjson_type::true_type: { visitor.bool_value(true, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::ubjson::ubjson_type::false_type: { visitor.bool_value(false, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::ubjson::ubjson_type::int8_type: { uint8_t buf[sizeof(int8_t)]; if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t)) { ec = ubjson_errc::unexpected_eof; more_ = false; return; } int8_t val = binary::big_to_native(buf, sizeof(buf)); visitor.int64_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::ubjson::ubjson_type::uint8_type: { uint8_t b; if (source_.read(&b, 1) == 0) { ec = ubjson_errc::unexpected_eof; more_ = false; return; } visitor.uint64_value(b, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::ubjson::ubjson_type::int16_type: { uint8_t buf[sizeof(int16_t)]; if (source_.read(buf, sizeof(int16_t)) != sizeof(int16_t)) { ec = ubjson_errc::unexpected_eof; more_ = false; return; } int16_t val = binary::big_to_native(buf, sizeof(buf)); visitor.int64_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::ubjson::ubjson_type::int32_type: { uint8_t buf[sizeof(int32_t)]; if (source_.read(buf, sizeof(int32_t)) != sizeof(int32_t)) { ec = ubjson_errc::unexpected_eof; more_ = false; return; } int32_t val = binary::big_to_native(buf, sizeof(buf)); visitor.int64_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::ubjson::ubjson_type::int64_type: { uint8_t buf[sizeof(int64_t)]; if (source_.read(buf, sizeof(int64_t)) != sizeof(int64_t)) { ec = ubjson_errc::unexpected_eof; more_ = false; return; } int64_t val = binary::big_to_native(buf, sizeof(buf)); visitor.int64_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::ubjson::ubjson_type::float32_type: { uint8_t buf[sizeof(float)]; if (source_.read(buf, sizeof(float)) != sizeof(float)) { ec = ubjson_errc::unexpected_eof; more_ = false; return; } float val = binary::big_to_native(buf, sizeof(buf)); visitor.double_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::ubjson::ubjson_type::float64_type: { uint8_t buf[sizeof(double)]; if (source_.read(buf, sizeof(double)) != sizeof(double)) { ec = ubjson_errc::unexpected_eof; more_ = false; return; } double val = binary::big_to_native(buf, sizeof(buf)); visitor.double_value(val, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::ubjson::ubjson_type::char_type: { text_buffer_.clear(); if (source_reader::read(source_,text_buffer_,1) != 1) { ec = ubjson_errc::unexpected_eof; more_ = false; return; } auto result = unicode_traits::validate(text_buffer_.data(),text_buffer_.size()); if (result.ec != unicode_traits::conv_errc()) { ec = ubjson_errc::invalid_utf8_text_string; more_ = false; return; } visitor.string_value(text_buffer_, semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::ubjson::ubjson_type::string_type: { std::size_t length = get_length(ec); if (JSONCONS_UNLIKELY(ec)) { return; } text_buffer_.clear(); if (source_reader::read(source_,text_buffer_,length) != length) { ec = ubjson_errc::unexpected_eof; more_ = false; return; } auto result = unicode_traits::validate(text_buffer_.data(),text_buffer_.size()); if (result.ec != unicode_traits::conv_errc()) { ec = ubjson_errc::invalid_utf8_text_string; more_ = false; return; } visitor.string_value(jsoncons::basic_string_view(text_buffer_.data(),text_buffer_.length()), semantic_tag::none, *this, ec); more_ = !cursor_mode_; break; } case jsoncons::ubjson::ubjson_type::high_precision_number_type: { std::size_t length = get_length(ec); if (JSONCONS_UNLIKELY(ec)) { return; } text_buffer_.clear(); if (source_reader::read(source_,text_buffer_,length) != length) { ec = ubjson_errc::unexpected_eof; more_ = false; return; } if (jsoncons::detail::is_base10(text_buffer_.data(),text_buffer_.length())) { visitor.string_value(jsoncons::basic_string_view(text_buffer_.data(),text_buffer_.length()), semantic_tag::bigint, *this, ec); more_ = !cursor_mode_; } else { visitor.string_value(jsoncons::basic_string_view(text_buffer_.data(),text_buffer_.length()), semantic_tag::bigdec, *this, ec); more_ = !cursor_mode_; } break; } case jsoncons::ubjson::ubjson_type::start_array_marker: { begin_array(visitor,ec); break; } case jsoncons::ubjson::ubjson_type::start_object_marker: { begin_object(visitor, ec); break; } default: { ec = ubjson_errc::unknown_type; break; } } if (JSONCONS_UNLIKELY(ec)) { more_ = false; } } void begin_array(json_visitor& visitor, std::error_code& ec) { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = ubjson_errc::max_nesting_depth_exceeded; more_ = false; return; } auto c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = ubjson_errc::unexpected_eof; more_ = false; return; } if (c.value == jsoncons::ubjson::ubjson_type::type_marker) { source_.ignore(1); uint8_t b; if (source_.read(&b, 1) == 0) { ec = ubjson_errc::unexpected_eof; more_ = false; return; } c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = ubjson_errc::unexpected_eof; more_ = false; return; } if (c.value == jsoncons::ubjson::ubjson_type::count_marker) { source_.ignore(1); std::size_t length = get_length(ec); if (JSONCONS_UNLIKELY(ec)) { return; } if (length > options_.max_items()) { ec = ubjson_errc::max_items_exceeded; more_ = false; return; } state_stack_.emplace_back(parse_mode::strongly_typed_array,length,b); visitor.begin_array(length, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else { ec = ubjson_errc::count_required_after_type; more_ = false; return; } } else if (c.value == jsoncons::ubjson::ubjson_type::count_marker) { source_.ignore(1); std::size_t length = get_length(ec); if (JSONCONS_UNLIKELY(ec)) { return; } if (length > options_.max_items()) { ec = ubjson_errc::max_items_exceeded; more_ = false; return; } state_stack_.emplace_back(parse_mode::array,length); visitor.begin_array(length, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else { state_stack_.emplace_back(parse_mode::indefinite_array,0); visitor.begin_array(semantic_tag::none, *this, ec); more_ = !cursor_mode_; } } void end_array(json_visitor& visitor, std::error_code& ec) { --nesting_depth_; visitor.end_array(*this, ec); more_ = !cursor_mode_; if (level() == mark_level_) { more_ = false; } state_stack_.pop_back(); } void begin_object(json_visitor& visitor, std::error_code& ec) { if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) { ec = ubjson_errc::max_nesting_depth_exceeded; more_ = false; return; } auto c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = ubjson_errc::unexpected_eof; more_ = false; return; } if (c.value == jsoncons::ubjson::ubjson_type::type_marker) { source_.ignore(1); uint8_t b; if (source_.read(&b, 1) == 0) { ec = ubjson_errc::unexpected_eof; more_ = false; return; } c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = ubjson_errc::unexpected_eof; more_ = false; return; } if (c.value == jsoncons::ubjson::ubjson_type::count_marker) { source_.ignore(1); std::size_t length = get_length(ec); if (JSONCONS_UNLIKELY(ec)) { return; } if (length > options_.max_items()) { ec = ubjson_errc::max_items_exceeded; more_ = false; return; } state_stack_.emplace_back(parse_mode::strongly_typed_map_key,length,b); visitor.begin_object(length, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else { ec = ubjson_errc::count_required_after_type; more_ = false; return; } } else { c = source_.peek(); if (JSONCONS_UNLIKELY(c.eof)) { ec = ubjson_errc::unexpected_eof; more_ = false; return; } if (c.value == jsoncons::ubjson::ubjson_type::count_marker) { source_.ignore(1); std::size_t length = get_length(ec); if (JSONCONS_UNLIKELY(ec)) { return; } if (length > options_.max_items()) { ec = ubjson_errc::max_items_exceeded; more_ = false; return; } state_stack_.emplace_back(parse_mode::map_key,length); visitor.begin_object(length, semantic_tag::none, *this, ec); more_ = !cursor_mode_; } else { state_stack_.emplace_back(parse_mode::indefinite_map_key,0); visitor.begin_object(semantic_tag::none, *this, ec); more_ = !cursor_mode_; } } } void end_object(json_visitor& visitor, std::error_code& ec) { --nesting_depth_; visitor.end_object(*this, ec); more_ = !cursor_mode_; if (level() == mark_level_) { more_ = false; } state_stack_.pop_back(); } std::size_t get_length(std::error_code& ec) { std::size_t length = 0; uint8_t type; if (source_.read(&type, 1) == 0) { ec = ubjson_errc::unexpected_eof; more_ = false; return length; } switch (type) { case jsoncons::ubjson::ubjson_type::int8_type: { uint8_t buf[sizeof(int8_t)]; if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t)) { ec = ubjson_errc::unexpected_eof; more_ = false; return length; } int8_t val = binary::big_to_native(buf, sizeof(buf)); if (val >= 0) { length = val; } else { ec = ubjson_errc::length_is_negative; more_ = false; return length; } break; } case jsoncons::ubjson::ubjson_type::uint8_type: { uint8_t b; if (source_.read(&b, 1) == 0) { ec = ubjson_errc::unexpected_eof; more_ = false; return length; } length = b; break; } case jsoncons::ubjson::ubjson_type::int16_type: { uint8_t buf[sizeof(int16_t)]; if (source_.read(buf, sizeof(int16_t)) != sizeof(int16_t)) { ec = ubjson_errc::unexpected_eof; more_ = false; return length; } int16_t val = binary::big_to_native(buf, sizeof(buf)); if (val >= 0) { length = val; } else { ec = ubjson_errc::length_is_negative; more_ = false; return length; } break; } case jsoncons::ubjson::ubjson_type::int32_type: { uint8_t buf[sizeof(int32_t)]; if (source_.read(buf, sizeof(int32_t)) != sizeof(int32_t)) { ec = ubjson_errc::unexpected_eof; more_ = false; return length; } int32_t val = binary::big_to_native(buf, sizeof(buf)); if (val >= 0) { length = static_cast(val); } else { ec = ubjson_errc::length_is_negative; more_ = false; return length; } break; } case jsoncons::ubjson::ubjson_type::int64_type: { uint8_t buf[sizeof(int64_t)]; if (source_.read(buf, sizeof(int64_t)) != sizeof(int64_t)) { ec = ubjson_errc::unexpected_eof; more_ = false; return length; } int64_t val = binary::big_to_native(buf, sizeof(buf)); if (val >= 0) { length = (std::size_t)val; if (length != (uint64_t)val) { ec = ubjson_errc::number_too_large; more_ = false; return length; } } else { ec = ubjson_errc::length_is_negative; more_ = false; return length; } break; } default: { ec = ubjson_errc::length_must_be_integer; more_ = false; return length; } } return length; } void read_key(json_visitor& visitor, std::error_code& ec) { std::size_t length = get_length(ec); if (JSONCONS_UNLIKELY(ec)) { ec = ubjson_errc::key_expected; more_ = false; return; } text_buffer_.clear(); if (source_reader::read(source_,text_buffer_,length) != length) { ec = ubjson_errc::unexpected_eof; more_ = false; return; } auto result = unicode_traits::validate(text_buffer_.data(),text_buffer_.size()); if (result.ec != unicode_traits::conv_errc()) { ec = ubjson_errc::invalid_utf8_text_string; more_ = false; return; } visitor.key(jsoncons::basic_string_view(text_buffer_.data(),text_buffer_.length()), *this, ec); more_ = !cursor_mode_; } }; } // namespace ubjson } // namespace jsoncons #endif jsoncons-1.3.2/include/jsoncons_ext/ubjson/ubjson_reader.hpp000066400000000000000000000047031477700171100243540ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_UBJSON_UBJSON_READER_HPP #define JSONCONS_EXT_UBJSON_UBJSON_READER_HPP #include #include #include #include // std::move #include #include #include #include #include #include #include namespace jsoncons { namespace ubjson { template > class basic_ubjson_reader { basic_ubjson_parser parser_; json_visitor& visitor_; public: template basic_ubjson_reader(Sourceable&& source, json_visitor& visitor, const Allocator& alloc) : basic_ubjson_reader(std::forward(source), visitor, ubjson_decode_options(), alloc) { } template basic_ubjson_reader(Sourceable&& source, json_visitor& visitor, const ubjson_decode_options& options = ubjson_decode_options(), const Allocator& alloc=Allocator()) : parser_(std::forward(source), options, alloc), visitor_(visitor) { } void read() { std::error_code ec; read(ec); if (JSONCONS_UNLIKELY(ec)) { JSONCONS_THROW(ser_error(ec,line(),column())); } } void read(std::error_code& ec) { parser_.reset(); parser_.parse(visitor_, ec); if (JSONCONS_UNLIKELY(ec)) { return; } } std::size_t line() const { return parser_.line(); } std::size_t column() const { return parser_.column(); } }; using ubjson_stream_reader = basic_ubjson_reader; using ubjson_bytes_reader = basic_ubjson_reader; } // namespace ubjson } // namespace jsoncons #endif // JSONCONS_EXT_UBJSON_UBJSON_READER_HPP jsoncons-1.3.2/include/jsoncons_ext/ubjson/ubjson_type.hpp000066400000000000000000000026311477700171100240710ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_EXT_UBJSON_UBJSON_TYPE_HPP #define JSONCONS_EXT_UBJSON_UBJSON_TYPE_HPP #include #include namespace jsoncons { namespace ubjson { namespace ubjson_type { const uint8_t null_type = 'Z'; const uint8_t no_op_type = 'N'; const uint8_t true_type = 'T'; const uint8_t false_type = 'F'; const uint8_t int8_type = 'i'; const uint8_t uint8_type = 'U'; const uint8_t int16_type = 'I'; const uint8_t int32_type = 'l'; const uint8_t int64_type = 'L'; const uint8_t float32_type = 'd'; const uint8_t float64_type = 'D'; const uint8_t high_precision_number_type = 'H'; const uint8_t char_type = 'C'; const uint8_t string_type = 'S'; const uint8_t start_array_marker = '['; const uint8_t end_array_marker = ']'; const uint8_t start_object_marker = '{'; const uint8_t end_object_marker = '}'; const uint8_t type_marker = '$'; const uint8_t count_marker = '#'; } } // namespace ubjson } // namespace jsoncons #endif // JSONCONS_EXT_UBJSON_UBJSON_TYPE_HPP jsoncons-1.3.2/test/000077500000000000000000000000001477700171100143355ustar00rootroot00000000000000jsoncons-1.3.2/test/CMakeLists.txt000066400000000000000000000245231477700171100171030ustar00rootroot00000000000000if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) project(jsoncons-test) find_package(jsoncons REQUIRED CONFIG) set(JSONCONS_INCLUDE_DIR ${jsoncons_INCLUDE_DIRS}) endif () if(NOT CMAKE_BUILD_TYPE) message(STATUS "Forcing tests build type to Release") set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE) endif() include(CheckCXXCompilerFlag) string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE) OPTION(JSONCONS_SANITIZE "sanitize" OFF) option(JSONCONS_VALGRIND "Execute tests with valgrind" OFF) if(JSONCONS_VALGRIND) find_program(CMAKE_MEMORYCHECK_COMMAND valgrind) message(STATUS "Executing test suite with Valgrind (${CMAKE_MEMORYCHECK_COMMAND})") set(memcheck_command "${CMAKE_MEMORYCHECK_COMMAND} ${CMAKE_MEMORYCHECK_COMMAND_OPTIONS} --error-exitcode=1 --leak-check=full") separate_arguments(memcheck_command) endif() include (CTest) # load per-platform configuration # include (${JSONCONS_PROJECT_DIR}/cmake/${CMAKE_SYSTEM_NAME}.cmake) # -fsanitize=undefined clang issue if (JSONCONS_SANITIZE) if(NOT MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fsanitize=address -fno-omit-frame-pointer") message(STATUS "SANITIZE ON") endif() endif() if(MSVC) set(CMAKE_EXE_LINKER_FLAGS /MANIFEST:NO) endif() set(CTEST_OUTPUT_ON_FAILURE ON) set(JSONCONS_TESTS_DIR ${JSONCONS_PROJECT_DIR}/test) set(JSONCONS_INCLUDE_DIR ${JSONCONS_PROJECT_DIR}/include) set(JSONCONS_THIRD_PARTY_INCLUDE_DIR ${JSONCONS_TESTS_DIR}/thirdparty) set(CATCH_INCLUDE_DIR ${JSONCONS_THIRD_PARTY_INCLUDE_DIR}/catch) add_library(catch INTERFACE) if (${CMAKE_VERSION} VERSION_LESS "3.8.0") target_compile_features(catch INTERFACE cxx_range_for) # for C++11 - flags else() target_compile_features(catch INTERFACE cxx_std_11) endif() target_include_directories (catch INTERFACE ${CATCH_INCLUDE_DIR}) add_executable(unit_tests fuzz_regression/src/fuzz_regression_tests.cpp bson/src/bson_cursor_tests.cpp bson/src/bson_encoder_tests.cpp bson/src/bson_reader_tests.cpp bson/src/bson_decimal128_tests.cpp bson/src/bson_oid_tests.cpp bson/src/bson_test_suite.cpp bson/src/encode_decode_bson_tests.cpp cbor/src/cbor_bitset_traits_tests.cpp cbor/src/cbor_cursor_tests.cpp cbor/src/cbor_event_reader_tests.cpp cbor/src/cbor_encoder_tests.cpp cbor/src/cbor_event_visitor_tests.cpp cbor/src/cbor_reader_tests.cpp cbor/src/cbor_tests.cpp cbor/src/cbor_typed_array_tests.cpp cbor/src/decode_cbor_tests.cpp cbor/src/encode_cbor_tests.cpp csv/src/csv_reader_tests.cpp csv/src/csv_cursor_tests.cpp csv/src/csv_subfield_tests.cpp csv/src/csv_tests.cpp csv/src/encode_decode_csv_tests.cpp jmespath/src/jmespath_custom_function_tests.cpp jmespath/src/jmespath_expression_tests.cpp jmespath/src/jmespath_let_tests.cpp jmespath/src/jmespath_tests.cpp mergepatch/src/mergepatch_test_suite.cpp jsonpatch/src/jsonpatch_test_suite.cpp jsonpatch/src/jsonpatch_tests.cpp jsonpath/src/jsonpath_flatten_tests.cpp jsonpath/src/jsonpath_function_tests.cpp jsonpath/src/path_node_tests.cpp jsonpath/src/json_location_tests.cpp jsonpath/src/json_location_parser_tests.cpp jsonpath/src/jsonpath_custom_function_tests.cpp jsonpath/src/jsonpath_json_query_tests.cpp jsonpath/src/jsonpath_expression_tests.cpp jsonpath/src/jsonpath_json_replace_tests.cpp jsonpath/src/jsonpath_select_paths_tests.cpp jsonpath/src/jsonpath_test_suite.cpp jsonpath/src/jsonpath_stateful_allocator_tests.cpp jsonpointer/src/jsonpointer_flatten_tests.cpp jsonpointer/src/jsonpointer_tests.cpp jsonschema/src/abort_early_tests.cpp jsonschema/src/custom_message_tests.cpp jsonschema/src/json_schema_walk_tests.cpp jsonschema/src/format_validator_tests.cpp jsonschema/src/validation_report_tests.cpp jsonschema/src/dynamic_ref_tests.cpp jsonschema/src/jsonschema_defaults_tests.cpp jsonschema/src/jsonschema_draft4_tests.cpp jsonschema/src/jsonschema_draft6_tests.cpp jsonschema/src/jsonschema_draft7_tests.cpp jsonschema/src/jsonschema_draft201909_tests.cpp jsonschema/src/jsonschema_draft202012_tests.cpp jsonschema/src/schema_version_tests.cpp msgpack/src/decode_msgpack_tests.cpp msgpack/src/encode_msgpack_tests.cpp msgpack/src/msgpack_bitset_traits_tests.cpp msgpack/src/msgpack_cursor_tests.cpp msgpack/src/msgpack_event_reader_tests.cpp msgpack/src/msgpack_encoder_tests.cpp msgpack/src/msgpack_tests.cpp msgpack/src/msgpack_timestamp_tests.cpp corelib/src/source_adaptor_tests.cpp corelib/src/value_converter_tests.cpp corelib/src/decode_traits_tests.cpp corelib/src/detail/optional_tests.cpp corelib/src/detail/span_tests.cpp corelib/src/detail/string_view_tests.cpp corelib/src/utility/byte_string_tests.cpp corelib/src/utility/heap_string_tests.cpp corelib/src/utility/bigint_tests.cpp corelib/src/utility/uri_tests.cpp corelib/src/utility/extension_traits_tests.cpp corelib/src/utility/unicode_conv_tests.cpp corelib/src/detail/to_integer_tests.cpp corelib/src/double_round_trip_tests.cpp corelib/src/double_to_string_tests.cpp corelib/src/dtoa_tests.cpp corelib/src/encode_decode_json_tests.cpp corelib/src/encode_traits_tests.cpp corelib/src/json_parser_recovery_tests.cpp corelib/src/json_array_tests.cpp corelib/src/json_as_tests.cpp corelib/src/json_bitset_traits_tests.cpp corelib/src/json_checker_tests.cpp corelib/src/json_compare_tests.cpp corelib/src/json_const_pointer_arg_tests.cpp corelib/src/json_pointer_arg_tests.cpp corelib/src/json_assignment_tests.cpp corelib/src/json_constructor_tests.cpp corelib/src/json_cursor_tests.cpp corelib/src/json_encoder_tests.cpp corelib/src/json_exception_tests.cpp corelib/src/json_filter_tests.cpp corelib/src/json_in_place_update_tests.cpp corelib/src/json_integer_tests.cpp corelib/src/json_less_tests.cpp corelib/src/json_line_split_tests.cpp corelib/src/json_literal_operator_tests.cpp corelib/src/json_object_tests.cpp corelib/src/ojson_object_tests.cpp corelib/src/json_options_tests.cpp corelib/src/json_parser_error_tests.cpp corelib/src/json_parser_position_tests.cpp corelib/src/json_parser_tests.cpp corelib/src/json_push_back_tests.cpp corelib/src/json_reader_exception_tests.cpp corelib/src/json_reader_tests.cpp corelib/src/json_storage_tests.cpp corelib/src/json_swap_tests.cpp corelib/src/json_traits_macro_functional_tests.cpp corelib/src/json_traits_macro_tests.cpp corelib/src/json_traits_macro_limit_tests.cpp corelib/src/json_traits_name_macro_tests.cpp corelib/src/json_type_traits_chrono_tests.cpp corelib/src/json_type_traits_container_tests.cpp corelib/src/json_type_traits_tests.cpp corelib/src/json_validation_tests.cpp corelib/src/jsoncons_tests.cpp corelib/src/JSONTestSuite_tests.cpp corelib/src/ojson_tests.cpp corelib/src/parse_string_tests.cpp corelib/src/short_string_tests.cpp corelib/src/source_tests.cpp corelib/src/staj_iterator_tests.cpp corelib/src/polymorphic_allocator_tests.cpp corelib/src/scoped_allocator_adaptor_tests.cpp corelib/src/string_to_double_tests.cpp corelib/src/wjson_tests.cpp ubjson/src/decode_ubjson_tests.cpp ubjson/src/encode_ubjson_tests.cpp ubjson/src/ubjson_cursor_tests.cpp ubjson/src/ubjson_encoder_tests.cpp corelib/src/testmain.cpp ) if (${CMAKE_VERSION} VERSION_LESS "3.8.0") target_compile_features(unit_tests INTERFACE cxx_range_for) # for C++11 - flags else() target_compile_features(unit_tests INTERFACE cxx_std_11) endif() target_compile_options(unit_tests PRIVATE $<$: /EHsc /MP /bigobj /W4> ) if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "8.0") message(STATUS Version " ${CMAKE_CXX_COMPILER_VERSION}") # older GCC versions don't support target_compile_options(unit_tests PRIVATE $<$:-Werror=maybe-uninitialized -Wnon-virtual-dtor -Werror=stringop-overflow -Werror -Wall -Wextra -Wcast-align -Wcast-qual -Wimplicit-fallthrough -Wsign-compare -pedantic -Wnonnull -Wnull-dereference -Werror=nonnull> ) endif() if (NOT CMAKE_SYSTEM_NAME STREQUAL Windows) target_compile_options(unit_tests PRIVATE $<$:-Werror=uninitialized -Werror -Wall -Wextra -Wimplicit-fallthrough -Wcast-align -Wcast-qual -Wsign-compare -pedantic> ) endif() add_test(NAME unit_tests COMMAND unit_tests WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/test) target_include_directories (unit_tests PUBLIC ${JSONCONS_INCLUDE_DIR} PRIVATE ${JSONCONS_TESTS_DIR} PRIVATE ${JSONCONS_THIRD_PARTY_INCLUDE_DIR}) target_link_libraries(unit_tests catch) jsoncons-1.3.2/test/bson/000077500000000000000000000000001477700171100152765ustar00rootroot00000000000000jsoncons-1.3.2/test/bson/input/000077500000000000000000000000001477700171100164355ustar00rootroot00000000000000jsoncons-1.3.2/test/bson/input/test1.bson000066400000000000000000000000161477700171100203550ustar00rootroot00000000000000intjsoncons-1.3.2/test/bson/input/test10.bson000066400000000000000000000000231477700171100204330ustar00rootroot00000000000000 regex1234ijsoncons-1.3.2/test/bson/input/test11.bson000066400000000000000000000000261477700171100204370ustar00rootroot00000000000000helloworldjsoncons-1.3.2/test/bson/input/test12.bson000066400000000000000000000000611477700171100204370ustar00rootroot000000000000001BSON&0awesome1333333@2jsoncons-1.3.2/test/bson/input/test13.bson000066400000000000000000000000431477700171100204400ustar00rootroot00000000000000#array[bool]012jsoncons-1.3.2/test/bson/input/test14.bson000066400000000000000000000000631477700171100204430ustar00rootroot000000000000003array[string]0hello1worldjsoncons-1.3.2/test/bson/input/test15.bson000066400000000000000000000000611477700171100204420ustar00rootroot000000000000001array[datetime] 0 1 +3jsoncons-1.3.2/test/bson/input/test16.bson000066400000000000000000000000401477700171100204400ustar00rootroot00000000000000 array[null] 0 1 2jsoncons-1.3.2/test/bson/input/test17.bson000066400000000000000000000003271477700171100204510ustar00rootroot00000000000000_id#Edocumentw_id#Etags)01122334text asdfanothersourcenameblahtype0sourcemissing0server_created_atjsoncons-1.3.2/test/bson/input/test18.bson000066400000000000000000000000141477700171100204430ustar00rootroot00000000000000 hellojsoncons-1.3.2/test/bson/input/test19.bson000066400000000000000000000000141477700171100204440ustar00rootroot00000000000000 booljsoncons-1.3.2/test/bson/input/test2.bson000066400000000000000000000000241477700171100203550ustar00rootroot00000000000000int64jsoncons-1.3.2/test/bson/input/test20.bson000066400000000000000000000000251477700171100204360ustar00rootroot00000000000000doubleS:^@jsoncons-1.3.2/test/bson/input/test21.bson000066400000000000000000000000241477700171100204360ustar00rootroot00000000000000documentjsoncons-1.3.2/test/bson/input/test22.bson000066400000000000000000000000261477700171100204410ustar00rootroot00000000000000oid4Vx4jsoncons-1.3.2/test/bson/input/test23.bson000066400000000000000000000000531477700171100204420ustar00rootroot00000000000000+array0hello1worldjsoncons-1.3.2/test/bson/input/test24.bson000066400000000000000000000000261477700171100204430ustar00rootroot00000000000000binary1234jsoncons-1.3.2/test/bson/input/test25.bson000066400000000000000000000000201477700171100204360ustar00rootroot00000000000000undefinedjsoncons-1.3.2/test/bson/input/test26.bson000066400000000000000000000000251477700171100204440ustar00rootroot00000000000000 time_tPqjsoncons-1.3.2/test/bson/input/test27.bson000066400000000000000000000000261477700171100204460ustar00rootroot00000000000000 regex^abcdilxjsoncons-1.3.2/test/bson/input/test28.bson000066400000000000000000000000441477700171100204470ustar00rootroot00000000000000$ dbpointerfoo###jsoncons-1.3.2/test/bson/input/test29.bson000066400000000000000000000000331477700171100204460ustar00rootroot00000000000000 code var a = {};jsoncons-1.3.2/test/bson/input/test3.bson000066400000000000000000000000251477700171100203570ustar00rootroot00000000000000double+?jsoncons-1.3.2/test/bson/input/test30.bson000066400000000000000000000000331477700171100204360ustar00rootroot00000000000000 code var a = {};jsoncons-1.3.2/test/bson/input/test31.bson000066400000000000000000000000611477700171100204400ustar00rootroot000000000000001code& var a = {};foobarjsoncons-1.3.2/test/bson/input/test32.bson000066400000000000000000000000261477700171100204420ustar00rootroot00000000000000helloworldjsoncons-1.3.2/test/bson/input/test33.bson000066400000000000000000000000321477700171100204400ustar00rootroot00000000000000acb{jsoncons-1.3.2/test/bson/input/test34.bson000066400000000000000000000000201477700171100204360ustar00rootroot00000000000000a@zZjsoncons-1.3.2/test/bson/input/test35.bson000066400000000000000000000000301477700171100204400ustar00rootroot00000000000000timestamp&jsoncons-1.3.2/test/bson/input/test36.bson000066400000000000000000000000151477700171100204440ustar00rootroot00000000000000 minkeyjsoncons-1.3.2/test/bson/input/test37.bson000066400000000000000000000000151477700171100204450ustar00rootroot00000000000000 maxkeyjsoncons-1.3.2/test/bson/input/test38.bson000066400000000000000000000014451477700171100204560ustar00rootroot00000000000000%aaa aaaaaaaaaaaaaaaaaa}auamaea]aUaMaEa=a5a-a%aaa aaaaaaaaaaaaaaaaaa}auamaea]aUaMaEa=a5a-a%aaa aaaaaaaaaaaaaaaaaa}auamaea]aUaMaEa=a5a-a%aaa ajsoncons-1.3.2/test/bson/input/test39.bson000066400000000000000000000014541477700171100204570ustar00rootroot00000000000000,b$bbb bbbbbbbbbbbbbbbbbb|btblbdb\bTbLbDb<b4b,b$bbb bbbbbbbbbbbbbbbbbb|btblbdb\bTbLbDb<b4b,b$bbb bbbbbbbbbbbbbbbbbb|btblbdb\bTbLbDb<b4b,b$bbb bjsoncons-1.3.2/test/bson/input/test4.bson000066400000000000000000000000221477700171100203550ustar00rootroot00000000000000 utc +3jsoncons-1.3.2/test/bson/input/test40.bson000066400000000000000000000000141477700171100204360ustar00rootroot00000000000000 jsoncons-1.3.2/test/bson/input/test41.bson000066400000000000000000000000221477700171100204360ustar00rootroot00000000000000foobarjsoncons-1.3.2/test/bson/input/test42.bson000066400000000000000000000000141477700171100204400ustar00rootroot00000000000000 jsoncons-1.3.2/test/bson/input/test43.bson000066400000000000000000000000221477700171100204400ustar00rootroot00000000000000foobarjsoncons-1.3.2/test/bson/input/test44.bson000066400000000000000000000000301477700171100204400ustar00rootroot00000000000000 RYj[AX]jsoncons-1.3.2/test/bson/input/test45.bson000066400000000000000000000000361477700171100204470ustar00rootroot00000000000000 foobarRYj[AX]jsoncons-1.3.2/test/bson/input/test46.bson000066400000000000000000000000141477700171100204440ustar00rootroot00000000000000 jsoncons-1.3.2/test/bson/input/test47.bson000066400000000000000000000000141477700171100204450ustar00rootroot00000000000000 jsoncons-1.3.2/test/bson/input/test48.bson000066400000000000000000000000341477700171100204500ustar00rootroot00000000000000 jsoncons-1.3.2/test/bson/input/test49.bson000066400000000000000000000000341477700171100204510ustar00rootroot00000000000000 jsoncons-1.3.2/test/bson/input/test5.bson000066400000000000000000000000351477700171100203620ustar00rootroot00000000000000string some stringjsoncons-1.3.2/test/bson/input/test50.bson000066400000000000000000000000341477700171100204410ustar00rootroot00000000000000 jsoncons-1.3.2/test/bson/input/test51.bson000066400000000000000000000000341477700171100204420ustar00rootroot00000000000000 jsoncons-1.3.2/test/bson/input/test52.bson000066400000000000000000000000301477700171100204370ustar00rootroot00000000000000foobar!jsoncons-1.3.2/test/bson/input/test53.bson000066400000000000000000000000361477700171100204460ustar00rootroot00000000000000 foobarRYj[AX]jsoncons-1.3.2/test/bson/input/test54.bson000066400000000000000000000000261477700171100204460ustar00rootroot00000000000000binary1234jsoncons-1.3.2/test/bson/input/test55.bson000066400000000000000000000000301477700171100204420ustar00rootroot00000000000000barjsoncons-1.3.2/test/bson/input/test56.bson000066400000000000000000000000521477700171100204470ustar00rootroot00000000000000*€€€€€"€€€€jsoncons-1.3.2/test/bson/input/test57.bson000066400000000000000000000000321477700171100204460ustar00rootroot00000000000000binary1234jsoncons-1.3.2/test/bson/input/test58.bson000066400000000000000000000000301477700171100204450ustar00rootroot00000000000000ajsoncons-1.3.2/test/bson/input/test59.bson000066400000000000000000000000211477700171100204460ustar00rootroot00000000000000.jsoncons-1.3.2/test/bson/input/test6.bson000066400000000000000000000001001477700171100203540ustar00rootroot00000000000000@array[int]/012345jsoncons-1.3.2/test/bson/input/test7.bson000066400000000000000000000000571477700171100203700ustar00rootroot00000000000000/array[double]0+?1Cl@jsoncons-1.3.2/test/bson/input/test8.bson000066400000000000000000000000351477700171100203650ustar00rootroot00000000000000documentintjsoncons-1.3.2/test/bson/input/test9.bson000066400000000000000000000000131477700171100203620ustar00rootroot00000000000000 nulljsoncons-1.3.2/test/bson/src/000077500000000000000000000000001477700171100160655ustar00rootroot00000000000000jsoncons-1.3.2/test/bson/src/bson_cursor_tests.cpp000066400000000000000000000246341477700171100223620ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("bson_cursor reputon test") { ojson j = ojson::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 } ] } )"); std::vector data; bson::encode_bson(j, data); SECTION("test 1") { bson::bson_bytes_cursor cursor(data); CHECK(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::double_value == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); CHECK(cursor.done()); } } TEST_CASE("bson_parser reset") { std::vector input1 = { 0x0C, 0x00, 0x00, 0x00, // Document: 12 bytes 0x10, // int32 field type 0x61, 0x00, // "a" field name 0x01, 0x00, 0x00, 0x00, // int32(1) field value 0x00, // end of object 0x0C, 0x00, 0x00, 0x00, // Document: 12 bytes 0x10, // int32 field type 0x62, 0x00, // "b" field name 0x02, 0x00, 0x00, 0x00, // int32(2) field value 0x00 // end of object }; std::vector input2 = { 0x0C, 0x00, 0x00, 0x00, // Document: 12 bytes 0x10, // int32 field type 0x63, 0x00, // "c" field name 0x03, 0x00, 0x00, 0x00, // int32(3) field value 0x00 // end of object }; json expected1 = json::parse(R"({"a":1})"); json expected2 = json::parse(R"({"b":2})"); json expected3 = json::parse(R"({"c":3})"); json_decoder destination; bson::basic_bson_parser parser{ input1 }; std::error_code ec; SECTION("keeping same source") { parser.parse(destination, ec); REQUIRE_FALSE(ec); CHECK(destination.get_result() == expected1); destination.reset(); parser.reset(); parser.parse(destination, ec); CHECK_FALSE(ec); CHECK(parser.stopped()); // TODO: This fails: CHECK(parser.done()); CHECK(destination.get_result() == expected2); } SECTION("with different source") { parser.parse(destination, ec); REQUIRE_FALSE(ec); CHECK(destination.get_result() == expected1); destination.reset(); parser.reset(input2); parser.parse(destination, ec); CHECK_FALSE(ec); CHECK(parser.stopped()); // TODO: This fails: CHECK(parser.done()); CHECK(destination.get_result() == expected3); } } struct bson_bytes_cursor_reset_test_traits { using cursor_type = bson::bson_bytes_cursor; using input_type = std::vector; static void set_input(input_type& input, input_type bytes) {input = bytes;} }; struct bson_stream_cursor_reset_test_traits { using cursor_type = bson::bson_stream_cursor; // binary_stream_source::char_type is actually char, not uint8_t using input_type = std::istringstream; static void set_input(input_type& input, std::vector bytes) { auto data = reinterpret_cast(bytes.data()); std::string s(data, bytes.size()); input.str(s); } }; template void check_bson_cursor_document(std::string info, CursorType& cursor, std::string expectedKey, int expectedValue) { INFO(info); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::begin_object == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); REQUIRE_FALSE(cursor.done()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); CHECK(expectedKey == cursor.current().template get()); CHECK(expectedKey == cursor.current().template get()); REQUIRE_FALSE(cursor.done()); cursor.next(); CHECK(staj_event_type::int64_value == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); CHECK(expectedValue == cursor.current().template get()); REQUIRE_FALSE(cursor.done()); cursor.next(); CHECK(staj_event_type::end_object == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); // Extra next() required to pop out of document state CHECK_FALSE(cursor.done()); cursor.next(); CHECK(cursor.done()); } TEMPLATE_TEST_CASE("bson_cursor reset test", "", bson_bytes_cursor_reset_test_traits, bson_stream_cursor_reset_test_traits) { using traits = TestType; using input_type = typename traits::input_type; using cursor_type = typename traits::cursor_type; using source_type = typename cursor_type::source_type; SECTION("keeping same source") { std::error_code ec; input_type input; traits::set_input(input, { 0x0C, 0x00, 0x00, 0x00, // Document: 12 bytes 0x10, // int32 field type 0x61, 0x00, // "a" field name 0x01, 0x00, 0x00, 0x00, // int32(1) field value 0x00, // end of object 0x0C, 0x00, 0x00, 0x00, // Document: 12 bytes 0x10, // int32 field type 0x62, 0x00, // "b" field name 0x02, 0x00, 0x00, 0x00, // int32(2) field value 0x00, // end of object 0x0C, 0x00, 0x00, 0x00, // Document: 12 bytes 0x10, // int32 field type 0x63, 0x00, // "c" field name 0x03, 0x00, 0x00, 0x00, // int32(3) field value 0x00 // end of object }); source_type source(input); cursor_type cursor(std::move(source)); check_bson_cursor_document("first document", cursor, "a", 1); cursor.reset(); check_bson_cursor_document("second document", cursor, "b", 2); cursor.reset(ec); check_bson_cursor_document("third document", cursor, "c", 3); } SECTION("with another source") { std::error_code ec; input_type input0; input_type input1; input_type input2; input_type input3; traits::set_input(input0, {}); traits::set_input(input1, { 0x0C, 0x00, 0x00, 0x00, // Document: 12 bytes 0x10, // int32 field type 0x61, 0x00, // "a" field name 0x01, 0x00, 0x00, 0x00, // int32(1) field value 0x00, // end of object }); traits::set_input(input2, { 0x09, 0x00, 0x00, 0x00, // Document: 9 bytes 0x20, // invalid field type 0x62, 0x00, // "b" field name 0x00, // bogus field value 0x00, // end of object }); traits::set_input(input3, { 0x0C, 0x00, 0x00, 0x00, // Document: 12 bytes 0x10, // int32 field type 0x63, 0x00, // "c" field name 0x03, 0x00, 0x00, 0x00, // int32(3) field value 0x00, // end of object }); // Constructing cursor with blank input results in unexpected_eof // error because it eagerly parses the next event upon construction. cursor_type cursor(input0, ec); CHECK(ec == bson::bson_errc::unexpected_eof); CHECK_FALSE(cursor.done()); // Reset to valid input1 cursor.reset(input1); check_bson_cursor_document("first document", cursor, "a", 1); // Reset to invalid input2 ec = bson::bson_errc::success; cursor.reset(input2, ec); REQUIRE_FALSE(ec); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::begin_object == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); REQUIRE_FALSE(cursor.done()); cursor.next(ec); REQUIRE_FALSE(ec); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::key == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); CHECK(std::string("b") == cursor.current().template get()); CHECK(cursor.current().template get() == jsoncons::string_view("b")); cursor.next(ec); CHECK(ec == bson::bson_errc::unknown_type); CHECK_FALSE(cursor.done()); // Reset to valid input3 ec = bson::bson_errc::success; cursor.reset(input3, ec); check_bson_cursor_document("third document", cursor, "c", 3); } } jsoncons-1.3.2/test/bson/src/bson_decimal128_tests.cpp000066400000000000000000001134141477700171100226710ustar00rootroot00000000000000/* * Copyright 2015 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include #include namespace bson = jsoncons::bson; TEST_CASE("test_decimal128_to_string__infinity") { char buf[bson::decimal128_limits::buf_size]; bson::decimal128_t positive_infinity(0x7800000000000000, 0); bson::decimal128_t negative_infinity(0xf800000000000000, 0); { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), positive_infinity); //std::cout << (uint64_t)buf << ", "<< (uint64_t)rc.ptr << "\n"; CHECK(rc.ec == std::errc()); std::string expected = "Infinity"; CHECK(static_cast(rc.ptr - buf) == expected.size()); CHECK(std::equal(buf, rc.ptr, expected.begin())); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), negative_infinity); CHECK(rc.ec == std::errc()); std::string expected = "-Infinity"; CHECK(static_cast(rc.ptr - buf) == expected.size()); CHECK(std::equal(buf, rc.ptr, expected.begin())); } } TEST_CASE("test_decimal128_to_string__nan") { /* All the above should just be NaN. */ char buf[bson::decimal128_limits::buf_size+1]; bson::decimal128_t dec_pnan(0x7c00000000000000, 0); bson::decimal128_t dec_nnan(0xfc00000000000000, 0); bson::decimal128_t dec_psnan(0x7e00000000000000, 0); bson::decimal128_t dec_nsnan(0xfe00000000000000, 0); bson::decimal128_t dec_payload_nan(0x7e00000000000000, 12); { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), dec_pnan); CHECK(rc.ec == std::errc()); std::string expected = "NaN"; CHECK(static_cast(rc.ptr - buf) == expected.size()); CHECK(std::equal(buf, rc.ptr, expected.begin())); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), dec_nnan); CHECK(rc.ec == std::errc()); std::string expected = "NaN"; CHECK(static_cast(rc.ptr - buf) == expected.size()); CHECK(std::equal(buf, rc.ptr, expected.begin())); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), dec_psnan); CHECK(rc.ec == std::errc()); std::string expected = "NaN"; CHECK(static_cast(rc.ptr - buf) == expected.size()); CHECK(std::equal(buf, rc.ptr, expected.begin())); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), dec_nsnan); CHECK(rc.ec == std::errc()); std::string expected = "NaN"; CHECK(static_cast(rc.ptr - buf) == expected.size()); CHECK(std::equal(buf, rc.ptr, expected.begin())); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), dec_payload_nan); CHECK(rc.ec == std::errc()); std::string expected = "NaN"; CHECK(static_cast(rc.ptr - buf) == expected.size()); CHECK(std::equal(buf, rc.ptr, expected.begin())); } } TEST_CASE("test_decimal128_to_string__regular") { char buf[bson::decimal128_limits::buf_size+1]; bson::decimal128_t one(0x3040000000000000, 0x0000000000000001); bson::decimal128_t zero(0x3040000000000000, 0x0000000000000000); bson::decimal128_t two(0x3040000000000000, 0x0000000000000002); bson::decimal128_t negative_one(0xb040000000000000, 0x0000000000000001); bson::decimal128_t negative_zero(0xb040000000000000, 0x0000000000000000); bson::decimal128_t tenth(0x303e000000000000, 0x0000000000000001); /* 0.1 */ /* 0.001234 */ bson::decimal128_t smallest_regular(0x3034000000000000, 0x00000000000004d2); /* 12345789012 */ bson::decimal128_t largest_regular(0x3040000000000000, 0x0000001cbe991a14); /* 0.00123400000 */ bson::decimal128_t trailing_zeros(0x302a000000000000, 0x00000000075aef40); /* 0.1234567890123456789012345678901234 */ bson::decimal128_t all_digits(0x2ffc3cde6fff9732, 0xde825cd07e96aff2); /* 5192296858534827628530496329220095 */ bson::decimal128_t full_house(0x3040ffffffffffff, 0xffffffffffffffff); { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), one); CHECK(rc.ec == std::errc()); std::string expected = "1"; CHECK(static_cast(rc.ptr - buf) == expected.size()); CHECK(std::equal(buf, rc.ptr, expected.begin())); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), zero); CHECK(rc.ec == std::errc()); std::string expected = "0"; CHECK(static_cast(rc.ptr - buf) == expected.size()); CHECK(std::equal(buf, rc.ptr, expected.begin())); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), two); CHECK(rc.ec == std::errc()); CHECK (std::equal(buf, rc.ptr, "2")); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), negative_one); CHECK(rc.ec == std::errc()); std::string expected = "-1"; CHECK(static_cast(rc.ptr - buf) == expected.size()); CHECK(std::equal(buf, rc.ptr, expected.begin())); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), negative_zero); CHECK(rc.ec == std::errc()); std::string expected = "-0"; CHECK(static_cast(rc.ptr - buf) == expected.size()); CHECK(std::equal(buf, rc.ptr, expected.begin())); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), tenth); CHECK(rc.ec == std::errc()); std::string expected = "0.1"; CHECK(static_cast(rc.ptr - buf) == expected.size()); CHECK(std::equal(buf, rc.ptr, expected.begin())); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), smallest_regular); CHECK(rc.ec == std::errc()); std::string expected = "0.001234"; CHECK(static_cast(rc.ptr - buf) == expected.size()); CHECK(std::equal(buf, rc.ptr, expected.begin())); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), largest_regular); CHECK(rc.ec == std::errc()); CHECK (std::equal(buf, rc.ptr, "123456789012")); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), trailing_zeros); CHECK(rc.ec == std::errc()); std::string expected = "0.00123400000"; CHECK(static_cast(rc.ptr - buf) == expected.size()); CHECK(std::equal(buf, rc.ptr, expected.begin())); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), all_digits); CHECK(rc.ec == std::errc()); CHECK (std::equal(buf, rc.ptr, "0.1234567890123456789012345678901234")); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), full_house); CHECK(rc.ec == std::errc()); CHECK (std::equal(buf, rc.ptr, "5192296858534827628530496329220095")); } } TEST_CASE("test_decimal128_to_string__scientific") { char buf[bson::decimal128_limits::buf_size+1]; bson::decimal128_t huge(0x5ffe314dc6448d93, 0x38c15b0a00000000); /* 1.000000000000000000000000000000000E+6144 */ bson::decimal128_t tiny(0x0000000000000000, 0x0000000000000001); /* 1E-6176 */ bson::decimal128_t neg_tiny(0x8000000000000000, 0x0000000000000001); /* -1E-6176 */ bson::decimal128_t large(0x3108000000000000, 0x000009184db63eb1); /* 9.999987654321E+112 */ bson::decimal128_t largest(0x5fffed09bead87c0, 0x378d8e63ffffffff); /* 9.999999999999999999999999999999999E+6144 */ bson::decimal128_t tiniest(0x0001ed09bead87c0, 0x378d8e63ffffffff); /* 9.999999999999999999999999999999999E-6143 */ bson::decimal128_t trailing_zero(0x304c000000000000, 0x000000000000041a); /* 1.050E9 */ bson::decimal128_t one_trailing_zero(0x3042000000000000, 0x000000000000041a); /* 1.050E4 */ bson::decimal128_t move_decimal(0x3040000000000000, 0x0000000000000069); /* 105 */ bson::decimal128_t move_decimal_after(0x3042000000000000, 0x0000000000000069); /* 1.05E3 */ bson::decimal128_t trailing_zero_no_decimal(0x3046000000000000, 0x0000000000000001); /* 1E3 */ { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), huge); CHECK(rc.ec == std::errc()); std::string expected = "1.000000000000000000000000000000000E+6144"; CHECK(static_cast(rc.ptr - buf) == expected.size()); CHECK(std::equal(buf, rc.ptr, expected.begin())); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), tiny); CHECK(rc.ec == std::errc()); std::string expected = "1E-6176"; CHECK(static_cast(rc.ptr - buf) == expected.size()); CHECK(std::equal(buf, rc.ptr, expected.begin())); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), neg_tiny); CHECK(rc.ec == std::errc()); CHECK (std::equal(buf, rc.ptr, "-1E-6176")); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), neg_tiny); CHECK(rc.ec == std::errc()); CHECK (std::equal(buf, rc.ptr, "-1E-6176")); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), large); CHECK(rc.ec == std::errc()); CHECK (std::equal(buf, rc.ptr, "9.999987654321E+112")); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), largest); CHECK(rc.ec == std::errc()); CHECK (std::equal(buf, rc.ptr, "9.999999999999999999999999999999999E+6144")); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), tiniest); CHECK(rc.ec == std::errc()); CHECK (std::equal(buf, rc.ptr, "9.999999999999999999999999999999999E-6143")); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), trailing_zero); CHECK(rc.ec == std::errc()); CHECK (std::equal(buf, rc.ptr, "1.050E+9")); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), one_trailing_zero); CHECK(rc.ec == std::errc()); CHECK (std::equal(buf, rc.ptr, "1.050E+4")); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), move_decimal); CHECK(rc.ec == std::errc()); std::string expected = "105"; CHECK(static_cast(rc.ptr - buf) == expected.size()); CHECK(std::equal(buf, rc.ptr, expected.begin())); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), move_decimal_after); CHECK(rc.ec == std::errc()); std::string expected = "1.05E+3"; CHECK(static_cast(rc.ptr - buf) == expected.size()); CHECK(std::equal(buf, rc.ptr, expected.begin())); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), trailing_zero_no_decimal); CHECK(rc.ec == std::errc()); std::string expected = "1E+3"; CHECK(static_cast(rc.ptr - buf) == expected.size()); CHECK(std::equal(buf, rc.ptr, expected.begin())); } } TEST_CASE("test_decimal128_to_string__zeros") { char buf[bson::decimal128_limits::buf_size+1]; bson::decimal128_t zero(0x3040000000000000, 0x0000000000000000); /* 0 */ bson::decimal128_t pos_exp_zero(0x3298000000000000, 0x0000000000000000); /* 0E+300 */ bson::decimal128_t neg_exp_zero(0x2b90000000000000, 0x0000000000000000); /* 0E-600 */ { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), zero); CHECK(rc.ec == std::errc()); CHECK (std::equal(buf, rc.ptr, "0")); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), pos_exp_zero); CHECK(rc.ec == std::errc()); CHECK (std::equal(buf, rc.ptr, "0E+300")); } { auto rc = bson::decimal128_to_chars(buf, buf+sizeof(buf), neg_exp_zero); CHECK(rc.ec == std::errc()); CHECK (std::equal(buf, rc.ptr, "0E-600")); } } TEST_CASE("test_decimal128_from_string__invalid_inputs") { bson::decimal128_t dec; { char buf[] = "."; auto rc = bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); //std::cout << (uint64_t)rc.ptr << ", " << (uint64_t)(buf+(sizeof(buf)-1)) << "\n"; CHECK_FALSE(rc.ec == std::errc()); CHECK((rc.ptr == buf+(sizeof(buf)-1))); CHECK (is_nan (dec)); } { char buf[] = ".e"; auto rc = bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = ""; auto rc = bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "invalid"; auto rc = bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "in"; auto rc = bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "i"; auto rc = bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "E02"; auto rc = bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "..1"; auto rc = bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "1abcede"; auto rc = bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "1.24abc"; auto rc = bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "1.24abcE+02"; auto rc = bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "1.24E+02abc2d"; auto rc = bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "E+02"; auto rc = bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "e+02"; auto rc = bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "."; auto rc = bson::decimal128_from_chars(buf, buf+1, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = ".e"; auto rc = bson::decimal128_from_chars(buf, buf+2, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = ""; auto rc = bson::decimal128_from_chars(buf, buf, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "invalid"; auto rc = bson::decimal128_from_chars(buf, buf+7, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "in"; auto rc = bson::decimal128_from_chars(buf, buf+2, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "i"; auto rc = bson::decimal128_from_chars(buf, buf+1, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "E02"; auto rc = bson::decimal128_from_chars(buf, buf+3, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "..1"; auto rc = bson::decimal128_from_chars(buf, buf+3, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "1abcede"; auto rc = bson::decimal128_from_chars(buf, buf+7, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "1.24abc"; auto rc = bson::decimal128_from_chars(buf, buf+7, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "1.24abcE+02"; auto rc = bson::decimal128_from_chars(buf, buf+11, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "1.24E+02abc2d"; auto rc = bson::decimal128_from_chars(buf, buf+13, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "E+02"; auto rc = bson::decimal128_from_chars(buf, buf+4, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } { char buf[] = "e+02"; auto rc = bson::decimal128_from_chars(buf, buf+4, dec); CHECK_FALSE(rc.ec == std::errc()); CHECK (is_nan (dec)); } } TEST_CASE("test_decimal128_from_string__nan") { bson::decimal128_t dec; { char buf[] = "NaN"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK (is_nan (dec)); } { char buf[] = "+NaN"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK (is_nan (dec)); } { char buf[] = "-NaN"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK (is_nan (dec)); } { char buf[] = "-nan"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK (is_nan (dec)); } { char buf[] = "1e"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK (is_nan (dec)); } { char buf[] = "+nan"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK (is_nan (dec)); } { char buf[] = "nan"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK (is_nan (dec)); } { char buf[] = "Nan"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK (is_nan (dec)); } { char buf[] = "+Nan"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK (is_nan (dec)); } { char buf[] = "-Nan"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK (is_nan (dec)); } { char buf[] = "NaN"; bson::decimal128_from_chars(buf, buf+3, dec); CHECK (is_nan (dec)); } { char buf[] = "+NaN"; bson::decimal128_from_chars(buf, buf+4, dec); CHECK (is_nan (dec)); } { char buf[] = "-NaN"; bson::decimal128_from_chars(buf, buf+4, dec); CHECK (is_nan (dec)); } { char buf[] = "-nan"; bson::decimal128_from_chars(buf, buf+4, dec); CHECK (is_nan (dec)); } { char buf[] = "1e"; bson::decimal128_from_chars(buf, buf+2, dec); CHECK (is_nan (dec)); } { char buf[] = "+nan"; bson::decimal128_from_chars(buf, buf+4, dec); CHECK (is_nan (dec)); } { char buf[] = "nan"; bson::decimal128_from_chars(buf, buf+3, dec); CHECK (is_nan (dec)); } { char buf[] = "Nan"; bson::decimal128_from_chars(buf, buf+3, dec); CHECK (is_nan (dec)); } { char buf[] = "+Nan"; bson::decimal128_from_chars(buf, buf+4, dec); CHECK (is_nan (dec)); } { char buf[] = "-Nan"; bson::decimal128_from_chars(buf, buf+4, dec); CHECK (is_nan (dec)); } } TEST_CASE("test_decimal128_from_string__infinity") { bson::decimal128_t dec; { char buf[] = "Infinity"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK (is_inf (dec)); } { char buf[] = "+Infinity"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK (is_inf (dec)); } { char buf[] = "+Inf"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK (is_inf (dec)); } { char buf[] = "-Inf"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK (is_neg_inf (dec)); } { char buf[] = "-Infinity"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, dec); CHECK (is_neg_inf (dec)); } { char buf[] = "Infinity"; bson::decimal128_from_chars(buf, buf+8, dec); CHECK (is_inf (dec)); } { char buf[] = "+Infinity"; bson::decimal128_from_chars(buf, buf+9, dec); CHECK (is_inf (dec)); } { char buf[] = "+Inf"; bson::decimal128_from_chars(buf, buf+4, dec); CHECK (is_inf (dec)); } { char buf[] = "-Inf"; bson::decimal128_from_chars(buf, buf+4, dec); CHECK (is_neg_inf (dec)); } { char buf[] = "-Infinity"; bson::decimal128_from_chars(buf, buf+9, dec); CHECK (is_neg_inf (dec)); } } TEST_CASE("test_decimal128_from_string__simple") { bson::decimal128_t one; bson::decimal128_t negative_one; bson::decimal128_t zero; bson::decimal128_t negative_zero; bson::decimal128_t number; bson::decimal128_t number_two; bson::decimal128_t negative_number; bson::decimal128_t fractional_number; bson::decimal128_t leading_zeros; bson::decimal128_t leading_insignificant_zeros; { char buf[] = "1"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, one); } { char buf[] = "-1"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, negative_one); } { char buf[] = "0"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, zero); } { char buf[] = "-0"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, negative_zero); } { char buf[] = "12345678901234567"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, number); } { char buf[] = "989898983458"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, number_two); } { char buf[] = "-12345678901234567"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, negative_number); } { char buf[] = "0.12345"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, fractional_number); } { char buf[] = "0.0012345"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, leading_zeros); } { char buf[] = "00012345678901234567"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, leading_insignificant_zeros); } CHECK (one == bson::decimal128_t(0x3040000000000000, 0x0000000000000001)); CHECK (negative_one == bson::decimal128_t(0xb040000000000000, 0x0000000000000001)); CHECK (zero == bson::decimal128_t(0x3040000000000000, 0x0000000000000000)); CHECK (negative_zero == bson::decimal128_t(0xb040000000000000, 0x0000000000000000)); CHECK (number == bson::decimal128_t(0x3040000000000000, 0x002bdc545d6b4b87)); CHECK (number_two == bson::decimal128_t(0x3040000000000000, 0x000000e67a93c822)); CHECK (negative_number == bson::decimal128_t(0xb040000000000000, 0x002bdc545d6b4b87)); CHECK (fractional_number == bson::decimal128_t(0x3036000000000000, 0x0000000000003039)); CHECK (leading_zeros == bson::decimal128_t(0x3032000000000000, 0x0000000000003039)); CHECK (leading_insignificant_zeros == bson::decimal128_t(0x3040000000000000, 0x002bdc545d6b4b87)); { char buf[] = "1"; bson::decimal128_from_chars(buf, buf+1, one); } { char buf[] = "-1"; bson::decimal128_from_chars(buf, buf+2, negative_one); } { char buf[] = "0"; bson::decimal128_from_chars(buf, buf+1, zero); } { char buf[] = "-0"; bson::decimal128_from_chars(buf, buf+2, negative_zero); } { char buf[] = "12345678901234567"; bson::decimal128_from_chars(buf, buf+17, number); } { char buf[] = "989898983458"; bson::decimal128_from_chars(buf, buf+12, number_two); CHECK (number_two == bson::decimal128_t(0x3040000000000000, 0x000000e67a93c822)); } { char buf[] = "-12345678901234567"; bson::decimal128_from_chars(buf, buf+18, negative_number); } { char buf[] = "0.12345"; bson::decimal128_from_chars(buf, buf+7, fractional_number); } { char buf[] = "0.0012345"; bson::decimal128_from_chars(buf, buf+9, leading_zeros); } { char buf[] = "00012345678901234567"; bson::decimal128_from_chars(buf, buf+20, leading_insignificant_zeros); } CHECK (one == bson::decimal128_t(0x3040000000000000, 0x0000000000000001)); CHECK (negative_one == bson::decimal128_t(0xb040000000000000, 0x0000000000000001)); CHECK (zero == bson::decimal128_t(0x3040000000000000, 0x0000000000000000)); CHECK (negative_zero == bson::decimal128_t(0xb040000000000000, 0x0000000000000000)); CHECK (number == bson::decimal128_t(0x3040000000000000, 0x002bdc545d6b4b87)); CHECK (negative_number == bson::decimal128_t(0xb040000000000000, 0x002bdc545d6b4b87)); CHECK (fractional_number == bson::decimal128_t(0x3036000000000000, 0x0000000000003039)); CHECK (leading_zeros == bson::decimal128_t(0x3032000000000000, 0x0000000000003039)); CHECK (leading_insignificant_zeros == bson::decimal128_t(0x3040000000000000, 0x002bdc545d6b4b87)); } TEST_CASE("test_decimal128_from_string__scientific") { bson::decimal128_t ten; bson::decimal128_t ten_again; bson::decimal128_t one; bson::decimal128_t huge_exp; bson::decimal128_t tiny_exp; bson::decimal128_t fractional; bson::decimal128_t trailing_zeros; { char buf[] = "10e0"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, ten); CHECK (ten == bson::decimal128_t(0x3040000000000000, 0x000000000000000a)); } { char buf[] = "1e1"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, ten_again); } { char buf[] = "10e-1"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, one); } CHECK (ten == bson::decimal128_t(0x3040000000000000, 0x000000000000000a)); CHECK (ten_again == bson::decimal128_t(0x3042000000000000, 0x0000000000000001)); CHECK (one == bson::decimal128_t(0x303e000000000000, 0x000000000000000a)); { char buf[] = "12345678901234567e6111"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, huge_exp); } { char buf[] = "1e-6176"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, tiny_exp); } CHECK (huge_exp == bson::decimal128_t(0x5ffe000000000000, 0x002bdc545d6b4b87)); CHECK (tiny_exp == bson::decimal128_t(0x0000000000000000, 0x0000000000000001)); { char buf[] = "-100E-10"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, fractional); } { char buf[] = "10.50E8"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, trailing_zeros); } CHECK (fractional == bson::decimal128_t(0xb02c000000000000, 0x0000000000000064)); CHECK (trailing_zeros == bson::decimal128_t(0x304c000000000000, 0x000000000000041a)); { char buf[] = "10e0"; bson::decimal128_from_chars(buf, buf+4, ten); } { char buf[] = "1e1"; bson::decimal128_from_chars(buf, buf+3, ten_again); } { char buf[] = "10e-1"; bson::decimal128_from_chars(buf, buf+5, one); } CHECK (ten_again == bson::decimal128_t(0x3042000000000000, 0x0000000000000001)); CHECK (one == bson::decimal128_t(0x303e000000000000, 0x000000000000000a)); { char buf[] = "12345678901234567e6111"; bson::decimal128_from_chars(buf, buf+22, huge_exp); } { char buf[] = "1e-6176"; bson::decimal128_from_chars(buf, buf+7, tiny_exp); } CHECK (huge_exp == bson::decimal128_t(0x5ffe000000000000, 0x002bdc545d6b4b87)); CHECK (tiny_exp == bson::decimal128_t(0x0000000000000000, 0x0000000000000001)); { char buf[] = "-100E-10"; bson::decimal128_from_chars(buf, buf+8, fractional); } { char buf[] = "10.50E8"; bson::decimal128_from_chars(buf, buf+7, trailing_zeros); } CHECK (fractional == bson::decimal128_t(0xb02c000000000000, 0x0000000000000064)); CHECK (trailing_zeros == bson::decimal128_t(0x304c000000000000, 0x000000000000041a)); } TEST_CASE("test_decimal128_from_string__large") { bson::decimal128_t large; bson::decimal128_t all_digits; bson::decimal128_t largest; bson::decimal128_t tiniest; bson::decimal128_t full_house; { char buf[] = "12345689012345789012345"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, large); } { char buf[] = "1234567890123456789012345678901234"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, all_digits); } { char buf[] = "9.999999999999999999999999999999999E+6144"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, largest); } { char buf[] = "9.999999999999999999999999999999999E-6143"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, tiniest); } { char buf[] = "5.192296858534827628530496329220095E+33"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, full_house); } CHECK (large == bson::decimal128_t(0x304000000000029d, 0x42da3a76f9e0d979)); CHECK (all_digits == bson::decimal128_t(0x30403cde6fff9732, 0xde825cd07e96aff2)); CHECK (largest == bson::decimal128_t(0x5fffed09bead87c0, 0x378d8e63ffffffff)); CHECK (tiniest == bson::decimal128_t(0x0001ed09bead87c0, 0x378d8e63ffffffff)); CHECK (full_house == bson::decimal128_t(0x3040ffffffffffff, 0xffffffffffffffff)); { char buf[] = "12345689012345789012345"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, large); } { char buf[] = "1234567890123456789012345678901234"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, all_digits); } { char buf[] = "9.999999999999999999999999999999999E+6144"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, largest); } { char buf[] = "9.999999999999999999999999999999999E-6143"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, tiniest); } { char buf[] = "5.192296858534827628530496329220095E+33"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, full_house); } CHECK (large == bson::decimal128_t(0x304000000000029d, 0x42da3a76f9e0d979)); CHECK (all_digits == bson::decimal128_t(0x30403cde6fff9732, 0xde825cd07e96aff2)); CHECK (largest == bson::decimal128_t(0x5fffed09bead87c0, 0x378d8e63ffffffff)); CHECK (tiniest == bson::decimal128_t(0x0001ed09bead87c0, 0x378d8e63ffffffff)); CHECK (full_house == bson::decimal128_t(0x3040ffffffffffff, 0xffffffffffffffff)); } TEST_CASE("test_decimal128_from_string__exponent_normalization") { bson::decimal128_t trailing_zeros; bson::decimal128_t one_normalize; bson::decimal128_t no_normalize; bson::decimal128_t a_disaster; { char buf[] = "1000000000000000000000000000000000000000"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, trailing_zeros); } { char buf[] = "10000000000000000000000000000000000"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, one_normalize); } { char buf[] = "1000000000000000000000000000000000"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, no_normalize); } { char buf[] = "100000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "0000000000000000000000000000000000"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, a_disaster); } CHECK (trailing_zeros == bson::decimal128_t(0x304c314dc6448d93, 0x38c15b0a00000000)); CHECK (one_normalize == bson::decimal128_t(0x3042314dc6448d93, 0x38c15b0a00000000)); CHECK (no_normalize == bson::decimal128_t(0x3040314dc6448d93, 0x38c15b0a00000000)); CHECK (a_disaster == bson::decimal128_t(0x37cc314dc6448d93, 0x38c15b0a00000000)); { char buf[] = "1000000000000000000000000000000000000000"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, trailing_zeros); } { char buf[] = "10000000000000000000000000000000000"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, one_normalize); } { char buf[] = "1000000000000000000000000000000000"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, no_normalize); } { char buf[] = "100000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000" "0000000000000000000000000000000000"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, a_disaster); } CHECK (trailing_zeros == bson::decimal128_t(0x304c314dc6448d93, 0x38c15b0a00000000)); CHECK (one_normalize == bson::decimal128_t(0x3042314dc6448d93, 0x38c15b0a00000000)); CHECK (no_normalize == bson::decimal128_t(0x3040314dc6448d93, 0x38c15b0a00000000)); CHECK (a_disaster == bson::decimal128_t(0x37cc314dc6448d93, 0x38c15b0a00000000)); } TEST_CASE("test_decimal128_from_string__zeros") { bson::decimal128_t zero; bson::decimal128_t exponent_zero; bson::decimal128_t large_exponent; bson::decimal128_t negative_zero; { char buf[] = "0"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, zero); } { char buf[] = "0e-611"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, exponent_zero); } { char buf[] = "0e+6000"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, large_exponent); } { char buf[] = "-0e-1"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, negative_zero); } CHECK (zero == bson::decimal128_t(0x3040000000000000, 0x0000000000000000)); CHECK (exponent_zero == bson::decimal128_t(0x2b7a000000000000, 0x0000000000000000)); CHECK (large_exponent == bson::decimal128_t(0x5f20000000000000, 0x0000000000000000)); CHECK (negative_zero == bson::decimal128_t(0xb03e000000000000, 0x0000000000000000)); { char buf[] = "0"; bson::decimal128_from_chars(buf, buf+1, zero); } { char buf[] = "0e-611"; bson::decimal128_from_chars(buf, buf+sizeof(buf)-1, exponent_zero); } { char buf[] = "0e+6000"; bson::decimal128_from_chars(buf, buf+7, large_exponent); } { char buf[] = "-0e-1"; bson::decimal128_from_chars(buf, buf+5, negative_zero); } CHECK (zero == bson::decimal128_t(0x3040000000000000, 0x0000000000000000)); CHECK (exponent_zero == bson::decimal128_t(0x2b7a000000000000, 0x0000000000000000)); CHECK (large_exponent == bson::decimal128_t(0x5f20000000000000, 0x0000000000000000)); CHECK (negative_zero == bson::decimal128_t(0xb03e000000000000, 0x0000000000000000)); } TEST_CASE("test_decimal128_from_string_w_len__special") { bson::decimal128_t number; bson::decimal128_t number_two; bson::decimal128_t negative_number; /* These strings have more bytes than the length indicates. */ { char buf[] = "12345678901234567abcd"; bson::decimal128_from_chars(buf, buf+17, number); } { char buf[] = "989898983458abcd"; bson::decimal128_from_chars(buf, buf+12, number_two); } { char buf[] = "-12345678901234567abcd"; bson::decimal128_from_chars(buf, buf+18, negative_number); } CHECK (number == bson::decimal128_t(0x3040000000000000, 0x002bdc545d6b4b87)); CHECK (number_two == bson::decimal128_t(0x3040000000000000, 0x000000e67a93c822)); CHECK (negative_number == bson::decimal128_t(0xb040000000000000, 0x002bdc545d6b4b87)); } jsoncons-1.3.2/test/bson/src/bson_encoder_tests.cpp000066400000000000000000000266551477700171100224710ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include using namespace jsoncons; namespace { void test_equal(const std::vector& v, const std::vector& expected) { REQUIRE(v.size() == expected.size()); for (std::size_t i = 0; i < v.size(); ++i) { CHECK(v[i] == expected[i]); } } void check_equal(const std::vector& v, const std::vector& expected) { test_equal(v, expected); JSONCONS_TRY { json j = bson::decode_bson(v); std::vector u; bson::encode_bson(j, u); test_equal(v,u); } JSONCONS_CATCH (const std::exception& e) { std::cout << e.what() << '\n'; } } } TEST_CASE("serialize to bson") { SECTION("array") { std::vector v; bson::bson_bytes_encoder encoder(v); encoder.begin_array(); encoder.int64_value((std::numeric_limits::max)()); encoder.uint64_value((uint64_t)(std::numeric_limits::max)()); encoder.double_value((std::numeric_limits::max)()); encoder.bool_value(true); encoder.bool_value(false); encoder.null_value(); encoder.string_value("Pussy cat"); std::vector purr = {'h','i','s','s'}; encoder.byte_string_value(purr); // default subtype is user defined // encoder.byte_string_value(purr, 0x80); encoder.end_array(); encoder.flush(); std::vector bson = {0x4e,0x00,0x00,0x00, 0x12, // int64 0x30, // '0' 0x00, // terminator 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, 0x12, // int64 0x31, // '1' 0x00, // terminator 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, 0x01, // double 0x32, // '2' 0x00, // terminator 0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x7f, 0x08, // bool 0x33, // '3' 0x00, // terminator 0x01, 0x08, // bool 0x34, // '4' 0x00, // terminator 0x00, 0x0a, // null 0x35, // '5' 0x00, // terminator 0x02, // string 0x36, // '6' 0x00, // terminator 0x0a,0x00,0x00,0x00, // string length 'P','u','s','s','y',' ','c','a','t', 0x00, // terminator 0x05, // binary 0x37, // '7' 0x00, // terminator 0x04,0x00,0x00,0x00, // byte string length 0x80, // subtype 'h','i','s','s', 0x00 // terminator }; check_equal(v,bson); } SECTION("object") { std::vector v; bson::bson_bytes_encoder encoder(v); encoder.begin_object(); encoder.key("0"); encoder.int64_value((std::numeric_limits::max)()); encoder.key("1"); encoder.uint64_value((uint64_t)(std::numeric_limits::max)()); encoder.key("2"); encoder.double_value((std::numeric_limits::max)()); encoder.key("3"); encoder.bool_value(true); encoder.key("4"); encoder.bool_value(false); encoder.key("5"); encoder.null_value(); encoder.key("6"); encoder.string_value("Pussy cat"); encoder.key("7"); std::vector hiss = {'h','i','s','s'}; encoder.byte_string_value(hiss); encoder.end_object(); encoder.flush(); std::vector bson = {0x4e,0x00,0x00,0x00, 0x12, // int64 0x30, // '0' 0x00, // terminator 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, 0x12, // int64 0x31, // '1' 0x00, // terminator 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, 0x01, // double 0x32, // '2' 0x00, // terminator 0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x7f, 0x08, // bool 0x33, // '3' 0x00, // terminator 0x01, 0x08, // bool 0x34, // '4' 0x00, // terminator 0x00, 0x0a, // null 0x35, // '5' 0x00, // terminator 0x02, // string 0x36, // '6' 0x00, // terminator 0x0a,0x00,0x00,0x00, // string length 'P','u','s','s','y',' ','c','a','t', 0x00, // terminator 0x05, // binary 0x37, // '7' 0x00, // terminator 0x04,0x00,0x00,0x00, // byte string length 0x80, // default subtype 'h','i','s','s', 0x00 // terminator }; check_equal(v,bson); } SECTION("outer object") { std::vector v; bson::bson_bytes_encoder encoder(v); encoder.begin_object(); encoder.key("a"); encoder.begin_object(); encoder.key("0"); encoder.int64_value((std::numeric_limits::max)()); encoder.end_object(); encoder.end_object(); encoder.flush(); std::vector bson = {0x18,0x00,0x00,0x00, 0x03, // object 'a', 0x00, 0x10,0x00,0x00,0x00, 0x12, // int64 0x30, // '0' 0x00, // terminator 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, 0x00, // terminator 0x00 // terminator }; check_equal(v,bson); } SECTION("outer array") { std::vector v; bson::bson_bytes_encoder encoder(v); encoder.begin_array(); encoder.begin_object(); encoder.key("0"); encoder.int64_value((std::numeric_limits::max)()); encoder.end_object(); encoder.end_array(); encoder.flush(); std::vector bson = {0x18,0x00,0x00,0x00, 0x03, // object '0', 0x00, 0x10,0x00,0x00,0x00, 0x12, // int64 0x30, // '0' 0x00, // terminator 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, 0x00, // terminator 0x00 // terminator }; check_equal(v,bson); } } TEST_CASE("serialize object to bson") { std::vector v; bson::bson_bytes_encoder encoder(v); encoder.begin_object(); encoder.key("null"); encoder.null_value(); encoder.end_object(); encoder.flush(); JSONCONS_TRY { json result = bson::decode_bson(v); } JSONCONS_CATCH (const std::exception& e) { std::cout << e.what() << '\n'; } } struct bson_bytes_encoder_reset_test_fixture { std::vector output1; std::vector output2; bson::bson_bytes_encoder encoder; bson_bytes_encoder_reset_test_fixture() : encoder(output1) {} std::vector bytes1() const {return output1;} std::vector bytes2() const {return output2;} }; struct bson_stream_encoder_reset_test_fixture { std::ostringstream output1; std::ostringstream output2; bson::bson_stream_encoder encoder; bson_stream_encoder_reset_test_fixture() : encoder(output1) {} std::vector bytes1() const {return bytes_of(output1);} std::vector bytes2() const {return bytes_of(output2);} private: static std::vector bytes_of(const std::ostringstream& os) { auto str = os.str(); auto data = reinterpret_cast(str.data()); std::vector bytes(data, data + str.size()); return bytes; } }; TEMPLATE_TEST_CASE("test_bson_encoder_reset", "", bson_bytes_encoder_reset_test_fixture, bson_stream_encoder_reset_test_fixture) { using fixture_type = TestType; fixture_type f; std::vector expected_full = { 0x0C, 0x00, 0x00, 0x00, // Document: 12 bytes 0x10, // int32 field type 0x62, 0x00, // "b" field name 0x02, 0x00, 0x00, 0x00, // int32(2) field value 0x00, // end of object marker }; // Partially encode, reset, then fully encode to same sink. // Note that partial BSON output is empty when flushed due to the // unknown document byte length. f.encoder.begin_object(1); f.encoder.key("a"); f.encoder.flush(); CHECK(f.bytes1().empty()); f.encoder.reset(); f.encoder.begin_object(1); f.encoder.key("b"); f.encoder.uint64_value(2); f.encoder.end_object(); f.encoder.flush(); CHECK(f.bytes1() == expected_full); // Reset and encode to different sink f.encoder.reset(f.output2); f.encoder.begin_object(1); f.encoder.key("b"); f.encoder.uint64_value(2); f.encoder.end_object(); f.encoder.flush(); CHECK(f.bytes2() == expected_full); } jsoncons-1.3.2/test/bson/src/bson_oid_tests.cpp000066400000000000000000000032231477700171100216070ustar00rootroot00000000000000/* * Copyright 2015 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include #include namespace bson = jsoncons::bson; TEST_CASE("test_bson_oid_init_from_string") { static std::vector gTestOids = {"000000000000000000000000", "010101010101010101010101", "0123456789abcdefafcdef03", "fcdeab182763817236817236", "ffffffffffffffffffffffff", "eeeeeeeeeeeeeeeeeeeeeeee", "999999999999999999999999", "111111111111111111111111"}; SECTION("test1") { for (const auto& item : gTestOids) { bson::oid_t oid(item); std::string s; to_string(oid, s); CHECK(item == s); } } } jsoncons-1.3.2/test/bson/src/bson_reader_tests.cpp000066400000000000000000000020771477700171100223040ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include using namespace jsoncons; void check_decode_bson(const std::vector& v, const json& expected) { json result = bson::decode_bson(v); REQUIRE(result == expected); std::string s; for (auto c : v) { s.push_back(c); } std::istringstream is(s); json j2 = bson::decode_bson(is); REQUIRE(j2 == expected); } TEST_CASE("bson hello world") { check_decode_bson({0x16,0x00,0x00,0x00, // total document size 0x02, // string 'h','e','l','l','o', 0x00, // field name 0x06,0x00,0x00,0x00, // size of value 'w','o','r','l','d',0x00, // field value and null terminator 0x00 // end of document },json::parse("{\"hello\":\"world\"}")); } jsoncons-1.3.2/test/bson/src/bson_test_suite.cpp000066400000000000000000000257651477700171100220210ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include using namespace jsoncons; namespace { std::vector read_bytes(const std::string& filename) { std::vector bytes; std::ifstream is(filename, std::ifstream::binary); REQUIRE(is); is.seekg (0, is.end); std::streamoff length = is.tellg(); is.seekg (0, is.beg); bytes.resize(static_cast(length)); is.read(bytes.data(), static_cast(length)); is.close(); return bytes; } } // Test data is from https://github.com/mongodb/mongo-c-driver/tree/master/src/libbson TEST_CASE("bson c test suite") { SECTION("utf8") { std::string in_file = "./bson/input/test11.bson"; std::vector bytes = read_bytes(in_file); json j; j.try_emplace("hello", "world"); std::vector bytes2; REQUIRE_NOTHROW(bson::encode_bson(j, bytes2)); //std::cout << byte_string_view(bytes2) << "\n\n"; //std::cout << byte_string_view(bytes) << "\n\n"; CHECK(bytes2 == bytes); auto b2 = bson::decode_bson(bytes); CHECK(b2 == j); } SECTION("null") { std::string in_file = "./bson/input/test18.bson"; std::vector bytes = read_bytes(in_file); json j; j.try_emplace("hello", null_type()); std::vector bytes2; REQUIRE_NOTHROW(bson::encode_bson(j, bytes2)); //std::cout << byte_string_view(bytes2) << "\n\n"; //std::cout << byte_string_view(bytes) << "\n\n"; CHECK(bytes2 == bytes); auto b2 = bson::decode_bson(bytes); CHECK(b2 == j); } SECTION("bool") { std::string in_file = "./bson/input/test19.bson"; std::vector bytes = read_bytes(in_file); std::vector bytes2; std::map m = { {"bool", true} }; REQUIRE_NOTHROW(bson::encode_bson(m, bytes2)); CHECK(bytes2 == bytes); auto m2 = bson::decode_bson>(bytes); CHECK(m2 == m); } SECTION("double") { std::string in_file = "./bson/input/test20.bson"; std::vector bytes = read_bytes(in_file); std::vector bytes2; std::map m = { {"double", 123.4567} }; REQUIRE_NOTHROW(bson::encode_bson(m, bytes2)); CHECK(bytes2 == bytes); auto m2 = bson::decode_bson>(bytes); CHECK(m2 == m); } SECTION("document") { std::string in_file = "./bson/input/test21.bson"; std::vector bytes = read_bytes(in_file); json b; b.try_emplace("document", json()); std::vector bytes2; REQUIRE_NOTHROW(bson::encode_bson(b, bytes2)); //std::cout << byte_string_view(bytes2) << "\n\n"; //std::cout << byte_string_view(bytes) << "\n\n"; CHECK(bytes2 == bytes); auto b2 = bson::decode_bson(bytes); CHECK(b2 == b); } SECTION("oid") { std::string in_file = "./bson/input/test22.bson"; std::vector input = read_bytes(in_file); json j = bson::decode_bson(input); bson::oid_t oid("1234567890abcdef1234abcd"); std::string s; to_string(oid, s); CHECK(j.at("oid").as() == s); CHECK(j.at("oid").tag() == semantic_tag::id); std::vector output; bson::encode_bson(j, output); CHECK(output == input); } SECTION("array") { std::string in_file = "./bson/input/test23.bson"; std::vector bytes = read_bytes(in_file); std::vector bytes2; ojson a(json_array_arg); a.push_back("hello"); a.push_back("world"); ojson b; b["array"] = std::move(a); REQUIRE_NOTHROW(bson::encode_bson(b, bytes2)); CHECK(bytes2 == bytes); auto b2 = bson::decode_bson(bytes); CHECK(b2 == b); } SECTION("binary") { std::string in_file = "./bson/input/test24.bson"; std::vector bytes = read_bytes(in_file); std::vector bytes2; std::vector bstr = {'1', '2', '3', '4'}; json b; b.try_emplace("binary", byte_string_arg, bstr, 0x80); REQUIRE_NOTHROW(bson::encode_bson(b, bytes2)); //std::cout << byte_string_view(bytes2) << "\n\n"; //std::cout << byte_string_view(bytes) << "\n\n"; CHECK(bytes2 == bytes); auto b2 = bson::decode_bson(bytes); CHECK(b2 == b); } SECTION("binary (jsoncons default)") { std::string in_file = "./bson/input/test24.bson"; std::vector bytes = read_bytes(in_file); std::vector bytes2; std::vector bstr = {'1', '2', '3', '4'}; json b; b.try_emplace("binary", byte_string_arg, bstr); // default subtype is user defined REQUIRE_NOTHROW(bson::encode_bson(b, bytes2)); //std::cout << byte_string_view(bytes2) << "\n\n"; //std::cout << byte_string_view(bytes) << "\n\n"; CHECK(bytes2 == bytes); auto b2 = bson::decode_bson(bytes); CHECK(b2 == b); } SECTION("undefined") { std::string in_file = "./bson/input/test25.bson"; std::vector input = read_bytes(in_file); json j = bson::decode_bson(input); //std::cout << j << "\n"; CHECK(j.at("undefined") == json::null()); CHECK(j.at("undefined").tag() == semantic_tag::undefined); std::vector output; bson::encode_bson(j, output); CHECK(output == input); } SECTION("time") { std::string in_file = "./bson/input/test26.bson"; std::vector input = read_bytes(in_file); json j = bson::decode_bson(input); int64_t expected = 1234567890000; // milliseconds CHECK(expected == j.at("time_t").as()); CHECK(j.at("time_t").tag() == semantic_tag::epoch_milli); std::vector output; bson::encode_bson(j, output); CHECK(output == input); } SECTION("regex") { std::string in_file = "./bson/input/test27.bson"; std::vector input = read_bytes(in_file); json j = bson::decode_bson(input); //std::cout << j << "\n"; std::string expected = "/^abcd/ilx"; CHECK(expected == j.at("regex").as()); CHECK(j.at("regex").tag() == semantic_tag::regex); std::vector output; bson::encode_bson(j, output); CHECK(output == input); } SECTION("code") { std::string in_file = "./bson/input/test29.bson"; std::vector input = read_bytes(in_file); json j = bson::decode_bson(input); std::string expected = "var a = {};"; CHECK(expected == j.at("code").as()); CHECK(j.at("code").tag() == semantic_tag::code); std::vector output; bson::encode_bson(j, output); CHECK(output == input); } SECTION("int32") { std::string in_file = "./bson/input/test33.bson"; std::vector bytes = read_bytes(in_file); std::vector bytes2; ojson j(json_object_arg); j.try_emplace("a", -123); j.try_emplace("c", 0); j.try_emplace("b", 123); REQUIRE_NOTHROW(bson::encode_bson(j, bytes2)); CHECK(bytes2 == bytes); auto j2 = bson::decode_bson(bytes); CHECK(j2 == j); } SECTION("int64") { uint8_t b; std::string in_file = "./bson/input/test34.bson"; std::vector bytes = read_bytes(in_file); bytes_source source(bytes); uint8_t buf[sizeof(int64_t)]; source.read(buf, sizeof(int32_t)); auto doc_size = binary::little_to_native(buf, sizeof(buf)); REQUIRE(doc_size == 16); REQUIRE(1 == source.read(&b, 1)); REQUIRE(b == 0x12); // 64-bit integer std::string s; while (source.read(&b, 1) == 1 && b != 0) { s.push_back(b); } REQUIRE(s == std::string("a")); source.read(buf, sizeof(int64_t)); auto val = binary::little_to_native(buf, sizeof(int64_t)); CHECK(val == 100000000000000ULL); REQUIRE(1 == source.read(&b, 1)); CHECK(0 == b); CHECK(source.eof()); std::vector bytes2; std::map m{ {"a", val} }; REQUIRE_NOTHROW(bson::encode_bson(m, bytes2)); CHECK(bytes2 == bytes); auto m2 = bson::decode_bson>(bytes); CHECK(m2 == m); } SECTION("decimal128") { std::string in_file = "./bson/input/test58.bson"; std::vector input = read_bytes(in_file); json j = bson::decode_bson(input); std::cout << j << "\n"; std::cout << j.tag() << "\n"; bson::decimal128_t dec(0,1); char buf[bson::decimal128_limits::buf_size]; auto rc = bson::decimal128_to_chars(buf,buf+sizeof(buf),dec); //std::cout << "128: " << std::string(buf,rc.ptr) << "\n"; CHECK(j.at("a") == json(std::string(buf,rc.ptr))); CHECK(j.at("a").tag() == semantic_tag::float128); std::vector output; bson::encode_bson(j, output); CHECK(output == input); } SECTION("document") { std::string in_file = "./bson/input/test21.bson"; std::vector bytes = read_bytes(in_file); json b; b.try_emplace("document", json()); std::vector bytes2; REQUIRE_NOTHROW(bson::encode_bson(b, bytes2)); //std::cout << byte_string_view(bytes2) << "\n\n"; //std::cout << byte_string_view(bytes) << "\n\n"; CHECK(bytes2 == bytes); auto b2 = bson::decode_bson(bytes); CHECK(b2 == b); } SECTION("oid") { std::string in_file = "./bson/input/test22.bson"; std::vector input = read_bytes(in_file); json j = bson::decode_bson(input); bson::oid_t oid("1234567890abcdef1234abcd"); std::string s; to_string(oid, s); CHECK(j.at("oid").as() == s); CHECK(j.at("oid").tag() == semantic_tag::id); std::vector output; bson::encode_bson(j, output); CHECK(output == input); } SECTION("regex") { std::string in_file = "./bson/input/test27.bson"; std::vector input = read_bytes(in_file); json j = bson::decode_bson(input); //std::cout << j << "\n"; std::string expected = "/^abcd/ilx"; std::vector output; bson::encode_bson(j, output); CHECK(output == input); } } jsoncons-1.3.2/test/bson/src/encode_decode_bson_tests.cpp000066400000000000000000000136431477700171100236030ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include using namespace jsoncons; namespace { class MyIterator { const uint8_t* p_; public: using iterator_category = std::input_iterator_tag; using value_type = uint8_t; using difference_type = std::ptrdiff_t; using pointer = const uint8_t*; using reference = const uint8_t&; MyIterator(const uint8_t* p) : p_(p) { } reference operator*() const { return *p_; } pointer operator->() const { return p_; } MyIterator& operator++() { ++p_; return *this; } MyIterator operator++(int) { MyIterator temp(*this); ++*this; return temp; } bool operator!=(const MyIterator& rhs) const { return p_ != rhs.p_; } }; } // namespace TEST_CASE("encode decode bson source uint8_t") { std::vector input = {0x27,0x00,0x00,0x00, // Total number of bytes comprising the document (40 bytes) 0x02, // URF-8 string 0x48,0x65,0x6c,0x6c,0x6f, // Hello 0x00, // trailing byte 0x06,0x00,0x00,0x00, // Number bytes in string (including trailing byte) 0x57,0x6f,0x72,0x6c,0x64, // World 0x00, // trailing byte 0x05, // binary 0x44,0x61,0x74,0x61, // Data 0x00, // trailing byte 0x06,0x00,0x00,0x00, // number of bytes 0x80, // subtype 0x66,0x6f,0x6f,0x62,0x61,0x72, 0x00}; SECTION("from bytes") { ojson j = bson::decode_bson(input); std::vector buffer; bson::encode_bson(j, buffer); CHECK(buffer == input); } SECTION("from stream") { std::string s(reinterpret_cast(input.data()), input.size()); std::stringstream is(std::move(s)); ojson j = bson::decode_bson(is); std::vector buffer; bson::encode_bson(j, buffer); CHECK(buffer == input); } SECTION("from iterator source") { ojson j = bson::decode_bson(input.begin(), input.end()); std::vector buffer; bson::encode_bson(j, buffer); CHECK(buffer == input); } SECTION("from custom iterator source") { MyIterator it(input.data()); MyIterator end(input.data() + input.size()); ojson j = bson::decode_bson(it, end); std::vector buffer; bson::encode_bson(j, buffer); CHECK(buffer == input); } } namespace { namespace ns { struct Person { std::string name; }; }} JSONCONS_ALL_MEMBER_TRAITS(ns::Person, name) TEST_CASE("encode_bson overloads") { SECTION("json, stream") { json person; person.try_emplace("name", "John Smith"); std::string s; std::stringstream ss(s); bson::encode_bson(person, ss); json other = bson::decode_bson(ss); CHECK(other == person); } SECTION("custom, stream") { ns::Person person{"John Smith"}; std::string s; std::stringstream ss(s); bson::encode_bson(person, ss); ns::Person other = bson::decode_bson(ss); CHECK(other.name == person.name); } } TEST_CASE("bson encode array") { SECTION("test1") { std::vector expected = {0x13,0x00,0x00,0x00,0x10,0x30,0x00,0x01,0x00,0x00,0x00,0x10,0x31,0x00,0x02,0x00,0x00,0x00,0x00}; /* 13,00,00,00, // document has 19 bytes 10,30,00, // "0" 01,00,00,00, // 1 10,31,00, // "1" 02,00,00,00, // 2 00 // terminating null */ std::pair p{1,2}; std::vector data; bson::encode_bson(p, data); CHECK(expected == data); auto p2 = bson::decode_bson>(data); CHECK(p2 == p); } } #if defined(JSONCONS_HAS_STATEFUL_ALLOCATOR) && JSONCONS_HAS_STATEFUL_ALLOCATOR == 1 #include #include template using MyScopedAllocator = std::scoped_allocator_adaptor>; using cust_json = basic_json>; TEST_CASE("encode decode bson source with temp_allocator") { std::vector input = {0x27,0x00,0x00,0x00, // Total number of bytes comprising the document (40 bytes) 0x02, // URF-8 string 0x48,0x65,0x6c,0x6c,0x6f, // Hello 0x00, // trailing byte 0x06,0x00,0x00,0x00, // Number bytes in string (including trailing byte) 0x57,0x6f,0x72,0x6c,0x64, // World 0x00, // trailing byte 0x05, // binary 0x44,0x61,0x74,0x61, // Data 0x00, // trailing byte 0x06,0x00,0x00,0x00, // number of bytes 0x80, // subtype 0x66,0x6f,0x6f,0x62,0x61,0x72, 0x00}; MyScopedAllocator temp_alloc(2); auto alloc_set = temp_allocator_only(temp_alloc); SECTION("from bytes") { auto j = bson::decode_bson(alloc_set, input); std::vector buffer; bson::encode_bson(alloc_set, j, buffer); CHECK(buffer == input); } SECTION("from stream") { std::string s(reinterpret_cast(input.data()), input.size()); std::stringstream is(std::move(s)); auto j = bson::decode_bson(alloc_set, is); std::vector buffer; bson::encode_bson(alloc_set, j, buffer); CHECK(buffer == input); } } #endif jsoncons-1.3.2/test/cbor/000077500000000000000000000000001477700171100152625ustar00rootroot00000000000000jsoncons-1.3.2/test/cbor/src/000077500000000000000000000000001477700171100160515ustar00rootroot00000000000000jsoncons-1.3.2/test/cbor/src/cbor_bitset_traits_tests.cpp000066400000000000000000000072551477700171100236750ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include using namespace jsoncons; TEST_CASE("CBOR std::bitset tests") { SECTION("low test") { std::bitset<32> i_bs32(0); std::string s32; cbor::encode_cbor(i_bs32, s32); auto o_bs32 = cbor::decode_cbor>(s32); CHECK(o_bs32 == i_bs32); std::bitset<64> i_bs64(0); std::string s64; cbor::encode_cbor(i_bs64, s64); auto o_bs64 = cbor::decode_cbor>(s64); CHECK(o_bs64 == i_bs64); } SECTION("high test") { std::bitset<32> i_bs32(0xffffffff); std::string s32; cbor::encode_cbor(i_bs32, s32); auto o_bs32 = cbor::decode_cbor>(s32); CHECK(o_bs32 == i_bs32); std::bitset<64> i_bs64(0xffffffffffffffff); std::string s64; cbor::encode_cbor(i_bs64, s64); auto o_bs64 = cbor::decode_cbor>(s64); CHECK(o_bs64 == i_bs64); } SECTION("random test") { std::random_device rd; std::mt19937 gen(rd()); auto rng32 = [&](){return random_binary_string(gen, 32);}; auto rng65 = [&](){return random_binary_string(gen, 65);}; auto rng128 = [&]() {return random_binary_string(gen, 128); }; auto rng129 = [&]() {return random_binary_string(gen, 129); }; auto rng256 = [&]() {return random_binary_string(gen, 256); }; auto rng257 = [&]() {return random_binary_string(gen, 257); }; auto rng512 = [&](){return random_binary_string(gen, 512);}; auto rng513 = [&](){return random_binary_string(gen, 513);}; for (std::size_t i = 0; i < 100; ++i) { std::bitset<32> i_bs32(rng32()); std::string s32; cbor::encode_cbor(i_bs32, s32); auto o_bs32 = cbor::decode_cbor>(s32); CHECK(o_bs32 == i_bs32); std::bitset<65> i_bs65(rng65()); std::string s65; cbor::encode_cbor(i_bs65, s65); auto o_bs65 = cbor::decode_cbor>(s65); CHECK(o_bs65 == i_bs65); std::bitset<128> i_bs128(rng128()); std::string s128; cbor::encode_cbor(i_bs128, s128); auto o_bs128 = cbor::decode_cbor>(s128); CHECK(o_bs128 == i_bs128); std::bitset<129> i_bs129(rng129()); std::string s129; cbor::encode_cbor(i_bs129, s129); auto o_bs129 = cbor::decode_cbor>(s129); CHECK(o_bs129 == i_bs129); std::bitset<256> i_bs256(rng256()); std::string s256; cbor::encode_cbor(i_bs256, s256); auto o_bs256 = cbor::decode_cbor>(s256); CHECK(o_bs256 == i_bs256); std::bitset<257> i_bs257(rng257()); std::string s257; cbor::encode_cbor(i_bs257, s257); auto o_bs257 = cbor::decode_cbor>(s257); CHECK(o_bs257 == i_bs257); std::bitset<512> i_bs512(rng512()); std::string s512; cbor::encode_cbor(i_bs512, s512); auto o_bs512 = cbor::decode_cbor>(s512); CHECK(o_bs512 == i_bs512); std::bitset<513> i_bs513(rng513()); std::string s513; cbor::encode_cbor(i_bs513, s513); auto o_bs513 = cbor::decode_cbor>(s513); CHECK(o_bs513 == i_bs513); } } } jsoncons-1.3.2/test/cbor/src/cbor_cursor_tests.cpp000066400000000000000000000335751477700171100223360ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("cbor_cursor reputon test") { ojson j = ojson::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 } ] } )"); std::vector data; cbor::encode_cbor(j, data); SECTION("test 1") { cbor::cbor_bytes_cursor cursor(data); CHECK(staj_event_type::begin_object == cursor.current().event_type()); CHECK(2 == cursor.current().size()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::begin_array == cursor.current().event_type()); CHECK(1 == cursor.current().size()); cursor.next(); CHECK(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::double_value == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); CHECK(cursor.done()); } } TEST_CASE("cbor_cursor indefinite array of array test") { std::vector data = {0x82,0x83,0x63,0x66,0x6f,0x6f,0x44,0x50,0x75,0x73,0x73,0xc3,0x49,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x83,0x63,0x62,0x61,0x72,0xd6,0x44,0x50,0x75,0x73,0x73,0xc4,0x82,0x21,0x19,0x6a,0xb3}; SECTION("test 1") { cbor::cbor_bytes_cursor cursor(data); CHECK(staj_event_type::begin_array == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); cursor.next(); CHECK(staj_event_type::begin_array == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); cursor.next(); CHECK(staj_event_type::string_value == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); cursor.next(); CHECK(staj_event_type::byte_string_value == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); cursor.next(); CHECK(staj_event_type::string_value == cursor.current().event_type()); CHECK(semantic_tag::bigint == cursor.current().tag()); cursor.next(); CHECK(staj_event_type::end_array == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); cursor.next(); CHECK(staj_event_type::begin_array == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); cursor.next(); CHECK(staj_event_type::string_value == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); cursor.next(); CHECK(staj_event_type::byte_string_value == cursor.current().event_type()); CHECK(semantic_tag::base64 == cursor.current().tag()); cursor.next(); CHECK(staj_event_type::string_value == cursor.current().event_type()); CHECK(semantic_tag::bigdec == cursor.current().tag()); cursor.next(); CHECK(staj_event_type::end_array == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); cursor.next(); CHECK(staj_event_type::end_array == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); cursor.next(); CHECK(cursor.done()); } } struct remove_mark_cbor_filter { bool reject_next_ = false; bool operator()(const staj_event& event, const ser_context&) { if (event.event_type() == staj_event_type::key && event.get() == "mark") { reject_next_ = true; return false; } else if (reject_next_) { reject_next_ = false; return false; } else { return true; } } }; TEST_CASE("cbor_cursor with filter tests") { auto j = ojson::parse(R"( [ { "enrollmentNo" : 100, "firstName" : "Tom", "lastName" : "Cochrane", "mark" : 55 }, { "enrollmentNo" : 101, "firstName" : "Catherine", "lastName" : "Smith", "mark" : 95 }, { "enrollmentNo" : 102, "firstName" : "William", "lastName" : "Skeleton", "mark" : 60 } ] )"); std::vector data; cbor::encode_cbor(j, data); cbor::cbor_bytes_cursor cursor(data); auto filtered_c = cursor | remove_mark_cbor_filter(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::begin_array); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::begin_object); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::uint64_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::string_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::string_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::end_object); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::begin_object); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::uint64_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::string_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::string_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::end_object); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::begin_object); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::uint64_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::string_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::string_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::end_object); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::end_array); filtered_c.next(); CHECK(filtered_c.done()); } struct cbor_bytes_cursor_reset_test_traits { using cursor_type = cbor::cbor_bytes_cursor; using input_type = std::vector; static void set_input(input_type& input, input_type bytes) {input = bytes;} }; struct cbor_stream_cursor_reset_test_traits { using cursor_type = cbor::cbor_stream_cursor; // binary_stream_source::char_type is actually char, not uint8_t using input_type = std::istringstream; static void set_input(input_type& input, std::vector bytes) { auto data = reinterpret_cast(bytes.data()); std::string s(data, bytes.size()); input.str(s); } }; TEMPLATE_TEST_CASE("cbor_cursor reset test", "", cbor_bytes_cursor_reset_test_traits, cbor_stream_cursor_reset_test_traits) { using traits = TestType; using input_type = typename traits::input_type; using cursor_type = typename traits::cursor_type; using source_type = typename cursor_type::source_type; SECTION("keeping same source") { std::error_code ec; input_type input; traits::set_input(input, { 0x63, 0x54, 0x6f, 0x6d, // text(3), "Tom" 0x38, 0x63, // negative(99) 0xf6 // null }); source_type source(input); cursor_type cursor(std::move(source)); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::string_value == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); CHECK(std::string("Tom") == cursor.current().template get()); CHECK(cursor.current().template get() == jsoncons::string_view("Tom")); cursor.next(); CHECK(cursor.done()); cursor.reset(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::int64_value == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); CHECK(-100 == cursor.current().template get()); cursor.next(); CHECK(cursor.done()); cursor.reset(ec); REQUIRE_FALSE(ec); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::null_value == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); cursor.next(ec); REQUIRE_FALSE(ec); CHECK(cursor.done()); } SECTION("with another source") { std::error_code ec; input_type input0; input_type input1; input_type input2; input_type input3; traits::set_input(input0, {}); traits::set_input(input1, {0x63, 0x54, 0x6f, 0x6d}); // text(3), "Tom" traits::set_input(input2, {0xe0}); // invalid special traits::set_input(input3, {0x38, 0x63}); // negative(99) // Constructing cursor with blank input results in unexpected_eof // error because it eagerly parses the next event upon construction. cursor_type cursor(input0, ec); CHECK(ec == cbor::cbor_errc::unexpected_eof); CHECK_FALSE(cursor.done()); // Reset to valid input1 cursor.reset(input1); CHECK(staj_event_type::string_value == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); CHECK(std::string("Tom") == cursor.current().template get()); CHECK(cursor.current().template get() == jsoncons::string_view("Tom")); ec = cbor::cbor_errc::success; REQUIRE_FALSE(cursor.done()); cursor.next(ec); CHECK_FALSE(ec); CHECK(cursor.done()); // Reset to invalid input2 ec = cbor::cbor_errc::success; cursor.reset(input2, ec); CHECK(ec == cbor::cbor_errc::unknown_type); CHECK_FALSE(cursor.done()); // Reset to valid input3 ec = cbor::cbor_errc::success; cursor.reset(input3, ec); REQUIRE_FALSE(ec); CHECK(staj_event_type::int64_value == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); CHECK(-100 == cursor.current().template get()); REQUIRE_FALSE(cursor.done()); cursor.next(ec); CHECK_FALSE(ec); CHECK(cursor.done()); } } jsoncons-1.3.2/test/cbor/src/cbor_encoder_tests.cpp000066400000000000000000000410331477700171100224240ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" #endif #include #include #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("cbor encode multi dim array test") { std::vector v; cbor::cbor_bytes_encoder encoder(v); std::vector shape = { 2,3 }; encoder.begin_multi_dim(shape); encoder.begin_array(6); encoder.uint64_value(2); encoder.uint64_value(4); encoder.uint64_value(8); encoder.uint64_value(4); encoder.uint64_value(16); encoder.uint64_value(256); encoder.end_array(); encoder.end_multi_dim(); byte_string_view bstr(v); //std::cout << "bstr: " << bstr << "\n\n"; //for (auto ch : bstr) //{ // std::cout << (int)ch << " "; //} //std::cout << "\n\n"; auto j = cbor::decode_cbor(v); //std::cout << pretty_print(j) << "\n\n"; } TEST_CASE("test_encode_to_stream") { json j = json::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 } ] } )"); std::ofstream os; os.open("./corelib/output/store.cbor", std::ios::binary | std::ios::out); cbor::encode_cbor(j,os); std::vector v; std::ifstream is; is.open("./corelib/output/store.cbor", std::ios::binary | std::ios::in); json j2 = cbor::decode_cbor(is); //std::cout << pretty_print(j2) << '\n'; CHECK(j == j2); } TEST_CASE("serialize array to cbor") { std::vector v; cbor::cbor_bytes_encoder encoder(v); encoder.begin_array(3); encoder.bool_value(true); encoder.bool_value(false); encoder.null_value(); encoder.end_array(); encoder.flush(); json result; REQUIRE_NOTHROW(result = cbor::decode_cbor(v)); } TEST_CASE("test_serialize_indefinite_length_array") { std::vector v; cbor::cbor_bytes_encoder encoder(v); encoder.begin_array(); encoder.begin_array(4); encoder.bool_value(true); encoder.bool_value(false); encoder.null_value(); encoder.string_value("Hello"); encoder.end_array(); encoder.end_array(); encoder.flush(); json result; REQUIRE_NOTHROW(result = cbor::decode_cbor(v)); } TEST_CASE("serialize object to cbor") { SECTION("definite length") { std::vector v; cbor::cbor_bytes_encoder encoder(v); encoder.begin_object(2); encoder.uint64_value(1); encoder.string_value("value1"); encoder.uint64_value(2); encoder.string_value("value2"); REQUIRE_NOTHROW(encoder.end_object()); encoder.flush(); json result; REQUIRE_NOTHROW(result = cbor::decode_cbor(v)); } } TEST_CASE("test_serialize_bignum") { std::vector v; cbor::cbor_bytes_encoder encoder(v); encoder.begin_array(); std::vector bytes = {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; bigint n = bigint::from_bytes_be(1, bytes.data(), bytes.size()); std::string s = n.to_string(); encoder.string_value(s, semantic_tag::bigint); encoder.end_array(); encoder.flush(); json result; REQUIRE_NOTHROW(result = cbor::decode_cbor(v)); CHECK(result[0].as() == std::string("18446744073709551616")); } TEST_CASE("test_serialize_negative_bignum1") { std::vector v; cbor::cbor_bytes_encoder encoder(v); encoder.begin_array(); std::vector bytes = {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; bigint n = bigint::from_bytes_be(1, bytes.data(), bytes.size()); n = -1 - n; std::string s = n.to_string(); encoder.string_value(s, semantic_tag::bigint); encoder.end_array(); encoder.flush(); JSONCONS_TRY { json result = cbor::decode_cbor(v); CHECK(result[0].as() == std::string("-18446744073709551617")); } JSONCONS_CATCH (const std::exception& e) { std::cout << e.what() << '\n'; } } TEST_CASE("test_serialize_negative_bignum2") { std::vector v; cbor::cbor_bytes_encoder encoder(v); encoder.begin_array(); std::vector bytes = {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; bigint n = bigint::from_bytes_be(1, bytes.data(), bytes.size()); n = -1 - n; std::string s = n.to_string(); encoder.string_value(s, semantic_tag::bigint); encoder.end_array(); encoder.flush(); JSONCONS_TRY { json result = cbor::decode_cbor(v); auto options = json_options{} .bignum_format(bignum_format_kind::raw); std::string text; result.dump(text,options); CHECK(text == std::string("[-18446744073709551617]")); } JSONCONS_CATCH (const std::exception& e) { std::cout << e.what() << '\n'; } } TEST_CASE("test_serialize_negative_bignum3") { std::vector v; cbor::cbor_bytes_encoder encoder(v); encoder.begin_array(); std::vector bytes = {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; bigint n = bigint::from_bytes_be(1, bytes.data(), bytes.size()); n = -1 - n; std::string s = n.to_string(); encoder.string_value(s, semantic_tag::bigint); encoder.end_array(); encoder.flush(); JSONCONS_TRY { json result = cbor::decode_cbor(v); auto options = json_options{} .bignum_format(bignum_format_kind::base64url); std::string text; result.dump(text,options); CHECK(text == std::string("[\"~AQAAAAAAAAAA\"]")); } JSONCONS_CATCH (const std::exception& e) { std::cout << e.what() << '\n'; } } TEST_CASE("serialize bigdec to cbor") { SECTION("-1 184467440737095516160") { std::vector v; cbor::cbor_bytes_encoder encoder(v); encoder.string_value("18446744073709551616.0", semantic_tag::bigdec); encoder.flush(); JSONCONS_TRY { json result = cbor::decode_cbor(v); CHECK(result.as() == std::string("1.84467440737095516160e+19")); } JSONCONS_CATCH (const std::exception& e) { std::cout << e.what() << '\n'; } } SECTION("18446744073709551616e-5") { std::vector v; cbor::cbor_bytes_encoder encoder(v); encoder.string_value("18446744073709551616e-5", semantic_tag::bigdec); encoder.flush(); JSONCONS_TRY { json result = cbor::decode_cbor(v); CHECK(result.as() == std::string("184467440737095.51616")); } JSONCONS_CATCH (const std::exception& e) { std::cout << e.what() << '\n'; } } SECTION("-18446744073709551616e-5") { std::vector v; cbor::cbor_bytes_encoder encoder(v); encoder.string_value("-18446744073709551616e-5", semantic_tag::bigdec); encoder.flush(); JSONCONS_TRY { json result = cbor::decode_cbor(v); CHECK(result.as() == std::string("-184467440737095.51616")); } JSONCONS_CATCH (const std::exception& e) { std::cout << e.what() << '\n'; } } SECTION("-18446744073709551616e5") { std::vector v; cbor::cbor_bytes_encoder encoder(v); encoder.string_value("-18446744073709551616e5", semantic_tag::bigdec); encoder.flush(); JSONCONS_TRY { json result = cbor::decode_cbor(v); CHECK(result.as() == std::string("-1.8446744073709551616e+24")); } JSONCONS_CATCH (const std::exception& e) { std::cout << e.what() << '\n'; } } } TEST_CASE("Too many and too few items in CBOR map or array") { std::error_code ec{}; std::vector v; cbor::cbor_bytes_encoder encoder(v); SECTION("Too many items in array") { encoder.begin_array(3); encoder.bool_value(true); encoder.bool_value(false); encoder.null_value(); encoder.begin_array(2); encoder.string_value("cat"); encoder.string_value("feline"); encoder.end_array(); REQUIRE_THROWS_WITH(encoder.end_array(), cbor::cbor_error_category_impl().message((int)cbor::cbor_errc::too_many_items).c_str()); encoder.flush(); } SECTION("Too few items in array") { encoder.begin_array(5); encoder.bool_value(true); encoder.bool_value(false); encoder.null_value(); encoder.begin_array(2); encoder.string_value("cat"); encoder.string_value("feline"); encoder.end_array(); REQUIRE_THROWS_WITH(encoder.end_array(), cbor::cbor_error_category_impl().message((int)cbor::cbor_errc::too_few_items).c_str()); encoder.flush(); } SECTION("Too many items in map") { encoder.begin_object(3); encoder.key("a"); encoder.bool_value(true); encoder.key("b"); encoder.bool_value(false); encoder.key("c"); encoder.null_value(); encoder.key("d"); encoder.begin_array(2); encoder.string_value("cat"); encoder.string_value("feline"); encoder.end_array(); REQUIRE_THROWS_WITH(encoder.end_object(), cbor::cbor_error_category_impl().message((int)cbor::cbor_errc::too_many_items).c_str()); encoder.flush(); } SECTION("Too few items in map") { encoder.begin_object(5); encoder.key("a"); encoder.bool_value(true); encoder.key("b"); encoder.bool_value(false); encoder.key("c"); encoder.null_value(); encoder.key("d"); encoder.begin_array(2); encoder.string_value("cat"); encoder.string_value("feline"); encoder.end_array(); REQUIRE_THROWS_WITH(encoder.end_object(), cbor::cbor_error_category_impl().message((int)cbor::cbor_errc::too_few_items).c_str()); encoder.flush(); } SECTION("Just enough items") { encoder.begin_array(4); // a fixed length array encoder.string_value("foo"); encoder.byte_string_value(std::vector{'P','u','s','s'}); // no suggested conversion encoder.string_value("-18446744073709551617", semantic_tag::bigint); encoder.string_value("273.15", semantic_tag::bigdec); encoder.end_array(); CHECK_FALSE(ec); encoder.flush(); } } TEST_CASE("encode stringref") { ojson j = ojson::parse(R"( [ { "name" : "Cocktail", "count" : 417, "rank" : 4 }, { "rank" : 4, "count" : 312, "name" : "Bath" }, { "count" : 691, "name" : "Food", "rank" : 4 } ] )"); auto options = cbor::cbor_options{} .pack_strings(true); std::vector buf; cbor::encode_cbor(j, buf, options); ojson j2 = cbor::decode_cbor(buf); CHECK(j2 == j); } TEST_CASE("cbor encode with semantic_tags") { SECTION("string") { json original; original["uri"] = json("https://gmail.com/", semantic_tag::uri); original["base64url"] = json("Zm9vYmFy", semantic_tag::base64url); original["base64"] = json("Zm9vYmE=", semantic_tag::base64); std::vector buffer; cbor::encode_cbor(original, buffer); json j = cbor::decode_cbor(buffer); CHECK(j == original); } SECTION("byte_string") { const std::vector s1 = {'f','o'}; const std::vector s2 = {'f','o','o','b','a'}; const std::vector s3 = {'f','o','o','b','a','r'}; json original; original["base64url"] = json(byte_string_arg, s1, semantic_tag::base64url); original["base64"] = json(byte_string_arg, s2, semantic_tag::base64); original["base16"] = json(byte_string_arg, s3, semantic_tag::base16); std::vector buffer; cbor::encode_cbor(original, buffer); json j = cbor::decode_cbor(buffer); CHECK(j == original); } } struct cbor_bytes_encoder_reset_test_fixture { std::vector output1; std::vector output2; cbor::cbor_bytes_encoder encoder; cbor_bytes_encoder_reset_test_fixture() : encoder(output1) {} std::vector bytes1() const {return output1;} std::vector bytes2() const {return output2;} }; struct cbor_stream_encoder_reset_test_fixture { std::ostringstream output1; std::ostringstream output2; cbor::cbor_stream_encoder encoder; cbor_stream_encoder_reset_test_fixture() : encoder(output1) {} std::vector bytes1() const {return bytes_of(output1);} std::vector bytes2() const {return bytes_of(output2);} private: static std::vector bytes_of(const std::ostringstream& os) { auto str = os.str(); auto data = reinterpret_cast(str.data()); std::vector bytes(data, data + str.size()); return bytes; } }; TEMPLATE_TEST_CASE("test_cbor_encoder_reset", "", cbor_bytes_encoder_reset_test_fixture, cbor_stream_encoder_reset_test_fixture) { using fixture_type = TestType; fixture_type f; std::vector expected_partial = { 0x82, // array(2) 0x63, // text(3) 0x66, 0x6F, 0x6F // "foo" // second element missing }; std::vector expected_full = { 0x82, // array(2) 0x63, // text(3) 0x66, 0x6F, 0x6F, // "foo" 0x18, 0x2A // unsigned(42) }; std::vector expected_partial_then_full(expected_partial); expected_partial_then_full.insert(expected_partial_then_full.end(), expected_full.begin(), expected_full.end()); // Parially encode, reset, then fully encode to same sink f.encoder.begin_array(2); f.encoder.string_value("foo"); f.encoder.flush(); CHECK(f.bytes1() == expected_partial); f.encoder.reset(); f.encoder.begin_array(2); f.encoder.string_value("foo"); f.encoder.uint64_value(42); f.encoder.end_array(); f.encoder.flush(); CHECK(f.bytes1() == expected_partial_then_full); // Reset and encode to different sink f.encoder.reset(f.output2); f.encoder.begin_array(2); f.encoder.string_value("foo"); f.encoder.uint64_value(42); f.encoder.end_array(); f.encoder.flush(); CHECK(f.bytes2() == expected_full); } TEST_CASE("test cbor encode with raw tags") { SECTION("test 1") { std::vector data; cbor::cbor_bytes_encoder encoder(data); encoder.begin_array_with_tag(7,0xB1); encoder.null_value_with_tag(0xC1); encoder.bool_value_with_tag(false, 0xC2); encoder.uint64_value_with_tag(1, 0xC3); encoder.int64_value_with_tag(-10, 0xC4); encoder.double_value_with_tag(10.5, 0xC5); encoder.byte_string_value_with_tag(std::vector{0x01,0x02,0x03}, 0xC6); encoder.begin_object_with_tag(0, 0xD1); encoder.end_object(); encoder.end_array(); encoder.flush(); cbor::cbor_bytes_cursor cursor(data); CHECK(0xB1 == cursor.raw_tag()); CHECK(jsoncons::staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); CHECK(0xC1 == cursor.raw_tag()); CHECK(jsoncons::staj_event_type::null_value == cursor.current().event_type()); cursor.next(); CHECK(0xC2 == cursor.raw_tag()); CHECK(false == cursor.current().get()); cursor.next(); CHECK(0xC3 == cursor.raw_tag()); CHECK(1 == cursor.current().get()); cursor.next(); CHECK(0xC4 == cursor.raw_tag()); CHECK(-10 == cursor.current().get()); cursor.next(); CHECK(0xC5 == cursor.raw_tag()); CHECK(Approx(10.5).epsilon(0.00001) == cursor.current().get()); cursor.next(); CHECK(0xC6 == cursor.raw_tag()); CHECK(std::vector{0x01,0x02,0x03} == cursor.current().get>()); cursor.next(); CHECK(0xD1 == cursor.raw_tag()); CHECK(jsoncons::staj_event_type::begin_object == cursor.current().event_type()); } } jsoncons-1.3.2/test/cbor/src/cbor_event_reader_tests.cpp000066400000000000000000000160511477700171100234520ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("cbor_event_reader reputon test") { ojson j = ojson::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 } ] } )"); std::vector data; cbor::encode_cbor(j, data); SECTION("test 1") { cbor::cbor_event_reader reader(data); CHECK(reader.current().event_type() == staj_event_type::begin_object); CHECK(2 == reader.current().size()); reader.next(); CHECK(reader.current().event_type() == staj_event_type::string_value); // key reader.next(); CHECK(reader.current().event_type() == staj_event_type::string_value); reader.next(); CHECK(reader.current().event_type() == staj_event_type::string_value); // key reader.next(); CHECK(reader.current().event_type() == staj_event_type::begin_array); CHECK(1 == reader.current().size()); reader.next(); CHECK(reader.current().event_type() == staj_event_type::begin_object); reader.next(); CHECK(reader.current().event_type() == staj_event_type::string_value); // key reader.next(); CHECK(reader.current().event_type() == staj_event_type::string_value); reader.next(); CHECK(reader.current().event_type() == staj_event_type::string_value); // key reader.next(); CHECK(reader.current().event_type() == staj_event_type::string_value); reader.next(); CHECK(reader.current().event_type() == staj_event_type::string_value); // key reader.next(); CHECK(reader.current().event_type() == staj_event_type::string_value); reader.next(); CHECK(reader.current().event_type() == staj_event_type::string_value); // key reader.next(); CHECK(reader.current().event_type() == staj_event_type::double_value); reader.next(); CHECK(reader.current().event_type() == staj_event_type::end_object); reader.next(); CHECK(reader.current().event_type() == staj_event_type::end_array); reader.next(); CHECK(reader.current().event_type() == staj_event_type::end_object); reader.next(); CHECK(reader.done()); } } struct cbor_bytes_cursor2_reset_test_traits { using event_reader_type = cbor::cbor_event_reader; using input_type = std::vector; static void set_input(input_type& input, input_type bytes) {input = bytes;} }; struct cbor_stream_cursor2_reset_test_traits { using event_reader_type = cbor::cbor_event_reader; // binary_stream_source::char_type is actually char, not uint8_t using input_type = std::istringstream; static void set_input(input_type& input, std::vector bytes) { auto data = reinterpret_cast(bytes.data()); std::string s(data, bytes.size()); input.str(s); } }; TEMPLATE_TEST_CASE("cbor_event_reader reset test", "", cbor_bytes_cursor2_reset_test_traits, cbor_stream_cursor2_reset_test_traits) { using traits = TestType; using input_type = typename traits::input_type; using event_reader_type = typename traits::event_reader_type; using source_type = typename event_reader_type::source_type; SECTION("keeping same source") { std::error_code ec; input_type input; traits::set_input(input, { 0x63, 0x54, 0x6f, 0x6d, // text(3), "Tom" 0x38, 0x63, // negative(99) 0xf6 // null }); source_type source(input); event_reader_type reader(std::move(source)); REQUIRE_FALSE(reader.done()); CHECK(reader.current().event_type() == staj_event_type::string_value); CHECK(reader.current().tag() == semantic_tag::none); CHECK(reader.current().template get() == std::string("Tom")); CHECK(reader.current().template get() == jsoncons::string_view("Tom")); reader.next(); CHECK(reader.done()); reader.reset(); REQUIRE_FALSE(reader.done()); CHECK(reader.current().event_type() == staj_event_type::int64_value); CHECK(reader.current().tag() == semantic_tag::none); CHECK(reader.current().template get() == -100); reader.next(); CHECK(reader.done()); reader.reset(ec); REQUIRE_FALSE(ec); REQUIRE_FALSE(reader.done()); CHECK(reader.current().event_type() == staj_event_type::null_value); CHECK(reader.current().tag() == semantic_tag::none); reader.next(ec); REQUIRE_FALSE(ec); CHECK(reader.done()); } SECTION("with another source") { std::error_code ec; input_type input0; input_type input1; input_type input2; input_type input3; traits::set_input(input0, {}); traits::set_input(input1, {0x63, 0x54, 0x6f, 0x6d}); // text(3), "Tom" traits::set_input(input2, {0xe0}); // invalid special traits::set_input(input3, {0x38, 0x63}); // negative(99) // Constructing reader with blank input results in unexpected_eof // error because it eagerly parses the next event upon construction. event_reader_type reader(input0, ec); CHECK(ec == cbor::cbor_errc::unexpected_eof); CHECK_FALSE(reader.done()); // Reset to valid input1 reader.reset(input1); CHECK(reader.current().event_type() == staj_event_type::string_value); CHECK(reader.current().tag() == semantic_tag::none); CHECK(reader.current().template get() == std::string("Tom")); CHECK(reader.current().template get() == jsoncons::string_view("Tom")); ec = cbor::cbor_errc::success; REQUIRE_FALSE(reader.done()); reader.next(ec); CHECK_FALSE(ec); CHECK(reader.done()); // Reset to invalid input2 reader.reset(input2, ec); CHECK(ec == cbor::cbor_errc::unknown_type); CHECK_FALSE(reader.done()); // Reset to valid input3 ec = cbor::cbor_errc::success; reader.reset(input3, ec); REQUIRE_FALSE(ec); CHECK(reader.current().event_type() == staj_event_type::int64_value); CHECK(reader.current().tag() == semantic_tag::none); CHECK(reader.current().template get() == -100); REQUIRE_FALSE(reader.done()); reader.next(ec); CHECK_FALSE(ec); CHECK(reader.done()); } } jsoncons-1.3.2/test/cbor/src/cbor_event_visitor_tests.cpp000066400000000000000000000267431477700171100237200ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" #endif #include #include #include #include #include #include #include #include #include using namespace jsoncons; class my_json_visitor : public default_json_visitor { JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag, const ser_context&, std::error_code&) override { std::cout << "visit_begin_object\n"; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context&, std::error_code&) override { std::cout << "visit_end_object\n"; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag, const ser_context&, std::error_code&) override { std::cout << "visit_begin_array\n"; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context&, std::error_code&) override { std::cout << "visit_end_array\n"; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type& s, const ser_context&, std::error_code&) override { std::cout << "visit_key " << s << "\n"; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& s, semantic_tag, const ser_context&, std::error_code&) override { std::cout << "visit_string " << s << "\n"; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t val, semantic_tag, const ser_context&, std::error_code&) override { std::cout << "visit_int64 " << val << "\n"; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t val, semantic_tag, const ser_context&, std::error_code&) override { std::cout << "visit_uint64 " << val << "\n"; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool val, semantic_tag, const ser_context&, std::error_code&) override { std::cout << "visit_bool " << val << "\n"; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const span& s, semantic_tag tag, const ser_context&, std::error_code&) override { std::cout << "visit_typed_array uint16_t " << tag << "\n"; for (auto val : s) { std::cout << val << "\n"; } std::cout << "\n"; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(half_arg_t, const span& s, semantic_tag tag, const ser_context&, std::error_code&) override { std::cout << "visit_typed_array half_arg_t uint16_t " << tag << "\n"; for (auto val : s) { std::cout << val << "\n"; } std::cout << "\n"; JSONCONS_VISITOR_RETURN; } }; TEST_CASE("item_event_visitor cbor 1") { std::vector input = {0xa2, 0xa1, // object (1), key 0x62,'o','c', // string, key 0x81,0, // array(1), value 0x61, 'a', // string(1), value 0xa0, // object(0), key 0 // value }; json expected = json::parse(R"( {"{\"oc\":[0]}":"a","{}":0} )"); SECTION("test 1") { json_decoder destination; item_event_visitor_to_visitor_adaptor visitor{destination}; cbor::basic_cbor_parser parser{ bytes_source(input) }; std::error_code ec; parser.parse(visitor, ec); CHECK(expected == destination.get_result()); } } TEST_CASE("item_event_visitor cbor 2") { std::vector input = {0xa2, 0xa2, // object (2), key 0x62,'a','a', // string, key 0x81,0, // array(1), value 0x62,'b','b', // string, key 0x81,1, // array(1), value 0x61, 'a', // string(1), value 0xa0, // object(0), key 0 // value }; json expected = json::parse(R"( {"{\"aa\":[0],\"bb\":[1]}":"a","{}":0} )"); SECTION("test 1") { json_decoder destination; item_event_visitor_to_visitor_adaptor visitor{destination}; cbor::basic_cbor_parser parser{ bytes_source(input) }; std::error_code ec; parser.parse(visitor, ec); //std::cout << destination.get_result() << "\n"; CHECK(expected == destination.get_result()); } } TEST_CASE("item_event_visitor cbor 3") { std::vector input = {0xa2, 0xa2, // object (2), key 0x62,'a','a', // string, key 0x81,0, // array(1), value 0xa0, // string, key 0x81,1, // array(1), value 0x61, 'a', // string(1), value 0xa0, // object(0), key 0 // value }; json expected = json::parse(R"( {"{\"aa\":[0],{}:[1]}":"a","{}":0} )"); SECTION("test 1") { json_decoder destination; item_event_visitor_to_visitor_adaptor visitor{destination}; cbor::basic_cbor_parser parser{ bytes_source(input) }; std::error_code ec; parser.parse(visitor, ec); //std::cout << destination.get_result() << "\n"; CHECK(expected == destination.get_result()); } } TEST_CASE("item_event_visitor cbor 4") { std::vector input = {0xa2, 0xa2, // object (2), key 0x62,'a','a', // string, key 0x81,0, // array(1), value 0x80, // array, key 0x81,1, // array(1), value 0x61, 'a', // string(1), value 0xa0, // object(0), key 0 // value }; json expected = json::parse(R"( {"{\"aa\":[0],[]:[1]}":"a","{}":0} )"); SECTION("test 1") { json_decoder destination; item_event_visitor_to_visitor_adaptor visitor{destination}; cbor::basic_cbor_parser parser{ bytes_source(input) }; std::error_code ec; parser.parse(visitor, ec); //std::cout << destination.get_result() << "\n"; CHECK(expected == destination.get_result()); } } TEST_CASE("item_event_visitor cbor 5") { std::vector input = {0xa2, 0x84, // array(4), key 0, 1, 2, 3, 0x61, 'a', // string(1), value 0x80, // array(0), key 0 // value }; json expected = json::parse(R"( {"[0,1,2,3]":"a","[]":0} )"); SECTION("test 1") { json_decoder destination; item_event_visitor_to_visitor_adaptor visitor{destination}; cbor::basic_cbor_parser parser{ bytes_source(input) }; std::error_code ec; parser.parse(visitor, ec); //std::cout << destination.get_result() << "\n"; CHECK(expected == destination.get_result()); } } TEST_CASE("item_event_visitor cbor 6") { const std::vector input = { 0x9f, // Start indefinte length array 0x83, // Array of length 3 0x63, // String value of length 3 0x66,0x6f,0x6f, // "foo" 0x44, // Byte string value of length 4 0x50,0x75,0x73,0x73, // 'P''u''s''s' 0xc5, // Tag 5 (bigfloat) 0x82, // Array of length 2 0x20, // -1 0x03, // 3 0x83, // Another array of length 3 0x63, // String value of length 3 0x62,0x61,0x72, // "bar" 0xd6, // Expected conversion to base64 0x44, // Byte string value of length 4 0x50,0x75,0x73,0x73, // 'P''u''s''s' 0xc4, // Tag 4 (decimal fraction) 0x82, // Array of length 2 0x38, // Negative integer of length 1 0x1c, // -29 0xc2, // Tag 2 (positive bignum) 0x4d, // Byte string value of length 13 0x01,0x8e,0xe9,0x0f,0xf6,0xc3,0x73,0xe0,0xee,0x4e,0x3f,0x0a,0xd2, 0xff // "break" }; SECTION("test 1") { json_decoder destination; item_event_visitor_to_visitor_adaptor visitor{destination}; cbor::basic_cbor_parser parser{ bytes_source(input) }; std::error_code ec; parser.parse(visitor, ec); //std::cout << destination.get_result() << "\n"; } SECTION("test 2") { auto j1 = cbor::decode_cbor(input); auto val = cbor::decode_cbor>>(input); // Serialize back to CBOR std::vector buffer; cbor::encode_cbor(val, buffer); json j2 = cbor::decode_cbor(buffer); CHECK(j2 == j1); } } TEST_CASE("cbor_parser reset") { std::vector input1 = { 0x82,0x01,0x02, // array(2), unsigned(1), unsigned(2) 0xa1,0x61,0x63,0x04, // map(1), text(1), "c", unsigned(4) }; std::vector input2 = { 0xa1,0x61,0x65,0x06, // map(1), text(1), "e", unsigned(6) }; json expected1 = json::parse(R"([1,2])"); json expected2 = json::parse(R"({"c":4})"); json expected3 = json::parse(R"({"e":6})"); json_decoder destination; item_event_visitor_to_visitor_adaptor visitor{destination}; cbor::basic_cbor_parser parser{ input1 }; std::error_code ec; SECTION("keeping same source") { parser.parse(visitor, ec); REQUIRE_FALSE(ec); CHECK(destination.get_result() == expected1); destination.reset(); parser.reset(); parser.parse(visitor, ec); CHECK_FALSE(ec); CHECK(parser.stopped()); // TODO: This fails: CHECK(parser.done()); CHECK(destination.get_result() == expected2); } SECTION("with different source") { parser.parse(visitor, ec); REQUIRE_FALSE(ec); CHECK(destination.get_result() == expected1); destination.reset(); parser.reset(input2); parser.parse(visitor, ec); CHECK_FALSE(ec); CHECK(parser.stopped()); // TODO: This fails: CHECK(parser.done()); CHECK(destination.get_result() == expected3); } } jsoncons-1.3.2/test/cbor/src/cbor_reader_tests.cpp000066400000000000000000000720471477700171100222600ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" #endif #include #include #include #include #include #include #include #include #include using namespace jsoncons; using namespace jsoncons::cbor; void check_parse_cbor(const std::vector& v, const json& expected) { JSONCONS_TRY { std::error_code ec; jsoncons::json_decoder decoder; cbor_bytes_reader reader(v, decoder); reader.read(ec); json result = decoder.get_result(); if (!(result == expected)) { std::cout << "v: "; for (auto b : v) { std::cout << "0x" << std::hex << (int)b; } std::cout << "\n"; std::cout << "result: " << result << "\n"; std::cout << "expected: " << expected << "\n"; } REQUIRE(result == expected); CHECK(result.tag() == expected.tag()); std::string s; for (auto c : v) { s.push_back(c); } std::istringstream is(s); json j2 = decode_cbor(is); REQUIRE(j2 == expected); } JSONCONS_CATCH (const std::exception& e) { std::cout << e.what() << '\n'; std::cout << expected.to_string() << '\n'; } } TEST_CASE("test_cbor_parsing") { // unsigned integer check_parse_cbor({0x00},json(0U)); check_parse_cbor({0x01},json(1U)); check_parse_cbor({0x0a},json(10U)); check_parse_cbor({0x17},json(23U)); check_parse_cbor({0x18,0x18},json(24U)); check_parse_cbor({0x18,0xff},json(255U)); check_parse_cbor({0x19,0x01,0x00},json(256U)); check_parse_cbor({0x19,0xff,0xff},json(65535U)); check_parse_cbor({0x1a,0,1,0x00,0x00},json(65536U)); check_parse_cbor({0x1a,0xff,0xff,0xff,0xff},json(4294967295U)); check_parse_cbor({0x1b,0,0,0,1,0,0,0,0},json(4294967296U)); check_parse_cbor({0x1b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},json((std::numeric_limits::max)())); // positive signed integer check_parse_cbor({0x00},json(0)); check_parse_cbor({0x01},json(1)); check_parse_cbor({0x0a},json(10)); check_parse_cbor({0x17},json(23)); check_parse_cbor({0x18,0x18},json(24)); check_parse_cbor({0x18,0xff},json(255)); check_parse_cbor({0x19,0x01,0x00},json(256)); check_parse_cbor({0x19,0xff,0xff},json(65535)); check_parse_cbor({0x1a,0,1,0x00,0x00},json(65536)); check_parse_cbor({0x1a,0xff,0xff,0xff,0xff},json(4294967295)); check_parse_cbor({0x1b,0,0,0,1,0,0,0,0},json(4294967296)); check_parse_cbor({0x1b,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff},json((std::numeric_limits::max)())); // negative integers check_parse_cbor({0x20},json(-1)); check_parse_cbor({0x21},json(-2)); check_parse_cbor({0x37},json(-24)); check_parse_cbor({0x38,0x18},json(-25)); check_parse_cbor({0x38,0xff},json(-256)); check_parse_cbor({0x39,0x01,0x00},json(-257)); check_parse_cbor({0x39,0xff,0xff},json(-65536)); check_parse_cbor({0x3a,0,1,0x00,0x00},json(-65537)); check_parse_cbor({0x3a,0xff,0xff,0xff,0xff},json(-4294967296)); check_parse_cbor({0x3b,0,0,0,1,0,0,0,0},json(-4294967297)); // null, undefined, true, false check_parse_cbor({0xf6},json::null()); check_parse_cbor({0xf7},json{null_type(),semantic_tag::undefined}); check_parse_cbor({0xf5},json(true)); check_parse_cbor({0xf4},json(false)); // floating point check_parse_cbor({0xfb,0,0,0,0,0,0,0,0},json(0.0)); check_parse_cbor({0xfb,0xbf,0xf0,0,0,0,0,0,0},json(-1.0)); check_parse_cbor({0xfb,0xc1,0x6f,0xff,0xff,0xe0,0,0,0},json(-16777215.0)); check_parse_cbor({0xfa,0xcb,0x7f,0xff,0xff},json(-16777215.0)); // byte string std::vector v; check_parse_cbor({0x40},json(byte_string_view(v))); v = {' '}; check_parse_cbor({0x41,' '},json(byte_string_view(v))); v = {0}; check_parse_cbor({0x41,0},json(byte_string_view(v))); v = {'H','e','l','l','o'}; check_parse_cbor({0x45,'H','e','l','l','o'},json(byte_string_view(v))); v = {'1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4'}; check_parse_cbor({0x58,0x18,'1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4'}, json(byte_string_view(v))); // string check_parse_cbor({0x60},json("")); check_parse_cbor({0x61,' '},json(" ")); check_parse_cbor({0x78,0x18,'1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4'}, json("123456789012345678901234")); // byte strings with undefined length check_parse_cbor({0x5f,0xff}, json(byte_string())); check_parse_cbor({0x5f,0x40,0xff}, json(byte_string())); check_parse_cbor({0x5f,0x40,0x40,0xff}, json(byte_string())); check_parse_cbor({0x5f,0x43,'H','e','l',0x42,'l','o',0xff}, json(byte_string({'H','e','l','l','o'}))); check_parse_cbor({0x5f,0x41,'H',0x41,'e',0x41,'l',0x41,'l',0x41,'o',0xff}, json(byte_string({'H','e','l','l','o'}))); check_parse_cbor({0x5f,0x41,'H',0x41,'e',0x40,0x41,'l',0x41,'l',0x41,'o',0xff}, json(byte_string({'H','e','l','l','o'}))); // text strings with undefined length check_parse_cbor({0x7f,0x7f,0x65,'H','e','l','l','o',0x7f,0x61,' ',0x60,0xff,0x65,'W','o','r','l','d',0xff,0xff},json("Hello World")); check_parse_cbor({0x7f,0xff}, json("")); check_parse_cbor({0x7f,0x60,0xff}, json("")); check_parse_cbor({0x7f,0x60,0x60,0xff}, json("")); check_parse_cbor({0x7f,0x63,'H','e','l',0x62,'l','o',0xff}, json("Hello")); check_parse_cbor({0x7f,0x61,'H',0x61,'e',0x61,'l',0x61,'l',0x61,'o',0xff}, json("Hello")); check_parse_cbor({0x7f,0x61,'H',0x61,'e',0x61,'l',0x60,0x61,'l',0x61,'o',0xff}, json("Hello")); SECTION ("arrays with definite length") { check_parse_cbor({0x80}, json(json_array_arg)); check_parse_cbor({0x81,'\0'},json::parse("[0]")); check_parse_cbor({0x82,'\0','\0'}, json(json_array_arg, {0,0})); check_parse_cbor({0x82,0x81,'\0','\0'}, json::parse("[[0],0]")); check_parse_cbor({0x81,0x65,'H','e','l','l','o'},json::parse("[\"Hello\"]")); check_parse_cbor({0x83,0x01,0x82,0x02,0x03,0x82,0x04,0x05},json::parse("[1, [2, 3], [4, 5]]")); check_parse_cbor({0x82, 0x7f,0xff, 0x7f,0xff}, json::parse("[\"\",\"\"]")); check_parse_cbor({0x82, 0x5f,0xff, 0x5f,0xff}, json(json_array_arg, {json(byte_string()),json(byte_string())})); } SECTION("arrays with indefinite length") { //check_parse_cbor({0x9f,0xff}, json(json_array_arg)); check_parse_cbor({0x9f,0x9f,0xff,0xff},json::parse("[[]]")); check_parse_cbor({0x9f,0x01,0x82,0x02,0x03,0x9f,0x04,0x05,0xff,0xff},json::parse("[1, [2, 3], [4, 5]]")); check_parse_cbor({0x9f,0x01,0x82,0x02,0x03,0x82,0x04,0x05,0xff},json::parse("[1, [2, 3], [4, 5]]")); check_parse_cbor({0x83,0x01,0x82,0x02,0x03,0x9f,0x04,0x05,0xff},json::parse("[1, [2, 3], [4, 5]]")); check_parse_cbor({0x83, // Array of length 3 0x01, // 1 0x9f, // Start indefinite-length array 0x02, // 2 0x03, // 3 0xff, // "break" 0x82, // Array of length 2 0x04, // 4 0x05}, // 5 json::parse("[1, [2, 3], [4, 5]]")); } // big float check_parse_cbor({0xc5, // Tag 5 0x82, // Array of length 2 0x21, // -2 0x19, 0x6a, 0xb3 // 27315 },json("0x6AB3p-2",semantic_tag::bigfloat)); SECTION("maps with definite length") { //check_parse_cbor({0xa0}, json(json_object_arg)); check_parse_cbor({0xa1,0x62,'o','c',0x81,'\0'}, json::parse("{\"oc\": [0]}")); //check_parse_cbor({0xa1,0x62,'o','c',0x84,'\0','\1','\2','\3'}, json::parse("{\"oc\": [0, 1, 2, 3]}")); } SECTION("maps with indefinite length") { check_parse_cbor({0xbf,0xff}, json(json_object_arg)); check_parse_cbor({0xbf,0x64,'N','a','m','e',0xbf,0xff,0xff},json::parse("{\"Name\":{}}")); check_parse_cbor({0xbf, // Start indefinite-length map 0x63, // First key, UTF-8 string length 3 0x46,0x75,0x6e, // "Fun" 0xf5, // First value, true 0x63, // Second key, UTF-8 string length 3 0x41,0x6d,0x74, // "Amt" 0x21, // -2 0xff}, // "break" json::parse("{\"Fun\": true, \"Amt\": -2}")); check_parse_cbor({0xbf, // Start indefinite-length map 0x21, // First key, -2 0xf5, // First value, true 0xf5, // Second key, UTF-8 string length 3 0x21, // -2 0xff}, // "break" json::parse("{\"-2\": true, \"true\": -2}")); } SECTION("maps with non-string keys") { check_parse_cbor({0xbf, // Start indefinite-length map 0x21, // First key, -2 0xf5, // First value, true 0xf5, // Second key, UTF-8 string length 3 0x21, // -2 0xff}, // "break" json::parse("{\"-2\": true, \"true\": -2}")); } // bignum std::vector data = { 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; check_parse_cbor({0xc2,0x49,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, json(bigint::from_bytes_be(1, data.data(),data.size()))); // datetime check_parse_cbor({0xc0,0x78,0x19,'2','0','1','5','-','0','5','-','0','7',' ','1','2',':','4','1',':','0','7','-','0','7',':','0','0'}, json("2015-05-07 12:41:07-07:00", semantic_tag::datetime)); // seconds check_parse_cbor({0xc1,0x1a,0x55,0x4b,0xbf,0xd3}, json(1431027667, semantic_tag::epoch_second)); } TEST_CASE("cbor decimal fraction") { check_parse_cbor({0xc4, // Tag 4 0x82, // Array of length 2 0x21, // -2 0x19,0x6a,0xb3 // 27315 }, json("273.15", semantic_tag::bigdec)); check_parse_cbor({0xc4, // Tag 4 0x82, // Array of length 2 0x22, // -3 0x19,0x6a,0xb3 // 27315 }, json("27.315", semantic_tag::bigdec)); check_parse_cbor({0xc4, // Tag 4 0x82, // Array of length 2 0x23, // -4 0x19,0x6a,0xb3 // 27315 }, json("2.7315", semantic_tag::bigdec)); check_parse_cbor({0xc4, // Tag 4 0x82, // Array of length 2 0x24, // -5 0x19,0x6a,0xb3 // 27315 }, json("0.27315", semantic_tag::bigdec)); check_parse_cbor({0xc4, // Tag 4 0x82, // Array of length 2 0x25, // -6 0x19,0x6a,0xb3 // 27315 }, json("0.027315", semantic_tag::bigdec)); check_parse_cbor({0xc4, // Tag 4 0x82, // Array of length 2 0x04, // 4 0x19,0x6a,0xb3 // 27315 }, json("273150000.0", semantic_tag::bigdec)); } TEST_CASE("test_decimal_as_string") { SECTION("-2 27315") { std::vector v = {0xc4, // Tag 4, 0x82, // Array of length 2 0x21, // -2 0x19,0x6a,0xb3 // 27315 }; json j = decode_cbor(v); CHECK(j.as() == std::string("273.15")); } SECTION("-6 27315") { std::vector v = {0xc4, // Tag 4, 0x82, // Array of length 2 0x25, // -6 0x19,0x6a,0xb3 // 27315 }; json j = decode_cbor(v); CHECK(j.as() == std::string("0.027315")); } SECTION("-5 27315") { std::vector v = {0xc4, // Tag 4, 0x82, // Array of length 2 0x24, // -5 0x19,0x6a,0xb3 // 27315 }; json j = decode_cbor(v); CHECK(j.as() == std::string("0.27315")); } SECTION("0 27315") { std::vector v = {0xc4, // Tag 4, 0x82, // Array of length 2 0x00, // 0 0x19,0x6a,0xb3 // 27315 }; json j = decode_cbor(v); CHECK(j.as() == std::string("27315.0")); } SECTION("2 27315") { std::vector v = {0xc4, // Tag 4, 0x82, // Array of length 2 0x02, // 2 0x19,0x6a,0xb3 // 27315 }; json j = decode_cbor(v); CHECK(j.as() == std::string("2731500.0")); } SECTION("-2 18446744073709551616") { std::vector v = {0xc4, // Tag 4, 0x82, // Array of length 2 0x21, // -2 0xc2,0x49,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 // 18446744073709551616 }; json j = decode_cbor(v); CHECK(j.as() == std::string("1.8446744073709551616e+17")); } SECTION("-2 -65537") { std::vector v = {0xc4, // Tag 4, 0x82, // Array of length 2 0x21, // -2 0x3a,0,1,0x00,0x00 // -65537 }; json j = decode_cbor(v); CHECK(j.as() == std::string("-655.37")); } SECTION("-5 -65537") { std::vector v = {0xc4, // Tag 4, 0x82, // Array of length 2 0x24, // -5 0x3a,0,1,0x00,0x00 // -65537 }; json j = decode_cbor(v); CHECK(j.as() == std::string("-0.65537")); } SECTION("-6 -65537") { std::vector v = {0xc4, // Tag 4, 0x82, // Array of length 2 0x25, // -6 0x3a,0,1,0x00,0x00 // -65537 }; json j = decode_cbor(v); CHECK(j.as() == std::string("-0.065537")); } } TEST_CASE("Compare CBOR packed item and jsoncons item") { std::vector bytes; cbor::cbor_bytes_encoder encoder(bytes); encoder.begin_array(); // indefinite length outer array encoder.string_value("foo"); encoder.byte_string_value(byte_string{'b','a','r'}); encoder.string_value("-18446744073709551617", semantic_tag::bigint); encoder.string_value("-273.15", semantic_tag::bigdec); encoder.string_value("273.15", semantic_tag::bigdec); encoder.string_value("18446744073709551616.15", semantic_tag::bigdec); encoder.string_value("-18446744073709551617.15", semantic_tag::bigdec); encoder.string_value("2018-10-19 12:41:07-07:00", semantic_tag::datetime) ; encoder.int64_value(1431027667, semantic_tag::epoch_second); encoder.int64_value(-1431027667, semantic_tag::epoch_second); encoder.double_value(1431027667.5, semantic_tag::epoch_second); encoder.end_array(); encoder.flush(); json expected(json_array_arg); expected.emplace_back("foo"); expected.emplace_back(byte_string{ 'b','a','r' }); expected.emplace_back("-18446744073709551617", semantic_tag::bigint); expected.emplace_back("-273.15", semantic_tag::bigdec); expected.emplace_back("273.15", semantic_tag::bigdec); expected.emplace_back("1.844674407370955161615e+19", semantic_tag::bigdec); expected.emplace_back("-1.844674407370955161715e+19", semantic_tag::bigdec); expected.emplace_back("2018-10-19 12:41:07-07:00", semantic_tag::datetime); expected.emplace_back(1431027667, semantic_tag::epoch_second); expected.emplace_back(-1431027667, semantic_tag::epoch_second); expected.emplace_back(1431027667.5, semantic_tag::epoch_second); json j = cbor::decode_cbor(bytes); REQUIRE(expected == j); for (std::size_t i = 0; i < j.size(); ++i) { CHECK(j[i].tag() == expected[i].tag()); } } TEST_CASE("CBOR stringref tag 1") { std::vector v = {0xd9,0x01,0x00, // tag(256) 0x83, // array(3) 0xa3, // map(3) 0x44, // bytes(4) 0x72,0x61,0x6e,0x6b, // "rank" 0x04, // unsigned(4) 0x45, // bytes(5) 0x63,0x6f,0x75,0x6e,0x74, // "count" 0x19,0x01,0xa1, // unsigned(417) 0x44, // bytes(4) 0x6e,0x61,0x6d,0x65, // "name" 0x48, // bytes(8) 0x43,0x6f,0x63,0x6b,0x74,0x61,0x69,0x6c, // "Cocktail" 0xa3, // map(3) 0xd8,0x19, // tag(25) 0x02, // unsigned(2) 0x44, // bytes(4) 0x42,0x61,0x74,0x68, // "Bath" 0xd8,0x19, // tag(25) 0x01, // unsigned(1) 0x19,0x01,0x38, // unsigned(312) 0xd8,0x19, // tag(25) 0x00, // unsigned(0) 0x04, // unsigned(4) 0xa3, // map(3) 0xd8,0x19, // tag(25) 0x02, // unsigned(2) 0x44, // bytes(4) 0x46,0x6f,0x6f,0x64, // "Food" 0xd8,0x19, // tag(25) 0x01, // unsigned(1) 0x19,0x02,0xb3, // unsigned(691) 0xd8,0x19, // tag(25) 0x00, // unsigned(0) 0x04 // unsigned(4) }; SECTION("decode") { ojson j = decode_cbor(v); //std::cout << pretty_print(j) << "\n"; { auto it = j[0].object_range().begin(); std::string key1; decode_base64url(it->key().begin(),it->key().end(),key1); CHECK(key1 == std::string("rank")); ++it; std::string key2; decode_base64url(it->key().begin(),it->key().end(),key2); CHECK(key2 == std::string("count")); ++it; std::string key3; decode_base64url(it->key().begin(),it->key().end(),key3); CHECK(key3 == std::string("name")); } { auto it = j[1].object_range().begin(); std::string key3; decode_base64url(it->key().begin(),it->key().end(),key3); CHECK(key3 == std::string("name")); ++it; std::string key2; decode_base64url(it->key().begin(),it->key().end(),key2); CHECK(key2 == std::string("count")); ++it; std::string key1; decode_base64url(it->key().begin(),it->key().end(),key1); CHECK(key1 == std::string("rank")); } { auto it = j[2].object_range().begin(); std::string key3; decode_base64url(it->key().begin(),it->key().end(),key3); CHECK(key3 == std::string("name")); ++it; std::string key2; decode_base64url(it->key().begin(),it->key().end(),key2); CHECK(key2 == std::string("count")); ++it; std::string key1; decode_base64url(it->key().begin(),it->key().end(),key1); CHECK(key1 == std::string("rank")); } } } TEST_CASE("CBOR stringref tag 2") { std::vector v = {0xd9, 0x01, 0x00, // tag(256) 0x98, 0x20, // array(32) 0x41, // bytes(1) 0x31, // "1" 0x43, // bytes(3) 0x32,0x32,0x32, // "222" 0x43, // bytes(3) 0x33,0x33,0x33, // "333" 0x41, // bytes(1) 0x34, // "4" 0x43, // bytes(3) 0x35,0x35,0x35, // "555" 0x43, // bytes(3) 0x36,0x36,0x36, // "666" 0x43, // bytes(3) 0x37,0x37,0x37, // "777" 0x43, // bytes(3) 0x38,0x38,0x38, // "888" 0x43, // bytes(3) 0x39,0x39,0x39, // "999" 0x43, // bytes(3) 0x61,0x61,0x61, // "aaa" 0x43, // bytes(3) 0x62,0x62,0x62, // "bbb" 0x43, // bytes(3) 0x63,0x63,0x63, // "ccc" 0x43, // bytes(3) 0x64,0x64,0x64, // "ddd" 0x43, // bytes(3) 0x65,0x65,0x65, // "eee" 0x43, // bytes(3) 0x66,0x66,0x66, // "fff" 0x43, // bytes(3) 0x67,0x67,0x67, // "ggg" 0x43, // bytes(3) 0x68,0x68,0x68, // "hhh" 0x43, // bytes(3) 0x69,0x69,0x69, // "iii" 0x43, // bytes(3) 0x6a,0x6a,0x6a, // "jjj" 0x43, // bytes(3) 0x6b,0x6b,0x6b, // "kkk" 0x43, // bytes(3) 0x6c,0x6c,0x6c, // "lll" 0x43, // bytes(3) 0x6d,0x6d,0x6d, // "mmm" 0x43, // bytes(3) 0x6e,0x6e,0x6e, // "nnn" 0x43, // bytes(3) 0x6f,0x6f,0x6f, // "ooo" 0x43, // bytes(3) 0x70,0x70,0x70, // "ppp" 0x43, // bytes(3) 0x71,0x71,0x71, // "qqq" 0x43, // bytes(3) 0x72,0x72,0x72, // "rrr" 0xd8, 0x19, // tag(25) 0x01, // unsigned(1) 0x44, // bytes(4) 0x73,0x73,0x73,0x73, // "ssss" 0xd8, 0x19, // tag(25) 0x17, // unsigned(23) 0x43, // bytes(3) 0x72,0x72,0x72, // "rrr" 0xd8, 0x19, // tag(25) 0x18, 0x18 // unsigned(24) }; ojson j = decode_cbor(v); byte_string bytes = j[0].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("1")); bytes = j[1].as(); // 0 CHECK(std::string(bytes.begin(),bytes.end()) == std::string("222")); bytes = j[2].as(); // 1 CHECK(std::string(bytes.begin(),bytes.end()) == std::string("333")); bytes = j[3].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("4")); bytes = j[4].as(); // 2 CHECK(std::string(bytes.begin(),bytes.end()) == std::string("555")); bytes = j[5].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("666")); bytes = j[6].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("777")); bytes = j[7].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("888")); bytes = j[8].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("999")); bytes = j[9].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("aaa")); bytes = j[10].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("bbb")); bytes = j[11].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("ccc")); bytes = j[12].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("ddd")); bytes = j[13].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("eee")); bytes = j[14].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("fff")); bytes = j[15].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("ggg")); bytes = j[16].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("hhh")); bytes = j[17].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("iii")); bytes = j[18].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("jjj")); bytes = j[19].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("kkk")); bytes = j[20].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("lll")); bytes = j[21].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("mmm")); bytes = j[22].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("nnn")); bytes = j[23].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("ooo")); bytes = j[24].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("ppp")); bytes = j[25].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("qqq")); bytes = j[26].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("rrr")); bytes = j[27].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("333")); bytes = j[28].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("ssss")); bytes = j[29].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("qqq")); bytes = j[30].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("rrr")); bytes = j[31].as(); CHECK(std::string(bytes.begin(),bytes.end()) == std::string("ssss")); } TEST_CASE("CBOR stringref tag 3") { std::vector v = {0xd9,0x01,0x00, // tag(256) 0x85, // array(5) 0x63, // text(3) 0x61,0x61,0x61, // "aaa" 0xd8, 0x19, // tag(25) 0x00, // unsigned(0) 0xd9, 0x01,0x00, // tag(256) 0x83, // array(3) 0x63, // text(3) 0x62,0x62,0x62, // "bbb" 0x63, // text(3) 0x61,0x61,0x61, // "aaa" 0xd8, 0x19, // tag(25) 0x01, // unsigned(1) 0xd9, 0x01,0x00, // tag(256) 0x82, // array(2) 0x63, // text(3) 0x63,0x63,0x63, // "ccc" 0xd8, 0x19, // tag(25) 0x00, // unsigned(0) 0xd8, 0x19, // tag(25) 0x00 // unsigned(0) }; json j = cbor::decode_cbor(v); json expected = json::parse(R"( ["aaa","aaa",["bbb","aaa","aaa"],["ccc","ccc"],"aaa"] )"); CHECK(expected == j); } jsoncons-1.3.2/test/cbor/src/cbor_tests.cpp000066400000000000000000000173751477700171100207410ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" #endif #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("cbor_test_floating_point") { json j1; j1["max double"] = (std::numeric_limits::max)(); j1["max float"] = (std::numeric_limits::max)(); std::vector v; cbor::encode_cbor(j1, v); json j2 = cbor::decode_cbor(v); CHECK(j2 == j1); json j3 = cbor::decode_cbor(v.begin(), v.end()); CHECK(j3 == j1); } TEST_CASE("cbor_test") { json j1; j1["zero"] = 0; j1["one"] = 1; j1["two"] = 2; j1["null"] = null_type(); j1["true"] = true; j1["false"] = false; j1["max int64_t"] = (std::numeric_limits::max)(); j1["max uint64_t"] = (std::numeric_limits::max)(); j1["min int64_t"] = (std::numeric_limits::lowest)(); j1["max int32_t"] = (std::numeric_limits::max)(); j1["max uint32_t"] = (std::numeric_limits::max)(); j1["min int32_t"] = (std::numeric_limits::lowest)(); j1["max int16_t"] = (std::numeric_limits::max)(); j1["max uint16_t"] = (std::numeric_limits::max)(); j1["min int16_t"] = (std::numeric_limits::lowest)(); j1["max int8_t"] = (std::numeric_limits::max)(); j1["max uint8_t"] = (std::numeric_limits::max)(); j1["min int8_t"] = (std::numeric_limits::lowest)(); j1["max double"] = (std::numeric_limits::max)(); j1["min double"] = (std::numeric_limits::lowest)(); j1["max float"] = (std::numeric_limits::max)(); j1["zero float"] = 0.0; j1["min float"] = (std::numeric_limits::lowest)(); j1["String too long for small string optimization"] = "String too long for small string optimization"; json ja(json_array_arg); ja.push_back(0); ja.push_back(1); ja.push_back(2); ja.push_back(null_type()); ja.push_back(true); ja.push_back(false); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::lowest)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::lowest)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::lowest)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::lowest)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::lowest)()); ja.push_back((std::numeric_limits::max)()); ja.push_back(0.0); ja.push_back((std::numeric_limits::lowest)()); ja.push_back("String too long for small string optimization"); j1["An array"] = ja; std::vector v; cbor::encode_cbor(j1, v); json j2 = cbor::decode_cbor(v); CHECK(j2 == j1); json j3 = cbor::decode_cbor(v.begin(), v.end()); CHECK(j3 == j1); } TEST_CASE("cbor_test2") { wjson j1; j1[L"zero"] = 0; j1[L"one"] = 1; j1[L"two"] = 2; j1[L"null"] = null_type(); j1[L"true"] = true; j1[L"false"] = false; j1[L"max int64_t"] = (std::numeric_limits::max)(); j1[L"max uint64_t"] = (std::numeric_limits::max)(); j1[L"min int64_t"] = (std::numeric_limits::lowest)(); j1[L"max int32_t"] = (std::numeric_limits::max)(); j1[L"max uint32_t"] = (std::numeric_limits::max)(); j1[L"min int32_t"] = (std::numeric_limits::lowest)(); j1[L"max int16_t"] = (std::numeric_limits::max)(); j1[L"max uint16_t"] = (std::numeric_limits::max)(); j1[L"min int16_t"] = (std::numeric_limits::lowest)(); j1[L"max int8_t"] = (std::numeric_limits::max)(); j1[L"max uint8_t"] = (std::numeric_limits::max)(); j1[L"min int8_t"] = (std::numeric_limits::lowest)(); j1[L"max double"] = (std::numeric_limits::max)(); j1[L"min double"] = (std::numeric_limits::lowest)(); j1[L"max float"] = (std::numeric_limits::max)(); j1[L"zero float"] = 0.0; j1[L"min float"] = (std::numeric_limits::lowest)(); j1[L"S"] = L"S"; j1[L"String too long for small string optimization"] = L"String too long for small string optimization"; wjson ja(json_array_arg); ja.push_back(0); ja.push_back(1); ja.push_back(2); ja.push_back(null_type()); ja.push_back(true); ja.push_back(false); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::lowest)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::lowest)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::lowest)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::lowest)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::lowest)()); ja.push_back((std::numeric_limits::max)()); ja.push_back(0.0); ja.push_back((std::numeric_limits::lowest)()); ja.push_back(L"S"); ja.push_back(L"String too long for small string optimization"); j1[L"An array"] = ja; std::vector v; cbor::encode_cbor(j1, v); wjson j2 = cbor::decode_cbor(v); CHECK(j2 == j1); wjson j3 = cbor::decode_cbor(v.begin(), v.end()); CHECK(j3 == j1); } TEST_CASE("cbor_reputon_test") { ojson j1 = ojson::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 } ] } )"); std::vector v; cbor::encode_cbor(j1, v); ojson j2 = cbor::decode_cbor(v); CHECK(j2 == j1); ojson j3 = cbor::decode_cbor(v.begin(), v.end()); CHECK(j3 == j1); } #if (defined(__GNUC__) || defined(__clang__)) && defined(JSONCONS_HAS_INT128) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" TEST_CASE("cbor json constructor __int64 tests") { SECTION("test 1") { json j1("-18446744073709551617", semantic_tag::bigint); __int128 val1 = j1.as<__int128>(); std::vector expected = {0xc3,0x49,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; std::vector data; cbor::encode_cbor(val1, data); CHECK(expected == data); auto val2 = cbor::decode_cbor<__int128>(data); CHECK((val2 == val1)); } } TEST_CASE("cbor json constructor unsigned __int64 tests") { SECTION("test 1") { json j1("18446744073709551616", semantic_tag::bigint); auto val1 = j1.as(); std::vector expected = {0xc2,0x49,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; std::vector data; cbor::encode_cbor(val1, data); CHECK(expected == data); auto val2 = cbor::decode_cbor(data); CHECK((val2 == val1)); } } #pragma GCC diagnostic pop #endif jsoncons-1.3.2/test/cbor/src/cbor_typed_array_tests.cpp000066400000000000000000000757531477700171100233500ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" #endif #include #include #include #include #include #include #include #include using namespace jsoncons; static void check_native(std::true_type, const std::vector& u, const std::vector& v) { if (u != v) { for (auto c : u) { std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)c << " "; } std::cout << "\n"; for (auto c : v) { std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)c << " "; } std::cout << "\n\n"; } CHECK((u == v)); } static void check_native(std::false_type, const std::vector&, const std::vector&) { } struct my_cbor_visitor : public default_json_visitor { std::vector v; private: JSONCONS_VISITOR_RETURN_TYPE visit_typed_array(const span& data, semantic_tag, const ser_context&, std::error_code&) override { //std::cout << "visit_typed_array size: " << data.size() << "\n"; v = std::vector(data.begin(),data.end()); JSONCONS_VISITOR_RETURN; } }; TEST_CASE("cbor multi dim row major cursor tests") { SECTION("Tag 86, float64, little endian") { //std::cout << "CBOR multi dim typed array Tag 86, float64, little endian" << '\n'; const std::vector input = { 0xd8,0x28,0x82,0x82,0x02,0x03,0x86,0x02,0x04,0x08,0x04,0x10,0x19,0x01,0x00 }; cbor::cbor_bytes_cursor cursor(input); for (; !cursor.done(); cursor.next()) { //const auto& event = cursor.current(); //std::cout << event.event_type() << " " << event.tag() << "\n"; } } } TEST_CASE("cbor typed array cursor tests") { SECTION("Tag 86, float64, little endian") { //std::cout << "CBOR cursor typed array Tag 86, float64, little endian" << '\n'; const std::vector input = { 0xd8, // Tag 0x56, // Tag 86, float64, little endian, Typed Array 0x50, // Byte string value of length 16 0xff,0xff,0xff,0xff,0xff,0xff,0xef,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x7f }; cbor::cbor_bytes_cursor cursor(input); CHECK(staj_event_type::begin_array == cursor.current().event_type()); CHECK(cursor.is_typed_array()); my_cbor_visitor visitor; cursor.read_to(visitor); //for (auto item : visitor.v) //{ // std::cout << item << "\n"; //} } } TEST_CASE("cbor typed array tests") { SECTION("Tag 64 (uint8 Typed Array)") { //std::cout << "CBOR typed array Tag 64 (uint8 Typed Array)" << '\n'; //std::cout << (int)detail::endian::native << "\n"; const std::vector input = { 0xd8, // Tag 0x40, // Tag 64, uint8, Typed Array 0x43, // Byte string value of length 3 0x00,0x01,0xff }; //json j = cbor::decode_cbor(input); //std::cout << "Tag 64\n" << pretty_print(j) << "\n"; //REQUIRE(j.is_array()); //REQUIRE(3 == j.size()); //CHECK(j[0].as() == std::numeric_limits::lowest()); //CHECK(j[1].as() == uint8_t(1)); //CHECK(j[2].as() == (std::numeric_limits::max)()); auto u = cbor::decode_cbor>(input); std::vector v; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(u, v, options); CHECK((v == input)); } SECTION("Tags 65 (uint16, big endian)") { const std::vector input = { 0xd8, // Tag 0x41, // Tag 65, uint16, big endian, Typed Array 0x46, // Byte string value of length 6 0x00,0x00,0x00,0x01,0xff,0xff }; json j = cbor::decode_cbor(input); //std::cout << "Tag 65\n" << pretty_print(j) << "\n"; REQUIRE(j.is_array()); REQUIRE(3 == j.size()); CHECK(j[0].as() == std::numeric_limits::lowest()); CHECK(j[1].as() == uint16_t(1)); CHECK(j[2].as() == (std::numeric_limits::max)()); auto u = cbor::decode_cbor>(input); std::vector v; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(u, v, options); check_native(std::integral_constant(), input, v); } SECTION("Tag 66 (uint32, big endian)") { const std::vector input = { 0xd8, // Tag 0x42, // Tag 66, uint32, big endian, Typed Array 0x4c, // Byte string value of length 12 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01, 0xff,0xff,0xff,0xff }; json j = cbor::decode_cbor(input); //std::cout << "Tag 66\n" << pretty_print(j) << "\n"; REQUIRE(j.is_array()); REQUIRE(3 == j.size()); CHECK(j[0].as() == std::numeric_limits::lowest()); CHECK(j[1].as() == uint32_t(1)); CHECK(j[2].as() == (std::numeric_limits::max)()); auto u = cbor::decode_cbor>(input); std::vector v; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(u, v, options); check_native(std::integral_constant(), input, v); } SECTION("Tags 67 (uint64,big endian)") { const std::vector input = { 0xd8, // Tag 0x43, // Tag 67, uint64, big endian, Typed Array 0x58,0x18, // Byte string value of length 24 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; json j = cbor::decode_cbor(input); //std::cout << "Tag 67\n" << pretty_print(j) << "\n"; REQUIRE(j.is_array()); REQUIRE(3 == j.size()); CHECK(j[0].as() == std::numeric_limits::lowest()); CHECK(j[1].as() == uint64_t(1)); CHECK(j[2].as() == (std::numeric_limits::max)()); auto u = cbor::decode_cbor>(input); std::vector v; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(u, v, options); check_native(std::integral_constant(), input, v); } SECTION("Tag 68 (uint8, Typed Array, clamped arithmetic)") { const std::vector input = { 0xd8, // Tag 0x44, // Tag 68, uint8, Typed Array, clamped arithmetic 0x43, // Byte string value of length 3 0x00,0x01,0xff }; json j = cbor::decode_cbor(input); //std::cout << "Tag 68\n" << pretty_print(j) << "\n"; REQUIRE(j.is_array()); CHECK(j.tag() == semantic_tag::clamped); REQUIRE(3 == j.size()); CHECK(j[0].as() == std::numeric_limits::lowest()); CHECK(j[1].as() == uint8_t(1)); CHECK(j[2].as() == (std::numeric_limits::max)()); auto v = cbor::decode_cbor>(input); REQUIRE(3 == v.size()); CHECK(v[0] == std::numeric_limits::lowest()); CHECK(v[1] == uint8_t(1)); CHECK(v[2] == (std::numeric_limits::max)()); } SECTION("Tags 69 (uint16, little endian)") { //std::cout << "CBOR typed array Tags 69 (uint16, little endian)" << '\n'; const std::vector input = { 0xd8, // Tag 0x45, // Tag 69, uint16, little endian, Typed Array 0x46, // Byte string value of length 6 0x00,0x00,0x01,0x00,0xff,0xff }; json j = cbor::decode_cbor(input); //std::cout << "Tag 69\n" << pretty_print(j) << "\n"; REQUIRE(j.is_array()); REQUIRE(3 == j.size()); CHECK(j[0].as() == std::numeric_limits::lowest()); CHECK(j[1].as() == uint16_t(1)); CHECK(j[2].as() == (std::numeric_limits::max)()); auto u = cbor::decode_cbor>(input); REQUIRE(3 == u.size()); CHECK(u[0] == std::numeric_limits::lowest()); CHECK(u[1] == uint16_t(1)); CHECK(u[2] == (std::numeric_limits::max)()); auto v = cbor::decode_cbor>(input); REQUIRE(3 == v.size()); CHECK(v[0] == std::numeric_limits::lowest()); CHECK(v[1] == uint16_t(1)); CHECK(v[2] == (std::numeric_limits::max)()); auto w = cbor::decode_cbor>(input); REQUIRE(3 == w.size()); CHECK(w[0] == std::numeric_limits::lowest()); CHECK(w[1] == uint16_t(1)); CHECK(w[2] == (std::numeric_limits::max)()); std::vector buf; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(u, buf, options); check_native(std::integral_constant(), input, buf); } SECTION("Tags 70 (uint32, little endian)") { //std::cout << "CBOR typed array Tags 70 (uint32, little endian)" << '\n'; const std::vector input = { 0xd8, // Tag 0x46, // Tag 70, uint32, little endian, Typed Array 0x4c, // Byte string value of length 12 0x00,0x00,0x00,0x00, 0x01,0x00,0x00,0x00, 0xff,0xff,0xff,0xff }; json j = cbor::decode_cbor(input); //std::cout << "Tag 70\n" << pretty_print(j) << "\n"; REQUIRE(j.is_array()); REQUIRE(3 == j.size()); CHECK(j[0].as() == std::numeric_limits::lowest()); CHECK(j[1].as() == uint32_t(1)); CHECK(j[2].as() == (std::numeric_limits::max)()); auto u = cbor::decode_cbor>(input); REQUIRE(3 == u.size()); CHECK(u[0] == std::numeric_limits::lowest()); CHECK(u[1] == uint32_t(1)); CHECK(u[2] == (std::numeric_limits::max)()); auto v = cbor::decode_cbor>(input); REQUIRE(3 == v.size()); CHECK(v[0] == std::numeric_limits::lowest()); CHECK(v[1] == uint32_t(1)); CHECK(v[2] == (std::numeric_limits::max)()); std::vector buf; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(u, buf, options); check_native(std::integral_constant(), input, buf); } SECTION("Tag 71 (uint64,little endian)") { //std::cout << "CBOR typed array Tag 71 (uint64,little endian)" << '\n'; const std::vector input = { 0xd8, // Tag 0x47, // Tag 71, uint64, little endian, Typed Array 0x58,0x18, // Byte string value of length 24 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; json j = cbor::decode_cbor(input); //std::cout << "Tag 71\n" << pretty_print(j) << "\n"; REQUIRE(j.is_array()); REQUIRE(3 == j.size()); CHECK(j[0].as() == std::numeric_limits::lowest()); CHECK(j[1].as() == uint64_t(1)); CHECK(j[2].as() == (std::numeric_limits::max)()); auto u = cbor::decode_cbor>(input); REQUIRE(3 == u.size()); CHECK(u[0] == std::numeric_limits::lowest()); CHECK(u[1] == uint64_t(1)); CHECK(u[2] == (std::numeric_limits::max)()); std::vector buf; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(u, buf, options); check_native(std::integral_constant(), input, buf); } SECTION("Tag 72 (int8)") { const std::vector input = { 0xd8, // Tag 0x48, // Tag 72, sint8, Typed Array 0x43, // Byte string value of length 3 0x80,0x01,0x7f }; json j = cbor::decode_cbor(input); //std::cout << "Tag 72\n" << pretty_print(j) << "\n"; REQUIRE(j.is_array()); REQUIRE(3 == j.size()); CHECK(j[0].as() == std::numeric_limits::lowest()); CHECK(j[1].as() == int8_t(1)); CHECK(j[2].as() == (std::numeric_limits::max)()); auto u = cbor::decode_cbor>(input); std::vector buf; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(u, buf, options); check_native(std::integral_constant(), input, buf); } SECTION("Tag 73 (int16, big endian)") { const std::vector input = { 0xd8, // Tag 0x49, // Tag 73, sint16, big endian, Typed Array 0x46, // Byte string value of length 6 0x80,0x00, 0x00,0x01, 0x7f,0xff }; json j = cbor::decode_cbor(input); //std::cout << "Tag 73\n" << pretty_print(j) << "\n"; REQUIRE(j.is_array()); REQUIRE(3 == j.size()); CHECK(j[0].as() == std::numeric_limits::lowest()); CHECK(j[1].as() == int16_t(1)); CHECK(j[2].as() == (std::numeric_limits::max)()); auto u = cbor::decode_cbor>(input); REQUIRE(3 == u.size()); CHECK(u[0] == std::numeric_limits::lowest()); CHECK(u[1] == int16_t(1)); CHECK(u[2] == (std::numeric_limits::max)()); auto v = cbor::decode_cbor>(input); REQUIRE(3 == v.size()); CHECK(v[0] == std::numeric_limits::lowest()); CHECK(v[1] == int16_t(1)); CHECK(v[2] == (std::numeric_limits::max)()); auto w = cbor::decode_cbor>(input); REQUIRE(3 == w.size()); CHECK(w[0] == std::numeric_limits::lowest()); CHECK(w[1] == int16_t(1)); CHECK(w[2] == (std::numeric_limits::max)()); std::vector buf; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(u, buf, options); check_native(std::integral_constant(), input, buf); } SECTION("Tag 74 (int32, big endian)") { const std::vector input = { 0xd8, // Tag 0x4a, // Tag 74, sint32, big endian, Typed Array 0x4c, // Byte string value of length 12 0x80,0x00,0x00,0x00, 0x00,0x00,0x00,0x01, 0x7f,0xff,0xff,0xff }; json j = cbor::decode_cbor(input); //std::cout << "Tag 74\n" << pretty_print(j) << "\n"; REQUIRE(j.is_array()); REQUIRE(3 == j.size()); CHECK(j[0].as() == std::numeric_limits::lowest()); CHECK(j[1].as() == int32_t(1)); CHECK(j[2].as() == (std::numeric_limits::max)()); auto u = cbor::decode_cbor>(input); REQUIRE(3 == u.size()); CHECK(u[0] == std::numeric_limits::lowest()); CHECK(u[1] == int32_t(1)); CHECK(u[2] == (std::numeric_limits::max)()); auto v = cbor::decode_cbor>(input); REQUIRE(3 == v.size()); CHECK(v[0] == std::numeric_limits::lowest()); CHECK(v[1] == int32_t(1)); CHECK(v[2] == (std::numeric_limits::max)()); std::vector buf; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(u, buf, options); check_native(std::integral_constant(), input, buf); } SECTION("Tag 75 (int64,big endian)") { const std::vector input = { 0xd8, // Tag 0x4b, // Tag 75, sint64, big endian, Typed Array 0x58,0x18, // Byte string value of length 24 0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, 0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; json j = cbor::decode_cbor(input); //std::cout << "Tag 75\n" << pretty_print(j) << "\n"; REQUIRE(j.is_array()); REQUIRE(3 == j.size()); CHECK(j[0].as() == std::numeric_limits::lowest()); CHECK(j[1].as() == int64_t(1)); CHECK(j[2].as() == (std::numeric_limits::max)()); auto u = cbor::decode_cbor>(input); REQUIRE(3 == u.size()); CHECK(u[0] == std::numeric_limits::lowest()); CHECK(u[1] == int64_t(1)); CHECK(u[2] == (std::numeric_limits::max)()); std::vector buf; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(u, buf, options); check_native(std::integral_constant(), input, buf); } SECTION("Tag 77 (int16, little endian)") { //std::cout << "CBOR typed array Tag 77 (int16, little endian)" << '\n'; const std::vector input = { 0xd8, // Tag 0x4d, // Tag 77, sint16, little endian, Typed Array 0x46, // Byte string value of length 6 0x00,0x80, 0x01,0x00, 0xff,0x7f }; json j = cbor::decode_cbor(input); //std::cout << "Tag 77\n" << pretty_print(j) << "\n"; REQUIRE(j.is_array()); REQUIRE(3 == j.size()); CHECK(j[0].as() == std::numeric_limits::lowest()); CHECK(j[1].as() == int16_t(1)); CHECK(j[2].as() == (std::numeric_limits::max)()); auto u = cbor::decode_cbor>(input); REQUIRE(3 == u.size()); CHECK(u[0] == std::numeric_limits::lowest()); CHECK(u[1] == int16_t(1)); CHECK(u[2] == (std::numeric_limits::max)()); auto v = cbor::decode_cbor>(input); REQUIRE(3 == v.size()); CHECK(v[0] == std::numeric_limits::lowest()); CHECK(v[1] == int16_t(1)); CHECK(v[2] == (std::numeric_limits::max)()); auto w = cbor::decode_cbor>(input); REQUIRE(3 == w.size()); CHECK(w[0] == std::numeric_limits::lowest()); CHECK(w[1] == int16_t(1)); CHECK(w[2] == (std::numeric_limits::max)()); std::vector buf; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(u, buf, options); check_native(std::integral_constant(), input, buf); } SECTION("Tags 78 (int32, little endian)") { //std::cout << "CBOR typed array Tags 78 (int32, little endian)" << '\n'; const std::vector input = { 0xd8, // Tag 0x4e, // Tag 78, sint32, little endian, Typed Array 0x4c, // Byte string value of length 12 0x00,0x00,0x00,0x80, 0x01,0x00,0x00,0x00, 0xff,0xff,0xff,0x7f }; json j = cbor::decode_cbor(input); //std::cout << "Tag 78\n" << pretty_print(j) << "\n"; REQUIRE(j.is_array()); REQUIRE(3 == j.size()); CHECK(j[0].as() == std::numeric_limits::lowest()); CHECK(j[1].as() == int32_t(1)); CHECK(j[2].as() == (std::numeric_limits::max)()); auto u = cbor::decode_cbor>(input); REQUIRE(3 == u.size()); CHECK(u[0] == std::numeric_limits::lowest()); CHECK(u[1] == int32_t(1)); CHECK(u[2] == (std::numeric_limits::max)()); auto v = cbor::decode_cbor>(input); REQUIRE(3 == v.size()); CHECK(v[0] == std::numeric_limits::lowest()); CHECK(v[1] == int32_t(1)); CHECK(v[2] == (std::numeric_limits::max)()); std::vector buf; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(u, buf, options); check_native(std::integral_constant(), input, buf); } SECTION("Tag 79 (int64,little endian)") { //std::cout << "CBOR typed array Tag 79 (int64,little endian)" << '\n'; const std::vector input = { 0xd8, // Tag 0x4f, // Tag 79, sint64, little endian, Typed Array 0x58,0x18, // Byte string value of length 24 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80, 0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f }; json j = cbor::decode_cbor(input); //std::cout << "Tag 79\n" << pretty_print(j) << "\n"; REQUIRE(j.is_array()); REQUIRE(3 == j.size()); CHECK(j[0].as() == std::numeric_limits::lowest()); CHECK(j[1].as() == int64_t(1)); CHECK(j[2].as() == (std::numeric_limits::max)()); auto u = cbor::decode_cbor>(input); REQUIRE(3 == u.size()); CHECK(u[0] == std::numeric_limits::lowest()); CHECK(u[1] == int64_t(1)); CHECK(u[2] == (std::numeric_limits::max)()); std::vector buf; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(u, buf, options); check_native(std::integral_constant(), input, buf); } SECTION("Tag 80, float16, big endian") { const std::vector input = { 0xd8, // Tag 0x50, // Tag 80, float16, big endian, Typed Array 0x48, // Byte string value of length 8 0x00,0x01, 0x03,0xff, 0x04,0x00, 0x7b,0xff }; json j = cbor::decode_cbor(input); //std::cout << "Tag 80\n" << pretty_print(j) << "\n"; REQUIRE(j.is_array()); REQUIRE(4 == j.size()); CHECK(j[0].as() == Approx(0.000000059605).epsilon(0.00001)); CHECK(j[1].as() == Approx(0.000060976).epsilon(0.00001)); CHECK(j[2].as() == Approx(0.000061035).epsilon(0.00001)); CHECK(j[3].as() == 65504); } SECTION("Tag 81, float32, big endian") { const std::vector input = { 0xd8, // Tag 0x51, // Tag 81, float32, big endian, Typed Array 0x48, // Byte string value of length 8 0xff,0x7f,0xff,0xff, 0x7f,0x7f,0xff,0xff }; json j = cbor::decode_cbor(input); //std::cout << "Tag 81\n" << pretty_print(j) << "\n"; REQUIRE(j.is_array()); REQUIRE(2 == j.size()); CHECK(j[0].as() == std::numeric_limits::lowest()); CHECK(j[1].as() == (std::numeric_limits::max)()); auto u = cbor::decode_cbor>(input); std::vector buf; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(u, buf, options); check_native(std::integral_constant(), input, buf); } SECTION("Tag 82, float64, big endian") { const std::vector input = { 0xd8, // Tag 0x52, // Tag 82, float64, big endian, Typed Array 0x50, // Byte string value of length 16 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; json j = cbor::decode_cbor(input); REQUIRE(j.is_array()); //std::cout << pretty_print(j) << "\n"; auto u = cbor::decode_cbor>(input); std::vector buf; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(u, buf, options); check_native(std::integral_constant(), input, buf); } SECTION("Tag 83, float128, big endian") { const std::vector input = { 0xd8, // Tag 0x53, // Tag 83, float128, big endian, Typed Array 0x58,0x40, // Byte string value of length 64 0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0x7f,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xbf,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x3f,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; //json j = cbor::decode_cbor(input); //REQUIRE(j.is_array()); //REQUIRE(2 == j.size()); //CHECK(j[0].as() == std::numeric_limits::lowest()); //CHECK(j[1].as() == (std::numeric_limits::max)()); } SECTION("Tag 84, float16, little endian") { //std::cout << "CBOR typed array Tag 84, float16, little endian" << '\n'; const std::vector input = { 0xd8, // Tag 0x54, // Tag 84, float16, little endian, Typed Array 0x48, // Byte string value of length 8 0x01,0x00, 0xff,0x03, 0x00,0x04, 0xff,0x7b }; json j = cbor::decode_cbor(input); //std::cout << "Tag 84\n" << pretty_print(j) << "\n"; REQUIRE(j.is_array()); REQUIRE(4 == j.size()); CHECK(j[0].as() == Approx(0.000000059605).epsilon(0.00001)); CHECK(j[1].as() == Approx(0.000060976).epsilon(0.00001)); CHECK(j[2].as() == Approx(0.000061035).epsilon(0.00001)); CHECK(j[3].as() == 65504); } SECTION("Tag 85, float32, little endian") { //std::cout << "CBOR typed array Tag 85, float32, little endian" << '\n'; const std::vector input = { 0xd8, // Tag 0x55, // Tag 85, float64, little endian, Typed Array 0x48, // Byte string value of length 8 0xff,0xff,0x7f,0xff, 0xff,0xff,0x7f,0x7f }; json j = cbor::decode_cbor(input); //std::cout << "Tag 85\n" << pretty_print(j) << "\n"; REQUIRE(j.is_array()); REQUIRE(2 == j.size()); CHECK(j[0].as() == std::numeric_limits::lowest()); CHECK(j[1].as() == (std::numeric_limits::max)()); auto u = cbor::decode_cbor>(input); REQUIRE(2 == u.size()); CHECK(u[0] == std::numeric_limits::lowest()); CHECK(u[1] == (std::numeric_limits::max)()); std::vector buf; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(u, buf, options); check_native(std::integral_constant(), input, buf); } SECTION("Tag 86, float64, little endian") { //std::cout << "CBOR typed array Tag 86, float64, little endian" << '\n'; const std::vector input = { 0xd8, // Tag 0x56, // Tag 86, float64, little endian, Typed Array 0x50, // Byte string value of length 16 0xff,0xff,0xff,0xff,0xff,0xff,0xef,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x7f }; json j = cbor::decode_cbor(input); //std::cout << "Tag 86\n" << pretty_print(j) << "\n"; REQUIRE(j.is_array()); REQUIRE(2 == j.size()); CHECK(j[0].as() == std::numeric_limits::lowest()); CHECK(j[1].as() == (std::numeric_limits::max)()); auto u = cbor::decode_cbor>(input); REQUIRE(2 == u.size()); CHECK(u[0] == std::numeric_limits::lowest()); CHECK(u[1] == (std::numeric_limits::max)()); std::vector buf; auto options = cbor::cbor_options{} .use_typed_arrays(true); cbor::encode_cbor(u, buf, options); check_native(std::integral_constant(), input, buf); } SECTION("Tag 87, float128, little endian") { //std::cout << "CBOR typed array Tag 87, float128, little endian" << '\n'; const std::vector input = { 0xd8, // Tag 0x57, // Tag 87, float128, little endian, Typed Array 0x58,0x40, // Byte string value of length 64 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x7f, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xbf, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x3f }; //json j = cbor::decode_cbor(input); //REQUIRE(j.is_array()); //REQUIRE(2 == j.size()); } } jsoncons-1.3.2/test/cbor/src/decode_cbor_tests.cpp000066400000000000000000000526561477700171100222450ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" #endif #include #include #include #include #include #include #include #include #include using namespace jsoncons; namespace { class MyIterator { const uint8_t* p_; public: using iterator_category = std::input_iterator_tag; using value_type = uint8_t; using difference_type = std::ptrdiff_t; using pointer = const uint8_t*; using reference = const uint8_t&; MyIterator(const uint8_t* p) : p_(p) { } reference operator*() const { return *p_; } pointer operator->() const { return p_; } MyIterator& operator++() { ++p_; return *this; } MyIterator operator++(int) { MyIterator temp(*this); ++*this; return temp; } bool operator!=(const MyIterator& rhs) const { return p_ != rhs.p_; } }; } // namespace TEST_CASE("cbor_view_test") { ojson j1 = ojson::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 } ] } )"); std::vector c; cbor::encode_cbor(j1, c); json v = cbor::decode_cbor(c); CHECK(v.is_object()); CHECK_FALSE(v.is_array()); const json& reputons = v.at("reputons"); CHECK(reputons.is_array()); const json& reputons_0 = reputons.at(0); const json& reputons_0_rated = reputons_0.at("rated"); (void)reputons_0_rated; const json& rating = reputons_0.at("rating"); CHECK(rating.as_double() == 0.90); for (const auto& member : v.object_range()) { const auto& key = member.key(); const json& jval = member.value(); (void)key; (void)jval; //std::cout << key << ": " << jval << '\n'; } //std::cout << '\n'; for (auto element : reputons.array_range()) { json j = element; //std::cout << j << '\n'; } //std::cout << '\n'; } TEST_CASE("jsonpointer_test") { json j = json::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 } ] } )"); std::vector v; cbor::encode_cbor(j, v); json jdoc = cbor::decode_cbor(v); std::string s; jdoc.dump(s); json j1 = json::parse(s); CHECK(j1 == j); std::error_code ec; const json& application = jsonpointer::get(jdoc, "/application", ec); CHECK_FALSE(ec); CHECK(application == j["application"]); const json& reputons_0_rated = jsonpointer::get(jdoc, "/reputons", ec); CHECK_FALSE(ec); json j4 = j["reputons"]; CHECK(reputons_0_rated == j4); //std::cout << pretty_print(j3) << '\n'; } TEST_CASE("as_string_test") { std::vector v; cbor::cbor_bytes_encoder encoder(v); encoder.begin_array(10); encoder.bool_value(true); encoder.bool_value(false); encoder.null_value(); encoder.string_value("Toronto"); encoder.byte_string_value(byte_string{'H','e','l','l','o'}); encoder.int64_value(-100); encoder.uint64_value(100); encoder.string_value("18446744073709551616", semantic_tag::bigint); encoder.double_value(10.5); encoder.string_value("-18446744073709551617", semantic_tag::bigint); encoder.end_array(); encoder.flush(); json j = cbor::decode_cbor(v); std::string s0; j[0].dump(s0); CHECK(std::string("true") == s0); CHECK(std::string("true") == j[0].as_string()); CHECK(true == j[0].as()); CHECK(j[0].is()); std::string s1; j[1].dump(s1); CHECK(std::string("false") == s1); CHECK(std::string("false") == j[1].as_string()); CHECK(false == j[1].as()); CHECK(j[1].is()); std::string s2; j[2].dump(s2); CHECK(std::string("null") == s2); CHECK(std::string("null") == j[2].as_string()); std::string s3; j[3].dump(s3); CHECK(std::string("\"Toronto\"") == s3); CHECK(std::string("Toronto") == j[3].as_string()); CHECK(std::string("Toronto") ==j[3].as()); std::string s4; j[4].dump(s4); CHECK(std::string("\"SGVsbG8\"") == s4); CHECK(std::string("SGVsbG8") == j[4].as_string()); CHECK(byte_string({'H','e','l','l','o'}) == j[4].as()); std::string s5; j[5].dump(s5); CHECK(std::string("-100") ==s5); CHECK(std::string("-100") == j[5].as_string()); CHECK(-100 ==j[5].as()); std::string s6; j[6].dump(s6); CHECK(std::string("100") == s6); CHECK(std::string("100") == j[6].as_string()); std::string s7; j[7].dump(s7); CHECK(std::string("18446744073709551616") == s7); std::string s8; j[8].dump(s8); CHECK(std::string("10.5") == s8); CHECK(std::string("10.5") == j[8].as_string()); std::string s9; j[9].dump(s9); CHECK(std::string("-18446744073709551617") == s9); } TEST_CASE("dump cbor to string test") { std::vector v; cbor::cbor_bytes_encoder encoder(v); encoder.begin_array(); std::vector bytes = {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; bigint n = bigint::from_bytes_be(1, bytes.data(), bytes.size()); n = -1 - n; std::string s = n.to_string(); encoder.string_value(s, semantic_tag::bigint); encoder.end_array(); encoder.flush(); json j = cbor::decode_cbor(v); std::string s0; j.dump(s0); CHECK("[-18446744073709551617]" == s0); //std::cout << s0 << '\n'; std::string s1; auto options1 = json_options{} .bignum_format(bignum_format_kind::raw); j.dump(s1,options1); CHECK("[-18446744073709551617]" == s1); //std::cout << s1 << '\n'; std::string s2; auto options2 = json_options{} .bignum_format(bignum_format_kind::base10); j.dump(s2,options2); CHECK("[\"-18446744073709551617\"]" == s2); //std::cout << s2 << '\n'; std::string s3; auto options3 = json_options{} .bignum_format(bignum_format_kind::base64url); j.dump(s3,options3); CHECK("[\"~AQAAAAAAAAAA\"]" == s3); //std::cout << s3 << '\n'; } TEST_CASE("test_dump_to_stream") { std::vector v; cbor::cbor_bytes_encoder encoder(v); encoder.begin_array(); std::vector bytes = {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; bigint n = bigint::from_bytes_be(1, bytes.data(), bytes.size()); n = -1 - n; std::string s = n.to_string(); encoder.string_value(s, semantic_tag::bigint); encoder.end_array(); encoder.flush(); json j = cbor::decode_cbor(v); std::ostringstream os0; j.dump(os0); CHECK("[-18446744073709551617]" == os0.str()); //std::cout << os0.str() << '\n'; std::ostringstream os1; auto options1 = json_options{} .bignum_format(bignum_format_kind::raw); j.dump(os1,options1); CHECK("[-18446744073709551617]" == os1.str()); //std::cout << os1.str() << '\n'; std::ostringstream os2; auto options2 = json_options{} .bignum_format(bignum_format_kind::base10); j.dump(os2,options2); CHECK("[\"-18446744073709551617\"]" == os2.str()); //std::cout << os2.str() << '\n'; std::ostringstream os3; auto options3 = json_options{} .bignum_format(bignum_format_kind::base64url); j.dump(os3,options3); CHECK("[\"~AQAAAAAAAAAA\"]" == os3.str()); //std::cout << os3.str() << '\n'; } TEST_CASE("test_indefinite_length_object_iterator") { std::vector v; cbor::cbor_bytes_encoder encoder(v); encoder.begin_object(); // indefinite length object encoder.key("City"); encoder.string_value("Toronto"); encoder.key("Province"); encoder.string_value("Ontario"); encoder.end_object(); encoder.flush(); json bv2 = cbor::decode_cbor(v); auto it2 = bv2.object_range().begin(); CHECK_FALSE((it2 == bv2.object_range().end())); CHECK_FALSE((++it2 == bv2.object_range().end())); CHECK((++it2 == bv2.object_range().end())); } TEST_CASE("test_indefinite_length_array_iterator") { std::vector v; cbor::cbor_bytes_encoder encoder(v); encoder.begin_array(); // indefinite length array encoder.string_value("Toronto"); encoder.string_value("Ontario"); encoder.end_array(); encoder.flush(); json j = cbor::decode_cbor(v); CHECK(2 == j.size()); auto it2 = j.array_range().begin(); CHECK_FALSE((it2 == j.array_range().end())); CHECK_FALSE((++it2 == j.array_range().end())); CHECK((++it2 == j.array_range().end())); } TEST_CASE("cbor array comparison test") { std::vector v1; cbor::cbor_bytes_encoder encoder1(v1); encoder1.begin_array(); // indefinite length array encoder1.string_value("Toronto"); encoder1.string_value("Vancouver"); encoder1.end_array(); encoder1.flush(); json j1 = cbor::decode_cbor(v1); std::vector v2; cbor::cbor_bytes_encoder serializer2(v2); serializer2.begin_array(); // indefinite length array serializer2.string_value("Toronto"); serializer2.string_value("Vancouver"); serializer2.end_array(); serializer2.flush(); json j2 = cbor::decode_cbor(v2); std::vector v3; cbor::cbor_bytes_encoder serializer3(v3); serializer3.begin_array(); // indefinite length array serializer3.string_value("Toronto"); serializer3.string_value("Montreal"); serializer3.end_array(); serializer3.flush(); json j3 = cbor::decode_cbor(v3); SECTION("operator== test") { CHECK(j2 == j1); REQUIRE(2 == j1.size()); REQUIRE(2 == j2.size()); CHECK(j1[0] == j2[0]); CHECK(j1[1] == j2[1]); } SECTION("element operator== test") { CHECK_FALSE(j1 == j3); REQUIRE(2 == j1.size()); REQUIRE(j1.size() == j3.size()); CHECK(j1[0] == j3[0]); CHECK_FALSE(j1[1] == j3[1]); } } TEST_CASE("cbor object comparison") { std::vector v; cbor::cbor_bytes_encoder encoder1(v); encoder1.begin_object(); // indefinite length array encoder1.key("City"); encoder1.string_value("Montreal"); encoder1.key("Amount"); encoder1.string_value("273.15", semantic_tag::bigdec); encoder1.key("Date"); encoder1.string_value("2018-05-07 12:41:07-07:00", semantic_tag::datetime) ; encoder1.end_object(); encoder1.flush(); json j1 = cbor::decode_cbor(v); //std::cout << pretty_print(j1) << "\n"; REQUIRE(3 == j1.size()); std::vector buf2; cbor::cbor_bytes_encoder serializer2(buf2); serializer2.begin_object(); // indefinite length array serializer2.key("City"); serializer2.string_value("Toronto"); serializer2.key("Amount"); serializer2.string_value("273.15", semantic_tag::bigdec); serializer2.key("Date"); serializer2.string_value("2018-10-18 12:41:07-07:00", semantic_tag::datetime) ; serializer2.end_object(); serializer2.flush(); json j2 = cbor::decode_cbor(buf2); REQUIRE(j2.size() == j1.size()); std::vector buf3; cbor::cbor_bytes_encoder serializer3(buf3); serializer3.begin_object(); // indefinite length array serializer3.key("empty-object"); serializer3.begin_object(0); serializer3.end_object(); serializer3.key("empty-array"); serializer3.begin_array(0); serializer3.end_array(); serializer3.key("empty-string"); serializer3.string_value(""); serializer3.key("empty-byte_string"); serializer3.byte_string_value(jsoncons::byte_string{}); serializer3.end_object(); serializer3.flush(); json j3 = cbor::decode_cbor(buf3); SECTION("contains") { CHECK(j1.contains("City")); CHECK(j1.contains("Amount")); CHECK(j1.contains("Date")); CHECK_FALSE(j1.contains("Country")); } SECTION("empty") { CHECK_FALSE(j3.empty()); CHECK(j3["empty-object"].empty()); CHECK(j3["empty-array"].empty()); CHECK(j3["empty-string"].empty()); CHECK(j3["empty-byte_string"].empty()); } SECTION("size") { CHECK(3 == j1.size()); } SECTION("operator==") { CHECK_FALSE(j1 == j2); CHECK_FALSE(j1["City"] == j2["City"]); CHECK(j1["Amount"] == j2["Amount"]); CHECK_FALSE(j1["Date"] == j2["Date"]); } } TEST_CASE("cbor member tests") { std::vector v; cbor::cbor_bytes_encoder encoder(v); encoder.begin_object(); // indefinite length object encoder.key("empty-object"); encoder.begin_object(0); encoder.end_object(); encoder.key("empty-array"); encoder.begin_array(0); encoder.end_array(); encoder.key("empty-string"); encoder.string_value(""); encoder.key("empty-byte_string"); encoder.byte_string_value(jsoncons::byte_string{}); encoder.key("City"); encoder.string_value("Montreal"); encoder.key("Amount"); encoder.string_value("273.15", semantic_tag::bigdec); encoder.key("Date"); encoder.string_value("2018-05-07 12:41:07-07:00", semantic_tag::datetime) ; encoder.end_object(); encoder.flush(); json j = cbor::decode_cbor(v); SECTION("contains") { CHECK(j.contains("City")); CHECK(j.contains("Amount")); CHECK(j.contains("Date")); CHECK_FALSE(j.contains("Country")); } SECTION("empty") { CHECK_FALSE(j.empty()); CHECK(j["empty-object"].empty()); CHECK(j["empty-array"].empty()); CHECK(j["empty-string"].empty()); CHECK(j["empty-byte_string"].empty()); } SECTION("size") { CHECK(7 == j.size()); } } TEST_CASE("cbor conversion tests") { std::vector v; cbor::cbor_bytes_encoder encoder(v); encoder.begin_array(); // indefinite length outer array encoder.begin_array(4); // a fixed length array encoder.string_value("foo"); encoder.byte_string_value(std::vector{'P','u','s','s'}); // no suggested conversion encoder.string_value("-18446744073709551617", semantic_tag::bigint); encoder.string_value("273.15", semantic_tag::bigdec); encoder.end_array(); encoder.end_array(); encoder.flush(); json j = cbor::decode_cbor(v); REQUIRE(1 == j.size()); auto range1 = j.array_range(); auto it = range1.begin(); const json& inner_array = *it++; REQUIRE(4 == inner_array.size()); REQUIRE((it == range1.end())); auto range2 = inner_array.array_range(); auto it2 = range2.begin(); CHECK(it2->as_string() == "foo"); it2++; CHECK(it2->as>() == std::vector{'P','u','s','s'}); it2++; CHECK(bool(it2->as() == bigint::from_string("-18446744073709551617"))); it2++; CHECK(bool(it2->as_string() == std::string{"273.15"})); it2++; CHECK((it2 == range2.end())); } TEST_CASE("cbor array as<> test") { std::vector v; cbor::cbor_bytes_encoder encoder(v); encoder.begin_array(); // indefinite length outer array encoder.string_value("foo"); encoder.byte_string_value(byte_string({'b','a','r'})); encoder.string_value("-18446744073709551617", semantic_tag::bigint); encoder.string_value("273.15", semantic_tag::bigdec); encoder.string_value("2015-05-07 12:41:07-07:00", semantic_tag::datetime) ; encoder.int64_value(1431027667, semantic_tag::epoch_second); encoder.int64_value(-1431027667, semantic_tag::epoch_second); encoder.double_value(1431027667.5, semantic_tag::epoch_second); encoder.end_array(); encoder.flush(); /* 9f -- Start indefinite length array 63 -- String value of length 3 666f6f -- "foo" 43 -- Byte string value of length 3 626172 -- 'b''a''r' c3 -- Tag 3 (negative bignum) 49 Byte string value of length 9 010000000000000000 -- Bytes content c4 - Tag 4 (decimal fraction) 82 -- Array of length 2 21 -- -2 19 6ab3 -- 27315 c0 -- Tag 0 (date-time) 78 19 -- Length (25) 323031352d30352d30372031323a34313a30372d30373a3030 -- "2015-05-07 12:41:07-07:00" c1 -- Tag 1 (epoch time) 1a -- uint32_t 554bbfd3 -- 1431027667 c1 3a 554bbfd2 c1 fb 41d552eff4e00000 ff -- "break" */ //std::cout << "v: \n"; //for (auto c : v) //{ // std::cout << std::hex << std::setprecision(2) << std::setw(2) // << std::setfill('0') << static_cast(c); //} //std::cout << "\n\n"; json j = cbor::decode_cbor(v); // a non-owning view of the CBOR v CHECK(8 == j.size()); SECTION("j[0].is()") { CHECK(j[0].is()); CHECK(j[1].is()); CHECK(j[1].is()); CHECK(j[2].is()); CHECK(j[3].is_string()); CHECK(j[3].tag() == semantic_tag::bigdec); CHECK(j[4].is()); CHECK(j[5].is()); CHECK(j[5].is()); CHECK(j[6].is()); CHECK_FALSE(j[6].is()); CHECK(j[7].is()); } SECTION("j[0].as()") { CHECK(j[0].as() == std::string("foo")); CHECK(j[1].as() == jsoncons::byte_string({'b','a','r'})); CHECK(j[2].as() == std::string("-18446744073709551617")); CHECK(bool(j[2].as() == jsoncons::bigint::from_string("-18446744073709551617"))); CHECK(j[3].as() == std::string("273.15")); CHECK(j[4].as() == std::string("2015-05-07 12:41:07-07:00")); CHECK(j[5].as() == 1431027667); CHECK(j[5].as() == 1431027667U); CHECK(j[6].as() == -1431027667); CHECK(j[7].as() == 1431027667.5); } SECTION("array_iterator is test") { auto it = j.array_range().begin(); CHECK(it++->is()); CHECK(it++->is()); CHECK(it++->is()); CHECK(it++->is()); CHECK(it++->is()); CHECK(it++->is()); CHECK(it++->is()); CHECK(it++->is()); } } TEST_CASE("cbor bigfloat tests") { SECTION("1.5") { std::vector v = {0xc5, // Tag 5 0x82, // Array of length 2 0x20, // -1 0x03 // 3 }; json j = cbor::decode_cbor(v); //std::string s = j.as(); double val = j.as(); CHECK(val == Approx(1.5).epsilon(0.0000000001)); } SECTION("-1.5") { std::vector v = {0xc5, // Tag 5 0x82, // Array of length 2 0x20, // -1 0x22 // -3 }; json j = cbor::decode_cbor(v); //std::string s = j.as(); //CHECK(s == std::string("-1.5")); double val = j.as(); CHECK(val == Approx(-1.5).epsilon(0.0000000001)); } } TEST_CASE("encode decode cbor source") { std::vector input = { 0x88, // Array of length 8 0x63, // String value of length 3 0x66,0x6f,0x6f, // "foo" 0x43, // Byte string value of length 3 0x62,0x61,0x72, // 'b''a''r' 0xc3, // Tag 3 (negative bignum) 0x49, // Byte string value of length 9 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Bytes content 0xc4, //Tag 4 (decimal fraction) 0x82, // Array of length 2 0x21, // -2 0x19,0x6a,0xb3, // 27315 0xc0, // Tag 0 (date-time) 0x78,0x19, // Length (25) 0x32,0x30,0x31,0x35,0x2d,0x30,0x35,0x2d,0x30,0x37,0x20,0x31,0x32,0x3a,0x34,0x31,0x3a,0x30,0x37,0x2d,0x30,0x37,0x3a,0x30,0x30, // "2015-05-07 12:41:07-07:00" 0xc1, // Tag 1 (epoch time) 0x1a, // uint32_t 0x55,0x4b,0xbf,0xd3, // 1431027667 0xc1, 0x3a, 0x55,0x4b,0xbf,0xd2, 0xc1, 0xfb, 0x41,0xd5,0x52,0xef,0xf4,0xe0,0x00,0x00 }; SECTION("from bytes") { ojson j = cbor::decode_cbor(input); std::vector buffer; cbor::encode_cbor(j, buffer); CHECK(buffer == input); } SECTION("from stream") { std::string s(reinterpret_cast(input.data()), input.size()); std::stringstream is(std::move(s)); ojson j = cbor::decode_cbor(is); std::vector buffer; cbor::encode_cbor(j, buffer); CHECK(buffer == input); } SECTION("from iterator source") { ojson j = cbor::decode_cbor(input.begin(), input.end()); std::vector buffer; cbor::encode_cbor(j, buffer); CHECK(buffer == input); } SECTION("from custom iterator source") { MyIterator it(input.data()); MyIterator end(input.data() + input.size()); ojson j = cbor::decode_cbor(it, end); std::vector buffer; cbor::encode_cbor(j, buffer); CHECK(buffer == input); } } jsoncons-1.3.2/test/cbor/src/encode_cbor_tests.cpp000066400000000000000000000202211477700171100222360ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include using namespace jsoncons; // test vectors from tinycbor https://github.com/01org/tinycbor tst_encoder.cpp // MIT license void check_encode_cbor(const std::vector& expected, const json& j) { std::vector result; cbor::encode_cbor(j,result); if (result.size() != expected.size()) { std::cout << j << "\n"; } REQUIRE(result.size() == expected.size()); for (std::size_t i = 0; i < expected.size(); ++i) { REQUIRE(result[i] == expected[i]); } } TEST_CASE("cbor_encoder_test") { // unsigned integer check_encode_cbor({0x00},json(0U)); check_encode_cbor({0x01},json(1U)); check_encode_cbor({0x0a},json(10U)); check_encode_cbor({0x17},json(23U)); check_encode_cbor({0x18,0x18},json(24U)); check_encode_cbor({0x18,0xff},json(255U)); check_encode_cbor({0x19,0x01,0x00},json(256U)); check_encode_cbor({0x19,0xff,0xff},json(65535U)); check_encode_cbor({0x1a,0,1,0x00,0x00},json(65536U)); check_encode_cbor({0x1a,0xff,0xff,0xff,0xff},json(4294967295U)); check_encode_cbor({0x1b,0,0,0,1,0,0,0,0},json(4294967296U)); check_encode_cbor({0x1b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},json((std::numeric_limits::max)())); // positive signed integer check_encode_cbor({0x00},json(0)); check_encode_cbor({0x01},json(1)); check_encode_cbor({0x0a},json(10)); check_encode_cbor({0x17},json(23)); check_encode_cbor({0x18,0x18},json(24)); check_encode_cbor({0x18,0xff},json(255)); check_encode_cbor({0x19,0x01,0x00},json(256)); check_encode_cbor({0x19,0xff,0xff},json(65535)); check_encode_cbor({0x1a,0,1,0x00,0x00},json(65536)); check_encode_cbor({0x1a,0xff,0xff,0xff,0xff},json(4294967295)); check_encode_cbor({0x1b,0,0,0,1,0,0,0,0},json(4294967296)); check_encode_cbor({0x1b,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff},json((std::numeric_limits::max)())); // negative integers check_encode_cbor({0x20},json(-1)); check_encode_cbor({0x21},json(-2)); check_encode_cbor({0x37},json(-24)); check_encode_cbor({0x38,0x18},json(-25)); check_encode_cbor({0x38,0xff},json(-256)); check_encode_cbor({0x39,0x01,0x00},json(-257)); check_encode_cbor({0x39,0xff,0xff},json(-65536)); check_encode_cbor({0x3a,0,1,0x00,0x00},json(-65537)); check_encode_cbor({0x3a,0xff,0xff,0xff,0xff},json(-4294967296)); check_encode_cbor({0x3b,0,0,0,1,0,0,0,0},json(-4294967297)); // null, true, false check_encode_cbor({0xf6},json::null()); check_encode_cbor({0xf5},json(true)); check_encode_cbor({0xf4},json(false)); // floating point check_encode_cbor({0xfa,0,0,0,0},json(0.0)); check_encode_cbor({0xfa,0xbf,0x80,0,0},json(-1.0)); SECTION("-16777215.0") { double val = -16777215.0; float valf = (float)val; CHECK((double)valf == val); check_encode_cbor({0xfa,0xcb,0x7f,0xff,0xff}, json(val)); } // From https://en.wikipedia.org/wiki/Double-precision_floating-point_forma SECTION("0.333333333333333314829616256247390992939472198486328125") { double val = 0.333333333333333314829616256247390992939472198486328125; float valf = (float)val; CHECK((double)valf != val); check_encode_cbor({0xfb,0x3F,0xD5,0x55,0x55,0x55,0x55,0x55,0x55},json(val)); } // byte string check_encode_cbor({0x40},json(byte_string())); check_encode_cbor({0x41,' '},json(byte_string({' '}))); check_encode_cbor({0x41,0},json(byte_string({0}))); check_encode_cbor({0x45,'H','e','l','l','o'},json(byte_string({'H','e','l','l','o'}))); check_encode_cbor({0x58,0x18,'1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4'}, json(byte_string({ '1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4' }))); // text string check_encode_cbor({0x60},json("")); check_encode_cbor({0x61,' '},json(" ")); check_encode_cbor({0x78,0x18,'1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4'}, json("123456789012345678901234")); } TEST_CASE("cbor_arrays_and_maps") { check_encode_cbor({ 0x80 }, json(json_array_arg)); check_encode_cbor({ 0xa0 }, json()); check_encode_cbor({ 0x81,'\0' }, json::parse("[0]")); check_encode_cbor({ 0x82,'\0','\0' }, json(json_array_arg, { 0,0 })); check_encode_cbor({ 0x82,0x81,'\0','\0' }, json::parse("[[0],0]")); check_encode_cbor({ 0x81,0x65,'H','e','l','l','o' }, json::parse("[\"Hello\"]")); // big float json j("0x6AB3p-2", semantic_tag::bigfloat); CHECK(j.tag() == semantic_tag::bigfloat); json j2 = j; CHECK(j2.tag() == semantic_tag::bigfloat); json j3; j3 = j; CHECK(j3.tag() == semantic_tag::bigfloat); check_encode_cbor({ 0xc5, // Tag 5 0x82, // Array of length 2 0x21, // -2 0x19, 0x6a, 0xb3 // 27315 }, json("0x6AB3p-2", semantic_tag::bigfloat)); check_encode_cbor({ 0xa1,0x62,'o','c',0x81,'\0' }, json::parse("{\"oc\": [0]}")); check_encode_cbor({ 0xa1,0x62,'o','c',0x84,'\0','\1','\2','\3' }, json::parse("{\"oc\": [0, 1, 2, 3]}")); } namespace { namespace ns { struct Person { std::string name; }; }} JSONCONS_ALL_MEMBER_TRAITS(ns::Person, name) TEST_CASE("encode_cbor overloads") { SECTION("json, stream") { json person; person.try_emplace("name", "John Smith"); std::string s; std::stringstream ss(s); cbor::encode_cbor(person, ss); json other = cbor::decode_cbor(ss); CHECK(other == person); } SECTION("custom, stream") { ns::Person person{"John Smith"}; std::string s; std::stringstream ss(s); cbor::encode_cbor(person, ss); ns::Person other = cbor::decode_cbor(ss); CHECK(other.name == person.name); } } #if defined(JSONCONS_HAS_STATEFUL_ALLOCATOR) && JSONCONS_HAS_STATEFUL_ALLOCATOR == 1 #include #include template using MyScopedAllocator = std::scoped_allocator_adaptor>; using cust_json = basic_json>; TEST_CASE("encode_cbor allocator_set") { MyScopedAllocator result_alloc(1); MyScopedAllocator temp_alloc(2); auto alloc_set = combine_allocators(result_alloc, temp_alloc); SECTION("json, stream") { cust_json person(json_object_arg, result_alloc); person.try_emplace("name", "John Smith"); std::string s; std::stringstream ss(s); cbor::encode_cbor(alloc_set, person, ss); cust_json other = cbor::decode_cbor(alloc_set,ss); CHECK(other == person); } /* SECTION("custom, stream") { ns::Person person{"John Smith"}; std::string s; std::stringstream ss(s); cbor::encode_cbor(alloc_set, person, ss); ns::Person other = cbor::decode_cbor(alloc_set,ss); CHECK(other.name == person.name); }*/ } TEST_CASE("encode_cbor allocator_set for temp only") { MyScopedAllocator temp_alloc(1); auto alloc_set = temp_allocator_only(temp_alloc); SECTION("json, stream") { json person; person.try_emplace("name", "John Smith"); std::string s; std::stringstream ss(s); cbor::encode_cbor(alloc_set, person, ss); json other = cbor::decode_cbor(alloc_set,ss); CHECK(other == person); } SECTION("custom, stream") { ns::Person person{"John Smith"}; std::string s; std::stringstream ss(s); cbor::encode_cbor(alloc_set, person, ss); ns::Person other = cbor::decode_cbor(alloc_set,ss); CHECK(other.name == person.name); } } #endif jsoncons-1.3.2/test/common/000077500000000000000000000000001477700171100156255ustar00rootroot00000000000000jsoncons-1.3.2/test/common/free_list_allocator.hpp000066400000000000000000000064221477700171100223560ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #ifndef FREE_LIST_ALLOCATOR_HPP #define FREE_LIST_ALLOCATOR_HPP #include #include #include #include #include #include // From http://coliru.stacked-crooked.com/a/cfd0c5c5021596ad template class free_list_allocator { union node { node* next; alignas(alignof(T)) unsigned char storage[sizeof(T)]; }; int id_; node* list = nullptr; void clear() noexcept { auto p = list; while (p) { auto tmp = p; p = p->next; delete tmp; } list = nullptr; } public: using value_type = T; using size_type = std::size_t; using propagate_on_container_move_assignment = std::true_type; using propagate_on_container_swap = std::true_type; free_list_allocator(int id) noexcept : id_(id) {} free_list_allocator(const free_list_allocator& other) noexcept : id_(other.id_) {} template free_list_allocator(const free_list_allocator& other) noexcept : id_(other.id()) {} free_list_allocator(free_list_allocator&& other) noexcept : id_(other.id_), list(other.list) { other.id_ = -1; other.list = nullptr; } free_list_allocator& operator = (const free_list_allocator& other) = delete; free_list_allocator& operator = (free_list_allocator&& other) noexcept { clear(); id_ = other.id_; list = other.list; other.id_ = -1; other.list = nullptr; return *this; } ~free_list_allocator() noexcept { clear(); } int id() const noexcept { return id_; } friend bool operator==(const free_list_allocator& lhs, const free_list_allocator& rhs) noexcept { return lhs.id_ == rhs.id_; } friend bool operator!=(const free_list_allocator& lhs, const free_list_allocator& rhs) noexcept { return !(lhs == rhs); } T* allocate(size_type n) { //std::cout << "Allocate(" << n << ") from "; if (n == 1) { auto ptr = list; if (ptr) { //std::cout << "freelist\n"; list = list->next; } else { //std::cout << "new node\n"; ptr = new node; } return reinterpret_cast(ptr); } //std::cout << "::operator new\n"; return static_cast(::operator new(n * sizeof(T))); } void deallocate(T* ptr, size_type n) noexcept { //std::cout << "Deallocate(" << static_cast(ptr) << ", " << n << ") to "; if (n == 1) { //std::cout << "freelist\n"; auto node_ptr = reinterpret_cast(ptr); node_ptr->next = list; list = node_ptr; } else { //std::cout << "::operator delete\n"; ::operator delete(ptr); } } template struct rebind { using other = free_list_allocator; }; using pointer = T*; using const_pointer = const T*; using reference = T&; using const_reference = const T&; using difference_type = std::ptrdiff_t; }; #endif jsoncons-1.3.2/test/common/test_utilities.hpp000066400000000000000000000006751477700171100214200ustar00rootroot00000000000000#ifndef JSONCONS_TESTS_TEST_UTILITIES_HPP #define JSONCONS_TESTS_TEST_UTILITIES_HPP #include #include #include template std::string random_binary_string(Generator& gen, std::size_t n) { std::string s; s.reserve(n); for (std::size_t i = 0; i < n; ++i) { auto c = static_cast(std::uniform_int_distribution('0', '1')(gen)); s.push_back(c); } return s; } #endif jsoncons-1.3.2/test/corelib/000077500000000000000000000000001477700171100157545ustar00rootroot00000000000000jsoncons-1.3.2/test/corelib/input/000077500000000000000000000000001477700171100171135ustar00rootroot00000000000000jsoncons-1.3.2/test/corelib/input/JSONTestSuite/000077500000000000000000000000001477700171100215365ustar00rootroot00000000000000jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_number_double_huge_neg_exp.json000066400000000000000000000000161477700171100302750ustar00rootroot00000000000000[123.456e-789]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_number_huge_exp.json000066400000000000000000000002111477700171100261070ustar00rootroot00000000000000[0.4e00669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999006]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_number_neg_int_huge_exp.json000066400000000000000000000000121477700171100276110ustar00rootroot00000000000000[-1e+9999]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_number_pos_double_huge_exp.json000066400000000000000000000000131477700171100303220ustar00rootroot00000000000000[1.5e+9999]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_number_real_neg_overflow.json000066400000000000000000000000201477700171100300000ustar00rootroot00000000000000[-123123e100000]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_number_real_pos_overflow.json000066400000000000000000000000171477700171100300360ustar00rootroot00000000000000[123123e100000]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_number_real_underflow.json000066400000000000000000000000171477700171100273170ustar00rootroot00000000000000[123e-10000000]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_number_too_big_neg_int.json000066400000000000000000000000411477700171100274310ustar00rootroot00000000000000[-123123123123123123123123123123]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_number_too_big_pos_int.json000066400000000000000000000000271477700171100274650ustar00rootroot00000000000000[100000000000000000000]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_number_very_big_negative_int.json000066400000000000000000000000631477700171100306520ustar00rootroot00000000000000[-237462374673276894279832749832423479823246327846]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_object_key_lone_2nd_surrogate.json000066400000000000000000000000141477700171100307250ustar00rootroot00000000000000{"\uDFAA":0}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_1st_surrogate_but_2nd_missing.json000066400000000000000000000000121477700171100322700ustar00rootroot00000000000000["\uDADA"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_1st_valid_surrogate_2nd_invalid.json000066400000000000000000000000201477700171100325510ustar00rootroot00000000000000["\uD888\u1234"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_UTF-16LE_with_BOM.json000066400000000000000000000000141477700171100271550ustar00rootroot00000000000000[""]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_UTF-8_invalid_sequence.json000066400000000000000000000000121477700171100305210ustar00rootroot00000000000000["日ш"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_UTF8_surrogate_U+D800.json000066400000000000000000000000071477700171100300400ustar00rootroot00000000000000[""]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_incomplete_surrogate_and_escape_valid.json000066400000000000000000000000141477700171100340750ustar00rootroot00000000000000["\uD800\n"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_incomplete_surrogate_pair.json000066400000000000000000000000131477700171100315660ustar00rootroot00000000000000["\uDd1ea"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_incomplete_surrogates_escape_valid.json000066400000000000000000000000221477700171100334350ustar00rootroot00000000000000["\uD800\uD800\n"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_invalid_lonely_surrogate.json000066400000000000000000000000121477700171100314230ustar00rootroot00000000000000["\ud800"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_invalid_surrogate.json000066400000000000000000000000151477700171100300440ustar00rootroot00000000000000["\ud800abc"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_invalid_utf-8.json000066400000000000000000000000051477700171100267730ustar00rootroot00000000000000[""]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_inverted_surrogates_U+1D11E.json000066400000000000000000000000201477700171100314100ustar00rootroot00000000000000["\uDd1e\uD834"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_iso_latin_1.json000066400000000000000000000000051477700171100265230ustar00rootroot00000000000000[""]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_lone_second_surrogate.json000066400000000000000000000000121477700171100307030ustar00rootroot00000000000000["\uDFAA"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_lone_utf8_continuation_byte.json000066400000000000000000000000051477700171100320420ustar00rootroot00000000000000[""]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_not_in_unicode_range.json000066400000000000000000000000101477700171100304660ustar00rootroot00000000000000[""]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_overlong_sequence_2_bytes.json000066400000000000000000000000061477700171100314750ustar00rootroot00000000000000[""]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_overlong_sequence_6_bytes.json000066400000000000000000000000121477700171100314760ustar00rootroot00000000000000[""]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_overlong_sequence_6_bytes_null.json000066400000000000000000000000121477700171100325300ustar00rootroot00000000000000[""]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_truncated-utf-8.json000066400000000000000000000000061477700171100272550ustar00rootroot00000000000000[""]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_utf16BE_no_BOM.json000066400000000000000000000000121477700171100266650ustar00rootroot00000000000000[""]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_string_utf16LE_no_BOM.json000066400000000000000000000000121477700171100266770ustar00rootroot00000000000000[""]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_structure_500_nested_arrays.json000066400000000000000000000017501477700171100303130ustar00rootroot00000000000000[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/i_structure_UTF-8_BOM_empty_object.json000066400000000000000000000000051477700171100311200ustar00rootroot00000000000000{}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_1_true_without_comma.json000066400000000000000000000000101477700171100302710ustar00rootroot00000000000000[1 true]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_a_invalid_utf8.json000066400000000000000000000000041477700171100270320ustar00rootroot00000000000000[a]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_colon_instead_of_comma.json000066400000000000000000000000071477700171100306220ustar00rootroot00000000000000["": 1]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_comma_after_close.json000066400000000000000000000000051477700171100276010ustar00rootroot00000000000000[""],jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_comma_and_number.json000066400000000000000000000000041477700171100274240ustar00rootroot00000000000000[,1]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_double_comma.json000066400000000000000000000000061477700171100265660ustar00rootroot00000000000000[1,,2]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_double_extra_comma.json000066400000000000000000000000071477700171100277720ustar00rootroot00000000000000["x",,]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_extra_close.json000066400000000000000000000000061477700171100264500ustar00rootroot00000000000000["x"]]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_extra_comma.json000066400000000000000000000000051477700171100264360ustar00rootroot00000000000000["",]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_incomplete.json000066400000000000000000000000041477700171100262750ustar00rootroot00000000000000["x"jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_incomplete_invalid_value.json000066400000000000000000000000021477700171100311750ustar00rootroot00000000000000[xjsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_inner_array_no_comma.json000066400000000000000000000000061477700171100303210ustar00rootroot00000000000000[3[4]]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_invalid_utf8.json000066400000000000000000000000031477700171100265310ustar00rootroot00000000000000[]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_items_separated_by_semicolon.json000066400000000000000000000000051477700171100320520ustar00rootroot00000000000000[1:2]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_just_comma.json000066400000000000000000000000031477700171100262760ustar00rootroot00000000000000[,]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_just_minus.json000066400000000000000000000000031477700171100263350ustar00rootroot00000000000000[-]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_missing_value.json000066400000000000000000000000111477700171100270010ustar00rootroot00000000000000[ , ""]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_newlines_unclosed.json000066400000000000000000000000131477700171100276560ustar00rootroot00000000000000["a", 4 ,1,jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_number_and_comma.json000066400000000000000000000000041477700171100274240ustar00rootroot00000000000000[1,]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_number_and_several_commas.json000066400000000000000000000000051477700171100313310ustar00rootroot00000000000000[1,,]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_spaces_vertical_tab_formfeed.json000066400000000000000000000000101477700171100317770ustar00rootroot00000000000000[" a"\f]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_star_inside.json000066400000000000000000000000031477700171100264410ustar00rootroot00000000000000[*]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_unclosed.json000066400000000000000000000000031477700171100257510ustar00rootroot00000000000000[""jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_unclosed_trailing_comma.json000066400000000000000000000000031477700171100310160ustar00rootroot00000000000000[1,jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_unclosed_with_new_lines.json000066400000000000000000000000101477700171100310450ustar00rootroot00000000000000[1, 1 ,1jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_array_unclosed_with_object_inside.json000066400000000000000000000000031477700171100316650ustar00rootroot00000000000000[{}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_incomplete_false.json000066400000000000000000000000061477700171100262530ustar00rootroot00000000000000[fals]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_incomplete_null.json000066400000000000000000000000051477700171100261320ustar00rootroot00000000000000[nul]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_incomplete_true.json000066400000000000000000000000051477700171100261370ustar00rootroot00000000000000[tru]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_multidigit_number_then_00.json000066400000000000000000000000041477700171100300000ustar00rootroot00000000000000123jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_++.json000066400000000000000000000000101477700171100245120ustar00rootroot00000000000000[++1234]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_+1.json000066400000000000000000000000041477700171100245230ustar00rootroot00000000000000[+1]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_+Inf.json000066400000000000000000000000061477700171100251010ustar00rootroot00000000000000[+Inf]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_-01.json000066400000000000000000000000051477700171100246060ustar00rootroot00000000000000[-01]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_-1.0..json000066400000000000000000000000071477700171100247440ustar00rootroot00000000000000[-1.0.]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_-2..json000066400000000000000000000000051477700171100246050ustar00rootroot00000000000000[-2.]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_-NaN.json000066400000000000000000000000061477700171100250430ustar00rootroot00000000000000[-NaN]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_.-1.json000066400000000000000000000000051477700171100246040ustar00rootroot00000000000000[.-1]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_.2e-3.json000066400000000000000000000000071477700171100250370ustar00rootroot00000000000000[.2e-3]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_0.1.2.json000066400000000000000000000000071477700171100247510ustar00rootroot00000000000000[0.1.2]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_0.3e+.json000066400000000000000000000000071477700171100250330ustar00rootroot00000000000000[0.3e+]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_0.3e.json000066400000000000000000000000061477700171100247570ustar00rootroot00000000000000[0.3e]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_0.e1.json000066400000000000000000000000061477700171100247550ustar00rootroot00000000000000[0.e1]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_0_capital_E+.json000066400000000000000000000000051477700171100264640ustar00rootroot00000000000000[0E+]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_0_capital_E.json000066400000000000000000000000041477700171100264100ustar00rootroot00000000000000[0E]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_0e+.json000066400000000000000000000000051477700171100246700ustar00rootroot00000000000000[0e+]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_0e.json000066400000000000000000000000041477700171100246140ustar00rootroot00000000000000[0e]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_1.0e+.json000066400000000000000000000000071477700171100250310ustar00rootroot00000000000000[1.0e+]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_1.0e-.json000066400000000000000000000000071477700171100250330ustar00rootroot00000000000000[1.0e-]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_1.0e.json000066400000000000000000000000061477700171100247550ustar00rootroot00000000000000[1.0e]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_1_000.json000066400000000000000000000000111477700171100250250ustar00rootroot00000000000000[1 000.0]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_1eE2.json000066400000000000000000000000061477700171100250060ustar00rootroot00000000000000[1eE2]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_2.e+3.json000066400000000000000000000000071477700171100250350ustar00rootroot00000000000000[2.e+3]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_2.e-3.json000066400000000000000000000000071477700171100250370ustar00rootroot00000000000000[2.e-3]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_2.e3.json000066400000000000000000000000061477700171100247610ustar00rootroot00000000000000[2.e3]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_9.e+.json000066400000000000000000000000061477700171100247600ustar00rootroot00000000000000[9.e+]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_Inf.json000066400000000000000000000000051477700171100250250ustar00rootroot00000000000000[Inf]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_NaN.json000066400000000000000000000000051477700171100247650ustar00rootroot00000000000000[NaN]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_U+FF11_fullwidth_digit_one.json000066400000000000000000000000051477700171100312510ustar00rootroot00000000000000[1]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_expression.json000066400000000000000000000000051477700171100265100ustar00rootroot00000000000000[1+2]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_hex_1_digit.json000066400000000000000000000000051477700171100264750ustar00rootroot00000000000000[0x1]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_hex_2_digits.json000066400000000000000000000000061477700171100266620ustar00rootroot00000000000000[0x42]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_infinity.json000066400000000000000000000000121477700171100261400ustar00rootroot00000000000000[Infinity]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_invalid+-.json000066400000000000000000000000071477700171100260710ustar00rootroot00000000000000[0e+-1]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_invalid-negative-real.json000066400000000000000000000000151477700171100304610ustar00rootroot00000000000000[-123.123foo]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_invalid-utf-8-in-bigger-int.json000066400000000000000000000000061477700171100313320ustar00rootroot00000000000000[123]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_invalid-utf-8-in-exponent.json000066400000000000000000000000061477700171100311430ustar00rootroot00000000000000[1e1]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_invalid-utf-8-in-int.json000066400000000000000000000000051477700171100300740ustar00rootroot00000000000000[0] jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_minus_infinity.json000066400000000000000000000000131477700171100273540ustar00rootroot00000000000000[-Infinity]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_minus_sign_with_trailing_garbage.json000066400000000000000000000000061477700171100330610ustar00rootroot00000000000000[-foo]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_minus_space_1.json000066400000000000000000000000051477700171100270370ustar00rootroot00000000000000[- 1]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_neg_int_starting_with_zero.json000066400000000000000000000000061477700171100317420ustar00rootroot00000000000000[-012]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_neg_real_without_int_part.json000066400000000000000000000000071477700171100315520ustar00rootroot00000000000000[-.123]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_neg_with_garbage_at_end.json000066400000000000000000000000051477700171100310770ustar00rootroot00000000000000[-1x]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_real_garbage_after_e.json000066400000000000000000000000051477700171100303710ustar00rootroot00000000000000[1ea]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_real_with_invalid_utf8_after_e.json000066400000000000000000000000051477700171100324300ustar00rootroot00000000000000[1e]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_real_without_fractional_part.json000066400000000000000000000000041477700171100322460ustar00rootroot00000000000000[1.]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_starting_with_dot.json000066400000000000000000000000061477700171100300460ustar00rootroot00000000000000[.123]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_with_alpha.json000066400000000000000000000000101477700171100264250ustar00rootroot00000000000000[1.2a-3]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_with_alpha_char.json000066400000000000000000000000311477700171100274250ustar00rootroot00000000000000[1.8011670033376514H-308]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_number_with_leading_zero.json000066400000000000000000000000051477700171100300060ustar00rootroot00000000000000[012]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_bad_value.json000066400000000000000000000000141477700171100262110ustar00rootroot00000000000000["x", truth]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_bracket_key.json000066400000000000000000000000111477700171100265470ustar00rootroot00000000000000{[: "x"} jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_comma_instead_of_colon.json000066400000000000000000000000131477700171100307470ustar00rootroot00000000000000{"x", null}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_double_colon.json000066400000000000000000000000121477700171100267310ustar00rootroot00000000000000{"x"::"b"}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_emoji.json000066400000000000000000000000121477700171100253700ustar00rootroot00000000000000{🇨🇭}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_garbage_at_end.json000066400000000000000000000000151477700171100271720ustar00rootroot00000000000000{"a":"a" 123}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_key_with_single_quotes.json000066400000000000000000000000161477700171100310550ustar00rootroot00000000000000{key: 'value'}n_object_lone_continuation_byte_in_key_and_trailing_comma.json000066400000000000000000000000121477700171100362050ustar00rootroot00000000000000jsoncons-1.3.2/test/corelib/input/JSONTestSuite{"":"0",}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_missing_colon.json000066400000000000000000000000071477700171100271340ustar00rootroot00000000000000{"a" b}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_missing_key.json000066400000000000000000000000061477700171100266110ustar00rootroot00000000000000{:"b"}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_missing_semicolon.json000066400000000000000000000000111477700171100300050ustar00rootroot00000000000000{"a" "b"}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_missing_value.json000066400000000000000000000000051477700171100271340ustar00rootroot00000000000000{"a":jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_no-colon.json000066400000000000000000000000041477700171100260120ustar00rootroot00000000000000{"a"jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_non_string_key.json000066400000000000000000000000051477700171100273170ustar00rootroot00000000000000{1:1}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_non_string_key_but_huge_number_instead.json000066400000000000000000000000151477700171100342610ustar00rootroot00000000000000{9999E9999:1}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_repeated_null_null.json000066400000000000000000000000251477700171100301460ustar00rootroot00000000000000{null:null,null:null}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_several_trailing_commas.json000066400000000000000000000000151477700171100311610ustar00rootroot00000000000000{"id":0,,,,,}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_single_quote.json000066400000000000000000000000071477700171100267670ustar00rootroot00000000000000{'a':0}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_trailing_comma.json000066400000000000000000000000111477700171100272510ustar00rootroot00000000000000{"id":0,}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_trailing_comment.json000066400000000000000000000000151477700171100276230ustar00rootroot00000000000000{"a":"b"}/**/jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_trailing_comment_open.json000066400000000000000000000000161477700171100306450ustar00rootroot00000000000000{"a":"b"}/**//jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_trailing_comment_slash_open.json000066400000000000000000000000131477700171100320340ustar00rootroot00000000000000{"a":"b"}//jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_trailing_comment_slash_open_incomplete.json000066400000000000000000000000121477700171100342520ustar00rootroot00000000000000{"a":"b"}/jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_two_commas_in_a_row.json000066400000000000000000000000221477700171100303130ustar00rootroot00000000000000{"a":"b",,"c":"d"}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_unquoted_key.json000066400000000000000000000000101477700171100267770ustar00rootroot00000000000000{a: "b"}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_unterminated-value.json000066400000000000000000000000071477700171100301020ustar00rootroot00000000000000{"a":"ajsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_with_single_string.json000066400000000000000000000000261477700171100301740ustar00rootroot00000000000000{ "foo" : "bar", "a" }jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_object_with_trailing_garbage.json000066400000000000000000000000121477700171100306010ustar00rootroot00000000000000{"a":"b"}#jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_single_space.json000066400000000000000000000000011477700171100253710ustar00rootroot00000000000000 jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_1_surrogate_then_escape.json000066400000000000000000000000131477700171100311170ustar00rootroot00000000000000["\uD800\"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_1_surrogate_then_escape_u.json000066400000000000000000000000141477700171100314440ustar00rootroot00000000000000["\uD800\u"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_1_surrogate_then_escape_u1.json000066400000000000000000000000151477700171100315260ustar00rootroot00000000000000["\uD800\u1"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_1_surrogate_then_escape_u1x.json000066400000000000000000000000161477700171100317170ustar00rootroot00000000000000["\uD800\u1x"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_accentuated_char_no_quotes.json000066400000000000000000000000041477700171100316770ustar00rootroot00000000000000[é]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_backslash_00.json000066400000000000000000000000061477700171100265620ustar00rootroot00000000000000["\"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_escape_x.json000066400000000000000000000000101477700171100261120ustar00rootroot00000000000000["\x00"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_escaped_backslash_bad.json000066400000000000000000000000071477700171100305560ustar00rootroot00000000000000["\\\"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_escaped_ctrl_char_tab.json000066400000000000000000000000061477700171100306030ustar00rootroot00000000000000["\ "]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_escaped_emoji.json000066400000000000000000000000111477700171100271130ustar00rootroot00000000000000["\🌀"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_incomplete_escape.json000066400000000000000000000000051477700171100300060ustar00rootroot00000000000000["\"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_incomplete_escaped_character.json000066400000000000000000000000111477700171100321630ustar00rootroot00000000000000["\u00A"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_incomplete_surrogate.json000066400000000000000000000000161477700171100305630ustar00rootroot00000000000000["\uD834\uDd"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_incomplete_surrogate_escape_invalid.json000066400000000000000000000000221477700171100336060ustar00rootroot00000000000000["\uD800\uD800\x"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_invalid-utf-8-in-escape.json000066400000000000000000000000071477700171100305620ustar00rootroot00000000000000["\u"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_invalid_backslash_esc.json000066400000000000000000000000061477700171100306230ustar00rootroot00000000000000["\a"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_invalid_unicode_escape.json000066400000000000000000000000121477700171100310010ustar00rootroot00000000000000["\uqqqq"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_invalid_utf8_after_escape.json000066400000000000000000000000061477700171100314250ustar00rootroot00000000000000["\"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_leading_uescaped_thinspace.json000066400000000000000000000000151477700171100316420ustar00rootroot00000000000000[\u0020"asd"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_no_quotes_with_bad_escape.json000066400000000000000000000000041477700171100315230ustar00rootroot00000000000000[\n]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_single_doublequote.json000066400000000000000000000000011477700171100302140ustar00rootroot00000000000000"jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_single_quote.json000066400000000000000000000000201477700171100270220ustar00rootroot00000000000000['single quote']jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_single_string_no_double_quotes.json000066400000000000000000000000031477700171100326220ustar00rootroot00000000000000abcjsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_start_escape_unclosed.json000066400000000000000000000000031477700171100306760ustar00rootroot00000000000000["\jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_unescaped_crtl_char.json000066400000000000000000000000071477700171100303210ustar00rootroot00000000000000["aa"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_unescaped_newline.json000066400000000000000000000000141477700171100300170ustar00rootroot00000000000000["new line"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_unescaped_tab.json000066400000000000000000000000051477700171100271240ustar00rootroot00000000000000[" "]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_unicode_CapitalU.json000066400000000000000000000000101477700171100275330ustar00rootroot00000000000000"\UA66D"jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_string_with_trailing_garbage.json000066400000000000000000000000031477700171100306410ustar00rootroot00000000000000""xjsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_100000_opening_arrays.json000066400000000000000000003032401477700171100307100ustar00rootroot00000000000000[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_U+2060_word_joined.json000066400000000000000000000000051477700171100302330ustar00rootroot00000000000000[⁠]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_UTF8_BOM_no_data.json000066400000000000000000000000031477700171100277670ustar00rootroot00000000000000jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_angle_bracket_..json000066400000000000000000000000031477700171100300550ustar00rootroot00000000000000<.>jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_angle_bracket_null.json000066400000000000000000000000101477700171100306700ustar00rootroot00000000000000[]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_array_trailing_garbage.json000066400000000000000000000000041477700171100315370ustar00rootroot00000000000000[1]xjsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_array_with_extra_array_close.json000066400000000000000000000000041477700171100330170ustar00rootroot00000000000000[1]]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_array_with_unclosed_string.json000066400000000000000000000000061477700171100325150ustar00rootroot00000000000000["asd]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_ascii-unicode-identifier.json000066400000000000000000000000031477700171100317130ustar00rootroot00000000000000aåjsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_capitalized_True.json000066400000000000000000000000061477700171100303520ustar00rootroot00000000000000[True]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_close_unopened_array.json000066400000000000000000000000021477700171100312560ustar00rootroot000000000000001]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_comma_instead_of_closing_brace.json000066400000000000000000000000131477700171100332210ustar00rootroot00000000000000{"x": true,jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_double_array.json000066400000000000000000000000041477700171100275300ustar00rootroot00000000000000[][]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_end_array.json000066400000000000000000000000011477700171100270210ustar00rootroot00000000000000]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_incomplete_UTF8_BOM.json000066400000000000000000000000041477700171100305220ustar00rootroot00000000000000{}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_lone-invalid-utf-8.json000066400000000000000000000000011477700171100303770ustar00rootroot00000000000000jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_lone-open-bracket.json000066400000000000000000000000011477700171100303620ustar00rootroot00000000000000[jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_no_data.json000066400000000000000000000000001477700171100264610ustar00rootroot00000000000000jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_null-byte-outside-string.json000066400000000000000000000000031477700171100317500ustar00rootroot00000000000000[]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_number_with_trailing_garbage.json000066400000000000000000000000021477700171100327420ustar00rootroot000000000000002@jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_object_followed_by_closing_object.json000066400000000000000000000000031477700171100337560ustar00rootroot00000000000000{}}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_object_unclosed_no_value.json000066400000000000000000000000041477700171100321120ustar00rootroot00000000000000{"":jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_object_with_comment.json000066400000000000000000000000241477700171100311050ustar00rootroot00000000000000{"a":/*comment*/"b"}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_object_with_trailing_garbage.json000066400000000000000000000000171477700171100327260ustar00rootroot00000000000000{"a": true} "x"jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_open_array_apostrophe.json000066400000000000000000000000021477700171100314610ustar00rootroot00000000000000['jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_open_array_comma.json000066400000000000000000000000021477700171100303710ustar00rootroot00000000000000[,jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_open_array_object.json000066400000000000000000007502211477700171100305620ustar00rootroot00000000000000[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"": jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_open_array_open_object.json000066400000000000000000000000021477700171100315640ustar00rootroot00000000000000[{jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_open_array_open_string.json000066400000000000000000000000031477700171100316250ustar00rootroot00000000000000["ajsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_open_array_string.json000066400000000000000000000000041477700171100306050ustar00rootroot00000000000000["a"jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_open_object.json000066400000000000000000000000011477700171100273440ustar00rootroot00000000000000{jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_open_object_close_array.json000066400000000000000000000000021477700171100317300ustar00rootroot00000000000000{]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_open_object_comma.json000066400000000000000000000000021477700171100305210ustar00rootroot00000000000000{,jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_open_object_open_array.json000066400000000000000000000000021477700171100315640ustar00rootroot00000000000000{[jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_open_object_open_string.json000066400000000000000000000000031477700171100317550ustar00rootroot00000000000000{"ajsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_open_object_string_with_apostrophes.json000066400000000000000000000000041477700171100344170ustar00rootroot00000000000000{'a'jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_open_open.json000066400000000000000000000000201477700171100270400ustar00rootroot00000000000000["\{["\{["\{["\{jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_single_eacute.json000066400000000000000000000000011477700171100276640ustar00rootroot00000000000000jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_single_star.json000066400000000000000000000000011477700171100273670ustar00rootroot00000000000000*jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_trailing_#.json000066400000000000000000000000141477700171100270740ustar00rootroot00000000000000{"a":"b"}#{}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_uescaped_LF_before_string.json000066400000000000000000000000121477700171100321410ustar00rootroot00000000000000[\u000A""]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_unclosed_array.json000066400000000000000000000000021477700171100300700ustar00rootroot00000000000000[1jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_unclosed_array_partial_null.json000066400000000000000000000000141477700171100326410ustar00rootroot00000000000000[ false, nuljsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_unclosed_array_unfinished_false.json000066400000000000000000000000141477700171100334610ustar00rootroot00000000000000[ true, falsjsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_unclosed_array_unfinished_true.json000066400000000000000000000000141477700171100333460ustar00rootroot00000000000000[ false, trujsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_unclosed_object.json000066400000000000000000000000141477700171100302230ustar00rootroot00000000000000{"asd":"asd"jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_unicode-identifier.json000066400000000000000000000000021477700171100306240ustar00rootroot00000000000000åjsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_whitespace_U+2060_word_joiner.json000066400000000000000000000000051477700171100324650ustar00rootroot00000000000000[⁠]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/n_structure_whitespace_formfeed.json000066400000000000000000000000031477700171100310620ustar00rootroot00000000000000[ ]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_array_arraysWithSpaces.json000066400000000000000000000000071477700171100274500ustar00rootroot00000000000000[[] ]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_array_empty-string.json000066400000000000000000000000041477700171100266130ustar00rootroot00000000000000[""]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_array_empty.json000066400000000000000000000000021477700171100253050ustar00rootroot00000000000000[]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_array_ending_with_newline.json000066400000000000000000000000051477700171100301720ustar00rootroot00000000000000["a"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_array_false.json000066400000000000000000000000071477700171100252460ustar00rootroot00000000000000[false]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_array_heterogeneous.json000066400000000000000000000000221477700171100270250ustar00rootroot00000000000000[null, 1, "1", {}]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_array_null.json000066400000000000000000000000061477700171100251250ustar00rootroot00000000000000[null]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_array_with_1_and_newline.json000066400000000000000000000000041477700171100277070ustar00rootroot00000000000000[1 ]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_array_with_leading_space.json000066400000000000000000000000041477700171100277620ustar00rootroot00000000000000 [1]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_array_with_several_null.json000066400000000000000000000000241477700171100277010ustar00rootroot00000000000000[1,null,null,null,2]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_array_with_trailing_space.json000066400000000000000000000000041477700171100301700ustar00rootroot00000000000000[2] jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_number.json000066400000000000000000000000101477700171100242400ustar00rootroot00000000000000[123e65]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_number_0e+1.json000066400000000000000000000000061477700171100247650ustar00rootroot00000000000000[0e+1]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_number_0e1.json000066400000000000000000000000051477700171100247110ustar00rootroot00000000000000[0e1]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_number_after_space.json000066400000000000000000000000041477700171100265770ustar00rootroot00000000000000[ 4]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_number_double_close_to_zero.json000066400000000000000000000001241477700171100305260ustar00rootroot00000000000000[-0.000000000000000000000000000000000000000000000000000000000000000000000000000001] jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_number_int_with_exp.json000066400000000000000000000000061477700171100270260ustar00rootroot00000000000000[20e1]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_number_minus_zero.json000066400000000000000000000000041477700171100265150ustar00rootroot00000000000000[-0]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_number_negative_int.json000066400000000000000000000000061477700171100270010ustar00rootroot00000000000000[-123]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_number_negative_one.json000066400000000000000000000000041477700171100267660ustar00rootroot00000000000000[-1]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_number_negative_zero.json000066400000000000000000000000041477700171100271640ustar00rootroot00000000000000[-0]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_number_real_capital_e.json000066400000000000000000000000061477700171100272510ustar00rootroot00000000000000[1E22]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_number_real_capital_e_neg_exp.json000066400000000000000000000000061477700171100307560ustar00rootroot00000000000000[1E-2]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_number_real_capital_e_pos_exp.json000066400000000000000000000000061477700171100310060ustar00rootroot00000000000000[1E+2]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_number_real_exponent.json000066400000000000000000000000101477700171100271630ustar00rootroot00000000000000[123e45]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_number_real_fraction_exponent.json000066400000000000000000000000141477700171100310540ustar00rootroot00000000000000[123.456e78]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_number_real_neg_exp.json000066400000000000000000000000061477700171100267550ustar00rootroot00000000000000[1e-2]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_number_real_pos_exponent.json000066400000000000000000000000061477700171100300510ustar00rootroot00000000000000[1e+2]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_number_simple_int.json000066400000000000000000000000051477700171100264670ustar00rootroot00000000000000[123]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_number_simple_real.json000066400000000000000000000000141477700171100266200ustar00rootroot00000000000000[123.456789]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_object.json000066400000000000000000000000321477700171100242220ustar00rootroot00000000000000{"asd":"sdf", "dfg":"fgh"}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_object_basic.json000066400000000000000000000000151477700171100253640ustar00rootroot00000000000000{"asd":"sdf"}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_object_duplicated_key.json000066400000000000000000000000211477700171100272660ustar00rootroot00000000000000{"a":"b","a":"c"}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_object_duplicated_key_and_value.json000066400000000000000000000000211477700171100313040ustar00rootroot00000000000000{"a":"b","a":"b"}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_object_empty.json000066400000000000000000000000021477700171100254350ustar00rootroot00000000000000{}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_object_empty_key.json000066400000000000000000000000061477700171100263110ustar00rootroot00000000000000{"":0}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_object_escaped_null_in_key.json000066400000000000000000000000241477700171100302770ustar00rootroot00000000000000{"foo\u0000bar": 42}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_object_extreme_numbers.json000066400000000000000000000000431477700171100275100ustar00rootroot00000000000000{ "min": -1.0e+28, "max": 1.0e+28 }jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_object_long_strings.json000066400000000000000000000001541477700171100270170ustar00rootroot00000000000000{"x":[{"id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}], "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_object_simple.json000066400000000000000000000000101477700171100255670ustar00rootroot00000000000000{"a":[]}jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_object_string_unicode.json000066400000000000000000000001561477700171100273250ustar00rootroot00000000000000{"title":"\u041f\u043e\u043b\u0442\u043e\u0440\u0430 \u0417\u0435\u043c\u043b\u0435\u043a\u043e\u043f\u0430" }jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_object_with_newlines.json000066400000000000000000000000141477700171100271610ustar00rootroot00000000000000{ "a": "b" }jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_1_2_3_bytes_UTF-8_sequences.json000066400000000000000000000000261477700171100313140ustar00rootroot00000000000000["\u0060\u012a\u12AB"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_accepted_surrogate_pair.json000066400000000000000000000000201477700171100312150ustar00rootroot00000000000000["\uD801\udc37"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_accepted_surrogate_pairs.json000066400000000000000000000000341477700171100314050ustar00rootroot00000000000000["\ud83d\ude39\ud83d\udc8d"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_allowed_escapes.json000066400000000000000000000000241477700171100274750ustar00rootroot00000000000000["\"\\\/\b\f\n\r\t"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_backslash_and_u_escaped_zero.json000066400000000000000000000000131477700171100321650ustar00rootroot00000000000000["\\u0000"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_backslash_doublequotes.json000066400000000000000000000000061477700171100310710ustar00rootroot00000000000000["\""]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_comments.json000066400000000000000000000000211477700171100261650ustar00rootroot00000000000000["a/*b*/c/*d//e"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_double_escape_a.json000066400000000000000000000000071477700171100274360ustar00rootroot00000000000000["\\a"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_double_escape_n.json000066400000000000000000000000071477700171100274530ustar00rootroot00000000000000["\\n"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_escaped_control_character.json000066400000000000000000000000121477700171100315200ustar00rootroot00000000000000["\u0012"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_escaped_noncharacter.json000066400000000000000000000000121477700171100304730ustar00rootroot00000000000000["\uFFFF"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_in_array.json000066400000000000000000000000071477700171100261500ustar00rootroot00000000000000["asd"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_in_array_with_leading_space.json000066400000000000000000000000101477700171100320330ustar00rootroot00000000000000[ "asd"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_last_surrogates_1_and_2.json000066400000000000000000000000201477700171100310430ustar00rootroot00000000000000["\uDBFF\uDFFF"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_nbsp_uescaped.json000066400000000000000000000000211477700171100271530ustar00rootroot00000000000000["new\u00A0line"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_nonCharacterInUTF-8_U+10FFFF.json000066400000000000000000000000101477700171100311100ustar00rootroot00000000000000["􏿿"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_nonCharacterInUTF-8_U+FFFF.json000066400000000000000000000000071477700171100307550ustar00rootroot00000000000000["￿"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_null_escape.json000066400000000000000000000000121477700171100266320ustar00rootroot00000000000000["\u0000"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_one-byte-utf-8.json000066400000000000000000000000121477700171100270230ustar00rootroot00000000000000["\u002c"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_pi.json000066400000000000000000000000061477700171100247530ustar00rootroot00000000000000["π"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_reservedCharacterInUTF-8_U+1BFFF.json000066400000000000000000000000101477700171100320510ustar00rootroot00000000000000["𛿿"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_simple_ascii.json000066400000000000000000000000101477700171100267770ustar00rootroot00000000000000["asd "]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_space.json000066400000000000000000000000031477700171100254330ustar00rootroot00000000000000" "y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json000066400000000000000000000000201477700171100327520ustar00rootroot00000000000000jsoncons-1.3.2/test/corelib/input/JSONTestSuite["\uD834\uDd1e"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_three-byte-utf-8.json000066400000000000000000000000121477700171100273510ustar00rootroot00000000000000["\u0821"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_two-byte-utf-8.json000066400000000000000000000000121477700171100270530ustar00rootroot00000000000000["\u0123"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_u+2028_line_sep.json000066400000000000000000000000071477700171100270550ustar00rootroot00000000000000["
"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_u+2029_par_sep.json000066400000000000000000000000071477700171100267110ustar00rootroot00000000000000["
"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_uEscape.json000066400000000000000000000000341477700171100257310ustar00rootroot00000000000000["\u0061\u30af\u30EA\u30b9"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_uescaped_newline.json000066400000000000000000000000211477700171100276520ustar00rootroot00000000000000["new\u000Aline"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_unescaped_char_delete.json000066400000000000000000000000051477700171100306300ustar00rootroot00000000000000[""]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_unicode.json000066400000000000000000000000121477700171100257660ustar00rootroot00000000000000["\uA66D"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_unicodeEscapedBackslash.json000066400000000000000000000000121477700171100310670ustar00rootroot00000000000000["\u005C"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_unicode_2.json000066400000000000000000000000151477700171100262120ustar00rootroot00000000000000["⍂㈴⍂"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_unicode_U+10FFFE_nonchar.json000066400000000000000000000000201477700171100306240ustar00rootroot00000000000000["\uDBFF\uDFFE"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_unicode_U+1FFFE_nonchar.json000066400000000000000000000000201477700171100305440ustar00rootroot00000000000000["\uD83F\uDFFE"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json000066400000000000000000000000121477700171100313620ustar00rootroot00000000000000["\u200B"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_unicode_U+2064_invisible_plus.json000066400000000000000000000000121477700171100317500ustar00rootroot00000000000000["\u2064"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_unicode_U+FDD0_nonchar.json000066400000000000000000000000121477700171100304330ustar00rootroot00000000000000["\uFDD0"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_unicode_U+FFFE_nonchar.json000066400000000000000000000000121477700171100304640ustar00rootroot00000000000000["\uFFFE"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_unicode_escaped_double_quote.json000066400000000000000000000000121477700171100322210ustar00rootroot00000000000000["\u0022"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_utf8.json000066400000000000000000000000131477700171100252270ustar00rootroot00000000000000["€𝄞"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_string_with_del_character.json000066400000000000000000000000071477700171100301570ustar00rootroot00000000000000["aa"]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_structure_lonely_false.json000066400000000000000000000000051477700171100275500ustar00rootroot00000000000000falsejsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_structure_lonely_int.json000066400000000000000000000000021477700171100272450ustar00rootroot0000000000000042jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_structure_lonely_negative_real.json000066400000000000000000000000041477700171100312620ustar00rootroot00000000000000-0.1jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_structure_lonely_null.json000066400000000000000000000000041477700171100274270ustar00rootroot00000000000000nulljsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_structure_lonely_string.json000066400000000000000000000000051477700171100277640ustar00rootroot00000000000000"asd"jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_structure_lonely_true.json000066400000000000000000000000041477700171100274340ustar00rootroot00000000000000truejsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_structure_string_empty.json000066400000000000000000000000021477700171100276150ustar00rootroot00000000000000""jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_structure_trailing_newline.json000066400000000000000000000000061477700171100304270ustar00rootroot00000000000000["a"] jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_structure_true_in_array.json000066400000000000000000000000061477700171100277400ustar00rootroot00000000000000[true]jsoncons-1.3.2/test/corelib/input/JSONTestSuite/y_structure_whitespace_array.json000066400000000000000000000000041477700171100304250ustar00rootroot00000000000000 [] jsoncons-1.3.2/test/corelib/input/JSON_checker/000077500000000000000000000000001477700171100213505ustar00rootroot00000000000000jsoncons-1.3.2/test/corelib/input/JSON_checker/Acknowledgement.txt000066400000000000000000000001251477700171100252160ustar00rootroot00000000000000These files are from the JSON_checker test suite http://www.json.org/JSON_checker/ jsoncons-1.3.2/test/corelib/input/JSON_checker/fail1.json000066400000000000000000000000741477700171100232400ustar00rootroot00000000000000"A JSON payload should be an object or array, not a string."jsoncons-1.3.2/test/corelib/input/JSON_checker/fail10.json000066400000000000000000000000721477700171100233160ustar00rootroot00000000000000{"Extra value after close": true} "misplaced quoted value"jsoncons-1.3.2/test/corelib/input/JSON_checker/fail11.json000066400000000000000000000000351477700171100233160ustar00rootroot00000000000000{"Illegal expression": 1 + 2}jsoncons-1.3.2/test/corelib/input/JSON_checker/fail12.json000066400000000000000000000000371477700171100233210ustar00rootroot00000000000000{"Illegal invocation": alert()}jsoncons-1.3.2/test/corelib/input/JSON_checker/fail13.json000066400000000000000000000000531477700171100233200ustar00rootroot00000000000000{"Numbers cannot have leading zeroes": 013}jsoncons-1.3.2/test/corelib/input/JSON_checker/fail14.json000066400000000000000000000000371477700171100233230ustar00rootroot00000000000000{"Numbers cannot be hex": 0x14}jsoncons-1.3.2/test/corelib/input/JSON_checker/fail15.json000066400000000000000000000000421477700171100233200ustar00rootroot00000000000000["Illegal backslash escape: \x15"]jsoncons-1.3.2/test/corelib/input/JSON_checker/fail16.json000066400000000000000000000000101477700171100233140ustar00rootroot00000000000000[\naked]jsoncons-1.3.2/test/corelib/input/JSON_checker/fail17.json000066400000000000000000000000421477700171100233220ustar00rootroot00000000000000["Illegal backslash escape: \017"]jsoncons-1.3.2/test/corelib/input/JSON_checker/fail18.json000066400000000000000000000000621477700171100233250ustar00rootroot00000000000000[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]jsoncons-1.3.2/test/corelib/input/JSON_checker/fail19.json000066400000000000000000000000261477700171100233260ustar00rootroot00000000000000{"Missing colon" null}jsoncons-1.3.2/test/corelib/input/JSON_checker/fail2.json000066400000000000000000000000211477700171100232310ustar00rootroot00000000000000["Unclosed array"jsoncons-1.3.2/test/corelib/input/JSON_checker/fail20.json000066400000000000000000000000271477700171100233170ustar00rootroot00000000000000{"Double colon":: null}jsoncons-1.3.2/test/corelib/input/JSON_checker/fail21.json000066400000000000000000000000401477700171100233130ustar00rootroot00000000000000{"Comma instead of colon", null}jsoncons-1.3.2/test/corelib/input/JSON_checker/fail22.json000066400000000000000000000000411477700171100233150ustar00rootroot00000000000000["Colon instead of comma": false]jsoncons-1.3.2/test/corelib/input/JSON_checker/fail23.json000066400000000000000000000000241477700171100233170ustar00rootroot00000000000000["Bad value", truth]jsoncons-1.3.2/test/corelib/input/JSON_checker/fail24.json000066400000000000000000000000201477700171100233140ustar00rootroot00000000000000['single quote']jsoncons-1.3.2/test/corelib/input/JSON_checker/fail25.json000066400000000000000000000000351477700171100233230ustar00rootroot00000000000000[" tab character in string "]jsoncons-1.3.2/test/corelib/input/JSON_checker/fail26.json000066400000000000000000000000461477700171100233260ustar00rootroot00000000000000["tab\ character\ in\ string\ "]jsoncons-1.3.2/test/corelib/input/JSON_checker/fail27.json000066400000000000000000000000161477700171100233240ustar00rootroot00000000000000["line break"]jsoncons-1.3.2/test/corelib/input/JSON_checker/fail28.json000066400000000000000000000000171477700171100233260ustar00rootroot00000000000000["line\ break"]jsoncons-1.3.2/test/corelib/input/JSON_checker/fail29.json000066400000000000000000000000041477700171100233230ustar00rootroot00000000000000[0e]jsoncons-1.3.2/test/corelib/input/JSON_checker/fail3.json000066400000000000000000000000451477700171100232400ustar00rootroot00000000000000{unquoted_key: "keys must be quoted"}jsoncons-1.3.2/test/corelib/input/JSON_checker/fail30.json000066400000000000000000000000051477700171100233140ustar00rootroot00000000000000[0e+]jsoncons-1.3.2/test/corelib/input/JSON_checker/fail31.json000066400000000000000000000000071477700171100233170ustar00rootroot00000000000000[0e+-1]jsoncons-1.3.2/test/corelib/input/JSON_checker/fail32.json000066400000000000000000000000501477700171100233160ustar00rootroot00000000000000{"Comma instead if closing brace": true,jsoncons-1.3.2/test/corelib/input/JSON_checker/fail33.json000066400000000000000000000000141477700171100233170ustar00rootroot00000000000000["mismatch"}jsoncons-1.3.2/test/corelib/input/JSON_checker/fail4.json000066400000000000000000000000201477700171100232320ustar00rootroot00000000000000["extra comma",]jsoncons-1.3.2/test/corelib/input/JSON_checker/fail5.json000066400000000000000000000000301477700171100232340ustar00rootroot00000000000000["double extra comma",,]jsoncons-1.3.2/test/corelib/input/JSON_checker/fail6.json000066400000000000000000000000321477700171100232370ustar00rootroot00000000000000[ , "<-- missing value"]jsoncons-1.3.2/test/corelib/input/JSON_checker/fail7.json000066400000000000000000000000321477700171100232400ustar00rootroot00000000000000["Comma after the close"],jsoncons-1.3.2/test/corelib/input/JSON_checker/fail8.json000066400000000000000000000000201477700171100232360ustar00rootroot00000000000000["Extra close"]]jsoncons-1.3.2/test/corelib/input/JSON_checker/fail9.json000066400000000000000000000000261477700171100232450ustar00rootroot00000000000000{"Extra comma": true,}jsoncons-1.3.2/test/corelib/input/JSON_checker/pass1.json000066400000000000000000000026411477700171100232750ustar00rootroot00000000000000[ "JSON Test Pattern pass1", {"object with 1 member":["array with 1 element"]}, {}, [], -42, true, false, null, { "integer": 1234567890, "real": -9876.543210, "e": 0.123456789e-12, "E": 1.234567890E+34, "": 23456789012E66, "zero": 0, "one": 1, "space": " ", "quote": "\"", "backslash": "\\", "controls": "\b\f\n\r\t", "slash": "/ & \/", "alpha": "abcdefghijklmnopqrstuvwyz", "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ", "digit": "0123456789", "0123456789": "digit", "special": "`1~!@#$%^&*()_+-={':[,]}|;.?", "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A", "true": true, "false": false, "null": null, "array":[ ], "object":{ }, "address": "50 St. James Street", "url": "http://www.JSON.org/", "comment": "// /* */": " ", " s p a c e d " :[1,2 , 3 , 4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7], "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}", "quotes": "" \u0022 %22 0x22 034 "", "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?" : "A key can be any string" }, 0.5 ,98.6 , 99.44 , 1066, 1e1, 0.1e1, 1e-1, 1e00,2e+00,2e-00 ,"rosebud"]jsoncons-1.3.2/test/corelib/input/JSON_checker/pass2.json000066400000000000000000000000641477700171100232730ustar00rootroot00000000000000[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]jsoncons-1.3.2/test/corelib/input/JSON_checker/pass3.json000066400000000000000000000002241477700171100232720ustar00rootroot00000000000000{ "JSON Test Pattern pass3": { "The outermost value": "must be an object or array.", "In this test": "It is an object." } } jsoncons-1.3.2/test/corelib/input/address-book.json000066400000000000000000000003441477700171100223640ustar00rootroot00000000000000{ "address-book" : [ { "name":"Jane Roe", "email":"jane.roe@example.com" }, { "name":"John", "email" : "john.doe@example.com" } ] } jsoncons-1.3.2/test/corelib/input/cyrillic.json000066400000000000000000001002461477700171100216230ustar00rootroot00000000000000{ "Xml": { "SLMS": [ { "-idSLMS": "1", "LMS": [ { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" } ] }, { "-idSLMS": "2", "LMS": [ { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" } ] }, { "-idSLMS": "3", "LMS": [ { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" } ] }, { "-idSLMS": "4", "LMS": [ { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" } ] }, { "-idSLMS": "5", "LMS": [ { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" } ] }, { "-idSLMS": "6", "LMS": [ { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" } ] }, { "-idSLMS": "7", "LMS": [ { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" } ] }, { "-idSLMS": "8", "LMS": [ { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" } ] }, { "-idSLMS": "9", "LMS": [ { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" } ] }, { "-idSLMS": "10", "LMS": [ { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" } ] }, { "-idSLMS": "11", "LMS": [ { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" }, { "PostTh": "Абвгдеёжзик лмнопрстуфхцчшщъ(Кккккккк ккккккк кккккккк)", "PostSh": "Абвгде.жзиклм-но(Кккккккк к.к.)", "KodeMod": "$A", "PostTabNum": "0000000004" } ] }, { "-idSLMS": "12", "LMS": [ { "PostTh": "Департамент ведомственного финансового контроля и аудита МО РФ", "PostSh": "ДВФКиА МО", "KodeMod": "$$", "PostTabNum": "0000000001" }, { "PostTh": "Консультант (Мирошниченко Ирина Владимировна)", "PostSh": "Консультант(Мирошниченко И.В)", "KodeMod": "$5", "PostTabNum": "0000000015" }, { "PostTh": "Главный специалист-эксперт (Власова Екатерина Генадьевнна)", "PostSh": "Гл.спец-эксперт(Власова Е.Г)", "KodeMod": "$7", "PostTabNum": "0000000013" } ] }, { "-idSLMS": "13", "LMS": [ { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" }, { "PostTh": "Учёт обращений граждан (Еееееее еееее ееееее)", "PostSh": "Учет обращений гр.(Ееееееее Е.Е)", "KodeMod": "$d", "PostTabNum": "0000000033" } ] } ] } }jsoncons-1.3.2/test/corelib/input/json-exception-1.json000066400000000000000000000007721477700171100231170ustar00rootroot00000000000000 { // Members "members" : [ { "first_name":"Jane", "last_name":"Roe", "events_attended":10, "accept_waiver_of_liability" : true }, /* Missing *left* brace */ "first_name":"John", "last_name":"Doe", "events_attended":2, "accept_waiver_of_liability" : true } ] } jsoncons-1.3.2/test/corelib/input/json-exception-2.json000066400000000000000000000006411477700171100231130ustar00rootroot00000000000000{ // Members "members" : [ { "first_name":"Jane", "last_name":"Roe", "events_attended":10, "accept_waiver_of_liability" : true }, { "first_name":"John", "last_name":"Doe", "events_attended":2, "accept_waiver_of_liability" : true /* Missing *right* brace */ ] } jsoncons-1.3.2/test/corelib/input/json-multiline-comment.json000066400000000000000000001737431477700171100244360ustar00rootroot00000000000000[ /* { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" }, { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee\nDependable, trustworthy", "comment":"Team player", "salary":"75,000.00" } */ ] jsoncons-1.3.2/test/corelib/input/locations.json000066400000000000000000000007411477700171100220030ustar00rootroot00000000000000 { // Members "members" : [ { "first_name":"Jane", "last_name":"Roe", "events_attended":10, "accept_waiver_of_liability" : true }, /* Error - missing *left* brace */ "first_name":"John", "last_name":"Doe", "events_attended":2, "accept_waiver_of_liability" : true } ] } jsoncons-1.3.2/test/corelib/input/members.json000066400000000000000000000007001477700171100214350ustar00rootroot00000000000000 { // Members "members" : [ { "first_name":"Jane", "last_name":"Roe", "events_attended":10, "accept_waiver_of_liability" : true }, { "first_name":"John", "last_name":"Doe", "events_attended":2, "accept_waiver_of_liability" : true } ] } jsoncons-1.3.2/test/corelib/input/persons.json000066400000000000000000000000451477700171100214760ustar00rootroot00000000000000{ "persons" : ["John","David"] } jsoncons-1.3.2/test/corelib/output/000077500000000000000000000000001477700171100173145ustar00rootroot00000000000000jsoncons-1.3.2/test/corelib/output/address-book-new.json000066400000000000000000000004121477700171100233500ustar00rootroot00000000000000{ "address-book": [ { "first-name": "Jane", "last-name": "Roe", "email2": "jane.roe@example.com" }, { "first-name": "John", "email2": "john.doe@example.com" } ] }jsoncons-1.3.2/test/corelib/output/store.cbor000066400000000000000000000001451477700171100213170ustar00rootroot00000000000000kapplicationfhikinghreputonsiassertionhadvancederatediMarilyn CeraterlHikingAsylumfrating?jsoncons-1.3.2/test/corelib/src/000077500000000000000000000000001477700171100165435ustar00rootroot00000000000000jsoncons-1.3.2/test/corelib/src/JSONTestSuite_tests.cpp000066400000000000000000000042441477700171100231200ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #include #include #include #include #include #if (defined JSONCONS_HAS_FILESYSTEM && defined(_MSC_VER)) #include namespace fs = std::filesystem; #endif using namespace jsoncons; #if (defined JSONCONS_HAS_FILESYSTEM && defined(_MSC_VER)) TEST_CASE("JSON Parsing Test Suite") { SECTION("Expected success") { std::string path = "./corelib/input/JSONTestSuite"; for (auto& p : fs::directory_iterator(path)) { if (fs::exists(p) && fs::is_regular_file(p) && p.path().extension() == ".json" && p.path().filename().c_str()[0] == 'y') { std::ifstream is(p.path().c_str()); auto options = json_options{}.allow_comments(false); json_stream_reader reader(is, options); std::error_code ec; reader.read(ec); if (JSONCONS_UNLIKELY(ec)) { std::cout << p.path().filename().string() << " failed, expected success\n"; } CHECK_FALSE(ec); } } } SECTION("Expected failure") { std::string path = "./corelib/input/JSONTestSuite"; for (auto& p : fs::directory_iterator(path)) { if (fs::exists(p) && fs::is_regular_file(p) && p.path().extension() == ".json" && p.path().filename().c_str()[0] == 'n') { std::ifstream is(p.path().c_str()); auto options = json_options{}.allow_comments(false); json_stream_reader reader(is, options); std::error_code ec; reader.read(ec); if (!ec) { std::cout << p.path().filename().string() << " succeeded, expected failure\n"; } // TODO: revisit // CHECK(ec); } } } } #endif jsoncons-1.3.2/test/corelib/src/decode_traits_tests.cpp000066400000000000000000000101771477700171100233100ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include using namespace jsoncons; TEST_CASE("decode_traits primitive") { SECTION("is_primitive") { CHECK(extension_traits::is_primitive::value); } SECTION("uint64_t") { std::string input = R"(1000)"; json_decoder decoder; std::error_code ec; json_string_cursor cursor(input); auto val = decode_traits::decode(cursor,decoder,ec); CHECK(val == 1000); } SECTION("vector of uint64_t") { using test_type = std::vector; std::string input = R"([1000,1001,1002])"; json_decoder decoder; std::error_code ec; json_string_cursor cursor(input); auto val = decode_traits::decode(cursor,decoder,ec); REQUIRE(3 == val.size()); CHECK(val[0] == 1000); CHECK(val[1] == 1001); CHECK(val[2] == 1002); } } TEST_CASE("decode_traits std::string") { SECTION("is_string") { CHECK(extension_traits::is_string::value); } SECTION("string") { std::string input = R"("Hello World")"; json_decoder decoder; std::error_code ec; json_string_cursor cursor(input); auto val = decode_traits::decode(cursor,decoder,ec); CHECK((val == "Hello World")); } } TEST_CASE("decode_traits std::pair") { SECTION("std::pair") { std::string input = R"(["first","second"])"; using test_type = std::pair; json_decoder decoder; std::error_code ec; json_string_cursor cursor(input); auto val = decode_traits::decode(cursor,decoder,ec); CHECK((val == test_type("first","second"))); } SECTION("vector of std::pair") { std::string input = R"([["first","second"],["one","two"]])"; using test_type = std::vector>; json_decoder decoder; std::error_code ec; json_string_cursor cursor(input); auto val = decode_traits::decode(cursor,decoder,ec); REQUIRE_FALSE(ec); REQUIRE(2 == val.size()); CHECK((val[0] == test_type::value_type("first","second"))); CHECK((val[1] == test_type::value_type("one","two"))); } SECTION("map of std::string-std::pair") { std::string input = R"({"foo": [100,1.5],"bar" : [200,2.5]})"; using test_type = std::map>; json_decoder decoder; std::error_code ec; json_string_cursor cursor(input); auto val = decode_traits::decode(cursor,decoder,ec); REQUIRE_FALSE(ec); REQUIRE(2 == val.size()); REQUIRE(val.count("foo") > 0); REQUIRE(val.count("bar") > 0); CHECK(val["foo"].first == 100); CHECK(val["foo"].second == 1.5); CHECK(val["bar"].first == 200); CHECK(val["bar"].second == 2.5); } SECTION("Conversion error") { std::string input = R"({"foo": [100,1.5,30],"bar" : [200,2.5]])"; using test_type = std::map>; json_decoder decoder; std::error_code ec; json_string_cursor cursor(input); auto val = decode_traits::decode(cursor,decoder,ec); CHECK(ec == conv_errc::not_pair); } } TEST_CASE("decode_traits deserialization errors") { SECTION("Expected comma or right brace") { std::string input = R"({"foo": [100,1.5],"bar" : [200,2.5]])"; using test_type = std::map>; json_decoder decoder; std::error_code ec; json_string_cursor cursor(input); auto val = decode_traits::decode(cursor,decoder,ec); CHECK(ec == json_errc::expected_comma_or_rbrace); } } jsoncons-1.3.2/test/corelib/src/detail/000077500000000000000000000000001477700171100200055ustar00rootroot00000000000000jsoncons-1.3.2/test/corelib/src/detail/from_integer_tests.cpp000066400000000000000000000003461477700171100244160ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include using namespace jsoncons; TEST_CASE("detail::from_integer tests") { SECTION("") { } } jsoncons-1.3.2/test/corelib/src/detail/optional_tests.cpp000066400000000000000000000100731477700171100235610ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include using jsoncons::detail::optional; using jsoncons::json; TEST_CASE("optional constructor tests") { std::string input = R"( [ { "enrollmentNo" : 100, "firstName" : "Tom", "lastName" : "Cochrane", "mark" : 55 }, { "enrollmentNo" : 101, "firstName" : "Catherine", "lastName" : "Smith", "mark" : 95 }, { "enrollmentNo" : 102, "firstName" : "William", "lastName" : "Skeleton", "mark" : 60 } ] )"; SECTION("optional()") { optional x; CHECK_FALSE(x.has_value()); CHECK_FALSE(x); } SECTION("optional(json)") { json j = json::parse(input); optional x{j}; CHECK(x.has_value()); bool b(x); CHECK(b); json* p = x.operator->(); REQUIRE(p); REQUIRE(3 == p->size()); json& ref = x.value(); REQUIRE(3 == ref.size()); const auto& cref = *x; REQUIRE(3 == cref.size()); x = j[1]; REQUIRE(x.has_value()); const auto& cref2 = *x; REQUIRE(cref2.is_object()); REQUIRE(4 == cref2.size()); CHECK(cref2["firstName"].as() == std::string("Catherine")); } SECTION("optional(int64_t) from const") { const int64_t val = 10; optional x{val}; CHECK(x.has_value()); bool b(x); CHECK(b); optional y; y = val; } SECTION("optional(const optional&)") { optional x(10); optional y(x); CHECK(y.has_value()); bool b(y); CHECK(b); } SECTION("optional(const optional&) from const") { const optional x(10); optional y(x); CHECK(y.has_value()); bool b(y); CHECK(b); } } TEST_CASE("optional swap tests") { SECTION("with value and with value") { optional> a(std::vector{1.0,2.0,3.0,4.0}); optional> b(std::vector{5.0,6.0,7.0,8.0}); swap(a,b); CHECK(a.has_value()); CHECK(b.has_value()); CHECK(a.value()[0] == 5.0); CHECK(a.value()[1] == 6.0); CHECK(a.value()[2] == 7.0); CHECK(a.value()[3] == 8.0); CHECK(b.value()[0] == 1.0); CHECK(b.value()[1] == 2.0); CHECK(b.value()[2] == 3.0); CHECK(b.value()[3] == 4.0); } SECTION("with value and without value") { optional> a(std::vector{1.0, 2.0, 3.0, 4.0}); optional> b; swap(a, b); CHECK_FALSE(a.has_value()); CHECK(b.has_value()); CHECK(b.value()[0] == 1.0); CHECK(b.value()[1] == 2.0); CHECK(b.value()[2] == 3.0); CHECK(b.value()[3] == 4.0); } SECTION("without value and without value") { optional> a; optional> b; swap(a, b); CHECK_FALSE(a.has_value()); CHECK_FALSE(b.has_value()); } } TEST_CASE("optional&& assignment tests") { SECTION("with value from with value") { optional> a(std::vector{1.0,2.0,3.0,4.0}); optional> b(std::vector{5.0,6.0,7.0,8.0}); a = std::move(b); CHECK(a.has_value()); CHECK(a.value()[0] == 5.0); CHECK(a.value()[1] == 6.0); CHECK(a.value()[2] == 7.0); CHECK(a.value()[3] == 8.0); } SECTION("with value from no value") { optional> a(std::vector{1.0,2.0,3.0,4.0}); optional> b; a = std::move(b); CHECK_FALSE(a.has_value()); } } jsoncons-1.3.2/test/corelib/src/detail/span_tests.cpp000066400000000000000000000024131477700171100226740ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include TEST_CASE("jsoncons::detail::span constructor tests") { SECTION("jsoncons::detail::span()") { jsoncons::detail::span s; CHECK(s.empty()); } SECTION("jsoncons::detail::span(pointer,size_type)") { std::vector v = {1,2,3,4}; jsoncons::detail::span s(v.data(), v.size()); CHECK(s.size() == v.size()); CHECK(s.data() == v.data()); } SECTION("jsoncons::detail::span(C& c)") { using C = std::vector; C c = {{1,2,3,4}}; jsoncons::detail::span s(c); CHECK(s.size() == c.size()); CHECK(s.data() == c.data()); } SECTION("jsoncons::detail::span(C c[])") { double c[] = {1,2,3,4}; jsoncons::detail::span s{ c }; CHECK(4 == s.size()); CHECK(s.data() == c); } SECTION("jsoncons::detail::span(std::array)") { std::array c = {{1,2,3,4}}; jsoncons::detail::span s(c); CHECK(4 == s.size()); CHECK(s.data() == c.data()); } } jsoncons-1.3.2/test/corelib/src/detail/string_view_tests.cpp000066400000000000000000000011111477700171100242650ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include TEST_CASE("string_view tests") { SECTION("test 1") { std::unordered_map map; std::string key1{"Foo"}; std::string key2{"Bar"}; map.emplace(key1, 1); map.emplace(key2, 2); CHECK(map.find(key1) != map.end()); CHECK(1 == map[key1]); CHECK(map.find(key2) != map.end()); CHECK(2 == map[key2]); } } jsoncons-1.3.2/test/corelib/src/detail/to_integer_tests.cpp000066400000000000000000000125011477700171100240710ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include using namespace jsoncons; TEST_CASE("detail::to_integer tests") { SECTION("") { std::string s = "-"; int64_t val; auto result = jsoncons::detail::to_integer(s.data(), s.length(), val); REQUIRE_FALSE(result); CHECK(result.ec == jsoncons::detail::to_integer_errc::invalid_number); } SECTION("-") { std::string s = "-"; int64_t val; auto result = jsoncons::detail::to_integer(s.data(), s.length(), val); REQUIRE_FALSE(result); CHECK(result.ec == jsoncons::detail::to_integer_errc::invalid_number); } SECTION("min int64_t") { std::string s = "-9223372036854775808"; int64_t val; auto result = jsoncons::detail::to_integer(s.data(), s.length(), val); REQUIRE(result); CHECK(val == (std::numeric_limits::min)()); } SECTION("max int64_t") { std::string s = "9223372036854775807"; int64_t val; auto result = jsoncons::detail::to_integer(s.data(), s.length(), val); REQUIRE(result); CHECK(val == (std::numeric_limits::max)()); } SECTION("max uint64_t") { std::string s = "18446744073709551615"; uint64_t val; auto result = jsoncons::detail::to_integer(s.data(), s.length(), val); REQUIRE(result); CHECK(val == (std::numeric_limits::max)()); } SECTION("min int64_t - 1") { std::string s = "-9223372036854775809"; int64_t val; auto result = jsoncons::detail::to_integer(s.data(), s.length(), val); REQUIRE_FALSE(result); CHECK(result.ec == jsoncons::detail::to_integer_errc::overflow); } SECTION("max int64_t + 1") { std::string s = "9223372036854775808"; int64_t val; auto result = jsoncons::detail::to_integer(s.data(), s.length(), val); REQUIRE_FALSE(result); CHECK(result.ec == jsoncons::detail::to_integer_errc::overflow); } } TEST_CASE("detail::decimal_to_integer tests") { SECTION("") { std::string s = "-"; int64_t val; auto result = jsoncons::detail::decimal_to_integer(s.data(), s.length(), val); REQUIRE_FALSE(result); CHECK(result.ec == jsoncons::detail::to_integer_errc::invalid_number); } SECTION("-") { std::string s = "-"; int64_t val; auto result = jsoncons::detail::decimal_to_integer(s.data(), s.length(), val); REQUIRE_FALSE(result); CHECK(result.ec == jsoncons::detail::to_integer_errc::invalid_number); } SECTION("min int64_t") { std::string s = "-9223372036854775808"; int64_t val; auto result = jsoncons::detail::decimal_to_integer(s.data(), s.length(), val); REQUIRE(result); CHECK(val == (std::numeric_limits::min)()); } SECTION("max int64_t") { std::string s = "9223372036854775807"; int64_t val; auto result = jsoncons::detail::decimal_to_integer(s.data(), s.length(), val); REQUIRE(result); CHECK(val == (std::numeric_limits::max)()); } SECTION("min int64_t - 1") { std::string s = "-9223372036854775809"; int64_t val; auto result = jsoncons::detail::decimal_to_integer(s.data(), s.length(), val); REQUIRE_FALSE(result); CHECK(result.ec == jsoncons::detail::to_integer_errc::overflow); } SECTION("max int64_t + 1") { std::string s = "9223372036854775808"; int64_t val; auto result = jsoncons::detail::decimal_to_integer(s.data(), s.length(), val); REQUIRE_FALSE(result); CHECK(result.ec == jsoncons::detail::to_integer_errc::overflow); } } TEST_CASE("detail::to_integer_unchecked tests") { SECTION("max uint64_t") { std::string s = "18446744073709551615"; uint64_t val; auto result = jsoncons::detail::to_integer_unchecked(s.data(), s.length(), val); REQUIRE(result); CHECK(val == (std::numeric_limits::max)()); } SECTION("min int64_t") { std::string s = "-9223372036854775808"; int64_t val; auto result = jsoncons::detail::to_integer_unchecked(s.data(), s.length(), val); REQUIRE(result); CHECK(val == (std::numeric_limits::min)()); } SECTION("max int64_t") { std::string s = "9223372036854775807"; int64_t val; auto result = jsoncons::detail::to_integer_unchecked(s.data(), s.length(), val); REQUIRE(result); CHECK(val == (std::numeric_limits::max)()); } SECTION("min int64_t - 1") { std::string s = "-9223372036854775809"; int64_t val; auto result = jsoncons::detail::to_integer_unchecked(s.data(), s.length(), val); REQUIRE_FALSE(result); CHECK(result.ec == jsoncons::detail::to_integer_errc::overflow); } SECTION("max int64_t + 1") { std::string s = "9223372036854775808"; int64_t val; auto result = jsoncons::detail::to_integer_unchecked(s.data(), s.length(), val); REQUIRE_FALSE(result); CHECK(result.ec == jsoncons::detail::to_integer_errc::overflow); } } jsoncons-1.3.2/test/corelib/src/detect_encoding_tests.cpp000066400000000000000000000024401477700171100236070ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("Detect json encoding") { SECTION("UTF16LE with lead surrogate") { std::vector v = {'\"',0x00,0xD8,0x00,0xDB,0xFF,'\"',0x00}; auto r = jsoncons::unicode_traits::detect_json_encoding(v.data(),v.size()); CHECK(r.encoding == jsoncons::unicode_traits::encoding_kind::utf16le); CHECK(r.ptr == v.data()); } SECTION("UTF16BE with lead surrogate") { std::vector v = {0x00,'\"',0x00,0xD8,0xFF,0xDB,0x00,'\"'}; auto r = jsoncons::unicode_traits::detect_json_encoding(v.data(),v.size()); CHECK(r.encoding == jsoncons::unicode_traits::encoding_kind::utf16be); CHECK(r.ptr == v.data()); } } TEST_CASE("Detect encoding from bom") { SECTION("detect utf8") { std::string input = "\xEF\xBB\xBF[1,2,3]"; auto r = jsoncons::unicode_traits::detect_encoding_from_bom(input.data(),input.size()); REQUIRE(r.encoding == jsoncons::unicode_traits::encoding_kind::utf8); CHECK(r.ptr == (input.data()+3)); } } jsoncons-1.3.2/test/corelib/src/double_round_trip_tests.cpp000066400000000000000000000017411477700171100242130ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("test_round_trip") { { std::ostringstream os; double d = 42.229999999999997; json j = d; os << j; CHECK(json::parse(os.str()).as() == d); } { std::ostringstream os; double d = 9.0099999999999998; json j = d; os << j; CHECK(json::parse(os.str()).as() == d); } { std::ostringstream os; double d = 13.449999999999999; json j = d; os << j; CHECK(json::parse(os.str()).as() == d); } { std::ostringstream os; double d = 0.000071; json j = d; os << j; CHECK(json::parse(os.str()).as() == d); } } jsoncons-1.3.2/test/corelib/src/double_to_string_tests.cpp000066400000000000000000000117171477700171100240420ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include using namespace jsoncons; template std::basic_string float_to_string(double val, int precision) { jsoncons::detail::write_double print(float_chars_format::general,precision); std::basic_string s; jsoncons::string_sink> writer(s); print(val, writer); writer.flush(); return s; } TEST_CASE("test_double_to_string") { double x = 1.0e100; std::string s = float_to_string(x, std::numeric_limits::digits10); //std::cout << x << ": " << s << '\n'; CHECK(s == std::string("1e+100")); x = 1.0e-100; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::string("1e-100")); x = 0.123456789e-100; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::string("1.23456789e-101")); x = 0.123456789e100; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::string("1.23456789e+99")); x = 1234563; s = float_to_string(x, 6); CHECK(s == std::string("1.23456e+06")); x = 0.0000001234563; s = float_to_string(x, 6); CHECK(s == std::string("1.23456e-07")); x = -1.0e+100; s = float_to_string(x, std::numeric_limits::digits10); std::cout << s << "\n"; CHECK(s == std::string("-1e+100")); x = -1.0e-100; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::string("-1e-100")); x = 0; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::string("0.0")); x = -0; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::string("0.0")); x = 1; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::string("1.0")); x = 0.1; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::string("0.1")); x = 1.1; s = float_to_string(x, 17); CHECK(s == std::string("1.1000000000000001")); x = -1; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::string("-1.0")); x = 10; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::string("10.0")); x = -10; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::string("-10.0")); x = 11; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::string("11.0")); x = -11; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::string("-11.0")); } #if defined(_MSC_VER) TEST_CASE("test_locale") { wchar_t * loc = _wsetlocale(LC_ALL, L"de-DE"); CHECK_FALSE(loc == nullptr); double x = 123456789.0123; std::wstring s = float_to_string(x, 13); //std::wcout << std::setprecision(13) << x << L": " << s << '\n'; CHECK(std::wstring(L"123456789.0123") == s); _wsetlocale(LC_ALL, L"C"); } #endif TEST_CASE("test_double_to_wstring") { double x = 1.0e100; std::wstring s = float_to_string(x, std::numeric_limits::digits10); //std::wcout << x << L":" << s << '\n'; CHECK(s == std::wstring(L"1e+100")); x = 1.0e-100; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::wstring(L"1e-100")); x = -1.0e+100; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::wstring(L"-1e+100")); x = -1.0e-100; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::wstring(L"-1e-100")); x = 0; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::wstring(L"0.0")); x = -0; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::wstring(L"0.0")); x = 1; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::wstring(L"1.0")); x = -1; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::wstring(L"-1.0")); x = 10; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::wstring(L"10.0")); x = -10; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::wstring(L"-10.0")); x = 11; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::wstring(L"11.0")); x = -11; s = float_to_string(x, std::numeric_limits::digits10); CHECK(s == std::wstring(L"-11.0")); } jsoncons-1.3.2/test/corelib/src/dtoa_tests.cpp000066400000000000000000000046561477700171100214330ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include using namespace jsoncons; static void check_safe_dtoa(double x, const std::vector& expected) { std::string s; bool result = jsoncons::detail::dtoa_general(x, '.', s, std::false_type()); if (!result) { std::cout << "safe dtoa_general failed " << s << "\n"; } REQUIRE(result); bool accept = false; for (std::size_t i = 0; !accept && i < expected.size(); ++i) { accept = s == expected[i]; } if (!accept) { std::cout << "safe dtoa_general does not match expected " << x << " " << s << "\n"; } CHECK(accept); } static void check_dtoa(double x, const std::vector& expected) { std::string s; bool result = jsoncons::detail::dtoa_general(x, '.', s); if (!result) { std::cout << "dtoa_general failed " << s << "\n"; } REQUIRE(result); bool accept = false; for (std::size_t i = 0; !accept && i < expected.size(); ++i) { accept = s == expected[i]; } if (!accept) { std::cout << "dtoa_general does not match expected " << x << " " << s << "\n"; } CHECK(accept); check_safe_dtoa(x,expected); } TEST_CASE("test grisu3") { check_dtoa(1.0e100, {"1e+100"}); check_dtoa(1.0e-100, {"1e-100"}); check_dtoa(0.123456789e-100, {"1.23456789e-101"}); check_dtoa(0.123456789e100, {"1.23456789e+99"}); check_dtoa(1234563, {"1234563.0"}); check_dtoa(0.0000001234563, {"1.234563e-07"}); check_dtoa(-1.0e+100, {"-1e+100"}); check_dtoa(-1.0e-100, {"-1e-100"}); check_dtoa(0, {"0.0"}); check_dtoa(-0, {"0.0"}); check_dtoa(1, {"1.0"}); check_dtoa(0.1, {"0.1"}); check_dtoa(1.1, {"1.1"}); check_dtoa(-1, {"-1.0"}); check_dtoa(10, {"10.0"}); check_dtoa(-10, {"-10.0"}); check_dtoa(-11, {"-11.0"}); check_dtoa(12.272727012634277, {"12.272727012634277"}); check_dtoa(4094.1111111111113, {"4094.1111111111113"}); check_dtoa(0.119942, {"0.119942"}); check_dtoa(-36.973846435546875, {"-36.973846435546875"}); check_dtoa(42.229999999999997, {"42.23"}); check_dtoa(9.0099999999999998, {"9.01"}); check_dtoa(13.449999999999999, {"13.45"}); check_dtoa(0.000071, {"7.1e-05"}); } jsoncons-1.3.2/test/corelib/src/encode_decode_json_tests.cpp000066400000000000000000000211321477700171100242610ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include namespace { class MyIterator { const char* p_; public: using iterator_category = std::input_iterator_tag; using value_type = char; using difference_type = std::ptrdiff_t; using pointer = const char*; using reference = const char&; MyIterator(const char* p) : p_(p) { } reference operator*() const { return *p_; } pointer operator->() const { return p_; } MyIterator& operator++() { ++p_; return *this; } MyIterator operator++(int) { MyIterator temp(*this); ++*this; return temp; } bool operator!=(const MyIterator& rhs) const { return p_ != rhs.p_; } }; } // namespace using namespace jsoncons; TEST_CASE("encode and decode json") { json j(std::make_pair(false,std::string("foo"))); SECTION("string source") { std::string s; encode_json(j, s); json result = decode_json(s); CHECK(result == j); } SECTION("stream source") { std::stringstream ss; encode_json(j, ss); json result = decode_json(ss); CHECK(result == j); } SECTION("iterator source") { std::string s; encode_json(j, s); json result = decode_json(s.begin(), s.end()); CHECK(result == j); } } TEST_CASE("encode and decode wjson") { wjson j(std::make_pair(false,std::wstring(L"foo"))); SECTION("string source") { std::wstring s; encode_json(j, s); wjson result = decode_json(s); CHECK(result == j); } SECTION("stream source") { std::wstringstream ss; encode_json(j, ss); wjson result = decode_json(ss); CHECK(result == j); } SECTION("iterator source") { std::wstring s; encode_json(j, s); wjson result = decode_json(s.begin(), s.end()); CHECK(result == j); } } TEST_CASE("convert_pair_test") { auto val = std::make_pair(false,std::string("foo")); std::string s; jsoncons::encode_json(val, s); auto result = jsoncons::decode_json>(s); CHECK(val == result); } TEST_CASE("convert_vector_test") { std::vector v = {1,2,3,4,5,6}; std::string s; jsoncons::encode_json(v,s); auto result = jsoncons::decode_json>(s); REQUIRE(v.size() == result.size()); for (std::size_t i = 0; i < result.size(); ++i) { CHECK(v[i] == result[i]); } } TEST_CASE("convert_map_test") { std::map m = {{"a",1},{"b",2}}; std::string s; jsoncons::encode_json(m,s); auto result = jsoncons::decode_json>(s); REQUIRE(result.size() == m.size()); CHECK(m["a"] == result["a"]); CHECK(m["b"] == result["b"]); } TEST_CASE("convert_array_test") { std::array v{{1,2,3,4}}; std::string s; jsoncons::encode_json(v,s); std::array result = jsoncons::decode_json>(s); REQUIRE(result.size() == v.size()); for (std::size_t i = 0; i < result.size(); ++i) { CHECK(v[i] == result[i]); } } TEST_CASE("convert vector of vector test") { std::vector u{1,2,3,4}; std::vector> v{u,u}; std::string s; jsoncons::encode_json(v,s); auto result = jsoncons::decode_json>>(s); REQUIRE(result.size() == v.size()); for (const auto& item : result) { REQUIRE(item.size() == u.size()); CHECK(1 == item[0]); CHECK(2 == item[1]); CHECK(3 == item[2]); CHECK(4 == item[3]); } } #if !(defined(__GNUC__) && __GNUC__ <= 5) TEST_CASE("convert_tuple_test") { using employee_collection = std::map>; employee_collection input = { {"John Smith",{"Hourly","Software Engineer",10000}}, {"Jane Doe",{"Commission","Sales",20000}} }; std::string s; jsoncons::encode_json(input, s, indenting::indent); json j = json::parse(s); REQUIRE(j.is_object()); REQUIRE(2 == j.size()); CHECK(j.contains("John Smith")); CHECK(j.contains("Jane Doe")); auto employees2 = jsoncons::decode_json(s); REQUIRE(employees2.size() == input.size()); CHECK(employees2 == input); } #endif TEST_CASE("encode/decode map with integer key") { std::map m = {{1,1},{2,2}}; SECTION("string source") { std::string s; jsoncons::encode_json(m,s); auto result = jsoncons::decode_json>(s); REQUIRE(result.size() == m.size()); CHECK(m[1] == result[1]); CHECK(m[2] == result[2]); } SECTION("stream source") { std::string s; jsoncons::encode_json(m,s); std::stringstream is(s); auto result = jsoncons::decode_json>(is); REQUIRE(result.size() == m.size()); CHECK(m[1] == result[1]); CHECK(m[2] == result[2]); } SECTION("iterator source") { std::string s; jsoncons::encode_json(m,s); auto result = jsoncons::decode_json>(s.begin(), s.end()); REQUIRE(result.size() == m.size()); CHECK(m[1] == result[1]); CHECK(m[2] == result[2]); } SECTION("custom iterator source") { std::string s; jsoncons::encode_json(m,s); MyIterator it(s.data()); MyIterator end(s.data() + s.length()); auto result = jsoncons::decode_json>(it, end); REQUIRE(result.size() == m.size()); CHECK(m[1] == result[1]); CHECK(m[2] == result[2]); } } #if defined(JSONCONS_HAS_STATEFUL_ALLOCATOR) && JSONCONS_HAS_STATEFUL_ALLOCATOR == 1 #include #include template using MyScopedAllocator = std::scoped_allocator_adaptor>; TEST_CASE("decode_json with work allocator") { MyScopedAllocator temp_alloc(1); auto alloc_set = temp_allocator_only(temp_alloc); SECTION("convert_vector_test") { std::vector v = {1,2,3,4,5,6}; std::string json_text; jsoncons::encode_json(alloc_set, v,json_text); auto result = jsoncons::decode_json>(alloc_set, json_text); REQUIRE(v.size() == result.size()); for (std::size_t i = 0; i < result.size(); ++i) { CHECK(v[i] == result[i]); } } SECTION("convert_map_test") { std::map m = {{"a",1},{"b",2}}; std::string json_text; jsoncons::encode_json(alloc_set, m,json_text); auto result = jsoncons::decode_json>(alloc_set, json_text); REQUIRE(result.size() == m.size()); CHECK(m["a"] == result["a"]); CHECK(m["b"] == result["b"]); } SECTION("convert vector of vector test") { std::vector u{1,2,3,4}; std::vector> v{u,u}; std::string json_text; jsoncons::encode_json(alloc_set, v,json_text); auto result = jsoncons::decode_json>>(alloc_set, json_text); REQUIRE(result.size() == v.size()); for (const auto& item : result) { REQUIRE(item.size() == u.size()); CHECK(1 == item[0]); CHECK(2 == item[1]); CHECK(3 == item[2]); CHECK(4 == item[3]); } } #if !(defined(__GNUC__) && __GNUC__ <= 5) SECTION("convert_tuple_test") { using employee_collection = std::map>; employee_collection employees = { {"John Smith",{"Hourly","Software Engineer",10000}}, {"Jane Doe",{"Commission","Sales",20000}} }; std::string json_text; jsoncons::encode_json(alloc_set, employees, json_text, json_options(), indenting::indent); auto employees2 = jsoncons::decode_json(alloc_set, json_text); REQUIRE(employees2.size() == employees.size()); CHECK(employees2 == employees); } #endif } #endifjsoncons-1.3.2/test/corelib/src/encode_traits_tests.cpp000066400000000000000000000053551477700171100233240ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include using jsoncons::json_type_traits; using jsoncons::json; using jsoncons::wjson; using jsoncons::decode_json; using jsoncons::encode_json; namespace encode_traits_tests { struct book { std::string author; std::string title; double price; book() = default; book(const book&) = default; book(book&&) = default; book(const std::string& author, const std::string& title, double price) : author(author), title(title), price(price) { } }; } // namespace encode_traits_tests namespace ns = encode_traits_tests; JSONCONS_ALL_MEMBER_TRAITS(ns::book,author,title,price) TEST_CASE("decode_traits string tests") { SECTION("test 1") { std::string s = "foo"; std::wstring buf; encode_json(s,buf); auto s2 = decode_json(buf); CHECK(s2 == s); } SECTION("test 2") { std::wstring s = L"foo"; std::string buf; encode_json(s,buf); auto s2 = decode_json(buf); CHECK(s2 == s); } } TEST_CASE("decode_traits vector of string tests") { SECTION("test 1") { std::vector v = {"foo","bar","baz"}; std::wstring buf; encode_json(v,buf); auto v2 = decode_json>(buf); CHECK(v2 == v); } SECTION("test 2") { std::vector v = {L"foo",L"bar",L"baz"}; std::string buf; encode_json(v,buf); auto v2 = decode_json>(buf); CHECK(v2 == v); } } TEST_CASE("decode_traits std::pair tests") { SECTION("test 1") { auto p = std::make_pair(1,"foo"); std::wstring buf; encode_json(p,buf); auto p2 = decode_json>(buf); CHECK(p2 == p); } SECTION("test 2") { auto p = std::make_pair(1,L"foo"); std::wstring buf; encode_json(p,buf); auto p2 = decode_json>(buf); CHECK(p2 == p); } SECTION("test 3") { ns::book book{"Haruki Murakami","Kafka on the Shore",25.17}; auto p = std::make_pair(1,book); std::wstring buf; encode_json(p,buf); auto p2 = decode_json>(buf); CHECK(p2.second.author == book.author); CHECK(p2.second.title == book.title); CHECK(p2.second.price == book.price); } } jsoncons-1.3.2/test/corelib/src/issue355_tests.cpp000066400000000000000000000011511477700171100220540ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("issue 355 test") { jsoncons::json someObject; jsoncons::json::array someArray(4); someArray[0] = 0; someArray[1] = 1; someArray[2] = 2; someArray[3] = 3; // This will end-up making a copy the array, which I did not expect. someObject.insert_or_assign("someKey", std::move(someArray)); } jsoncons-1.3.2/test/corelib/src/json_array_tests.cpp000066400000000000000000000320311477700171100226370ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("test_initializer_list_of_integers") { json doc(json_array_arg, {0,1,2,3}); CHECK(doc.is_array()); CHECK(4 == doc.size()); for (std::size_t i = 0; i < doc.size(); ++i) { CHECK(i == doc[i].as()); } } TEST_CASE("test_assignment_to_initializer_list") { json doc; doc = json(json_array_arg, {0,1,2,3}); CHECK(doc.is_array()); CHECK(4 == doc.size()); for (std::size_t i = 0; i < doc.size(); ++i) { CHECK(i == doc[i].as()); } } TEST_CASE("test_assignment_to_initializer_list2") { json val; val["data"]["id"] = json(json_array_arg, {0,1,2,3,4,5,6,7}); val["data"]["item"] = json(json_array_arg,{json(json_array_arg, {2}), json(json_array_arg, {4,5,2,3}), json(json_array_arg, {4}), json(json_array_arg, {4,5,2,3}), json(json_array_arg, {2}), json(json_array_arg, {4,5,3}), json(json_array_arg, {2}), json(json_array_arg, {4,3})}); CHECK(json(2) == val["data"]["item"][0][0]); CHECK(json(4) == val["data"]["item"][1][0]); CHECK(json(4) == val["data"]["item"][2][0]); CHECK(json(4) == val["data"]["item"][3][0]); CHECK(json(2) == val["data"]["item"][4][0]); CHECK(json(4) == val["data"]["item"][5][0]); CHECK(json(2) == val["data"]["item"][6][0]); CHECK(json(4) == val["data"]["item"][7][0]); CHECK(json(3) == val["data"]["item"][7][1]); } TEST_CASE("test_assignment_to_initializer_list3") { json val; val["data"]["id"] = json(json_array_arg, {0,1,2,3,4,5,6,7}); val["data"]["item"] = json(json_array_arg, {json(json_object_arg, {{"first",1},{"second",2}})}); json expected_id = json::parse(R"( [0,1,2,3,4,5,6,7] )"); json expected_item = json::parse(R"( [{"first":1,"second":2}] )"); CHECK(expected_id == val["data"]["id"]); CHECK(expected_item == val["data"]["item"]); } TEST_CASE("test_assign_initializer_list_of_object") { json doc(json_array_arg); json transaction; transaction["Debit"] = 10000; doc = json(json_array_arg, {transaction}); CHECK(doc.is_array()); CHECK(1 == doc.size()); CHECK(doc[0] == transaction); } TEST_CASE("test_initializer_list_of_objects") { json book1; book1["author"] = "Smith"; book1["title"] = "Old Bones"; json book2; book2["author"] = "Jones"; book2["title"] = "New Things"; json doc(json_array_arg, {book1, book2}); CHECK(doc.is_array()); CHECK(2 == doc.size()); CHECK(book1 == doc[0]); CHECK(book2 == doc[1]); } TEST_CASE("test_array_constructor") { json doc(json_array_arg); doc.resize(10,10.0); CHECK(doc.is_array()); CHECK(doc.size() == 10); CHECK(doc[0].as() == Approx(10.0).epsilon(0.0000001)); } TEST_CASE("test_make_array") { json doc(json_array_arg); CHECK(0 == doc.size()); doc.resize(10,10.0); CHECK(doc.is_array()); CHECK(doc.size() == 10); CHECK(doc[0].as() == Approx(10.0).epsilon(0.0000001)); } TEST_CASE("test_add_element_to_array") { json doc(json_array_arg); CHECK(doc.is_array()); CHECK(doc.is_array()); doc.push_back("Toronto"); doc.push_back("Vancouver"); doc.insert(doc.array_range().begin(),"Montreal"); CHECK(3 == doc.size()); CHECK(doc[0].as() == std::string("Montreal")); CHECK(doc[1].as() == std::string("Toronto")); CHECK(doc[2].as() == std::string("Vancouver")); } TEST_CASE("test_emplace_element_to_array") { json a(json_array_arg); CHECK(a.is_array()); CHECK(a.is_array()); a.emplace_back("Toronto"); a.emplace_back("Vancouver"); a.emplace(a.array_range().begin(),"Montreal"); CHECK(3 == a.size()); CHECK(a[0].as() == std::string("Montreal")); CHECK(a[1].as() == std::string("Toronto")); CHECK(a[2].as() == std::string("Vancouver")); } TEST_CASE("test_array_add_pos") { json arr(json_array_arg); CHECK(arr.is_array()); CHECK(arr.is_array()); arr.push_back("Toronto"); arr.push_back("Vancouver"); arr.insert(arr.array_range().begin(),"Montreal"); CHECK(3 == arr.size()); CHECK(arr[0].as() == std::string("Montreal")); CHECK(arr[1].as() == std::string("Toronto")); CHECK(arr[2].as() == std::string("Vancouver")); } TEST_CASE("test_array_erase_range") { json arr(json_array_arg); CHECK(arr.is_array()); CHECK(arr.is_array()); arr.push_back("Toronto"); arr.push_back("Vancouver"); arr.insert(arr.array_range().begin(),"Montreal"); CHECK(3 == arr.size()); arr.erase(arr.array_range().begin()+1,arr.array_range().end()); CHECK(1 == arr.size()); CHECK(arr[0].as() == std::string("Montreal")); } TEST_CASE("test_reserve_array_capacity") { json cities(json_array_arg); CHECK(cities.is_array()); CHECK(cities.is_array()); cities.reserve(10); // storage is allocated CHECK(cities.capacity() == 10); CHECK(0 == cities.size()); cities.push_back("Toronto"); CHECK(cities.is_array()); CHECK(cities.is_array()); CHECK(cities.capacity() == 10); CHECK(1 == cities.size()); cities.push_back("Vancouver"); cities.insert(cities.array_range().begin(),"Montreal"); CHECK(cities.capacity() == 10); CHECK(3 == cities.size()); } TEST_CASE("test make_array()") { json doc = json::make_array(); CHECK(doc.is_array()); CHECK(0 == doc.size()); doc.emplace_back("Toronto"); doc.emplace_back("Vancouver"); doc.emplace(doc.array_range().begin(),"Montreal"); CHECK(doc[0].as() == std::string("Montreal")); CHECK(doc[1].as() == std::string("Toronto")); CHECK(doc[2].as() == std::string("Vancouver")); } TEST_CASE("test_one_dim_array") { basic_json> a = basic_json>::make_array<1>(10,0); CHECK(a.size() == 10); CHECK(0 == a[0].as()); a[1] = 1; a[2] = 2; CHECK(1 == a[1].as()); CHECK(2 == a[2].as()); CHECK(0 == a[9].as()); CHECK(1 == a[1].as()); CHECK(2 == a[2].as()); CHECK(0 == a[9].as()); } TEST_CASE("test_two_dim_array") { json a = json::make_array<2>(3,4,0); CHECK(3 == a.size()); a[0][0] = "Tenor"; a[0][1] = "ATM vol"; a[0][2] = "25-d-MS"; a[0][3] = "25-d-RR"; a[1][0] = "1Y"; a[1][1] = 0.20; a[1][2] = 0.009; a[1][3] = -0.006; a[2][0] = "2Y"; a[2][1] = 0.18; a[2][2] = 0.009; a[2][3] = -0.005; CHECK(a[0][0].as() ==std::string("Tenor")); CHECK(a[2][3].as() == Approx(-0.005).epsilon(0.00000001)); CHECK(a[0][0].as() ==std::string("Tenor")); CHECK(a[2][3].as() == Approx(-0.005).epsilon(0.00000001)); } TEST_CASE("test_three_dim_array") { json a = json::make_array<3>(4,3,2,0); CHECK(4 == a.size()); a[0][2][0] = 2; a[0][2][1] = 3; CHECK(2 == a[0][2][0].as()); CHECK(3 == a[0][2][1].as()); CHECK(0 == a[3][2][1].as()); CHECK(2 == a[0][2][0].as()); CHECK(3 == a[0][2][1].as()); CHECK(0 == a[3][2][1].as()); } TEST_CASE("test_array_assign_vector") { std::vector vec; vec.push_back("Toronto"); vec.push_back("Vancouver"); vec.push_back("Montreal"); json val; val = vec; CHECK(3 == val.size()); CHECK(val[0].as() ==std::string("Toronto")); CHECK(val[1].as() ==std::string("Vancouver")); CHECK(val[2].as() ==std::string("Montreal")); } TEST_CASE("test_array_assign_vector_of_bool") { std::vector vec; vec.push_back(true); vec.push_back(false); vec.push_back(true); json val; val = vec; CHECK(3 == val.size()); CHECK(val[0].as() == true); CHECK(val[1].as() == false); CHECK(val[2].as() == true); } TEST_CASE("test_array_add_null") { json a(json_array_arg); a.push_back(jsoncons::null_type()); a.push_back(json::null()); CHECK(a[0].is_null()); CHECK(a[1].is_null()); } TEST_CASE("test_array_from_container") { std::vector vec; vec.push_back(10); vec.push_back(20); vec.push_back(30); json val1 = vec; REQUIRE(3 == vec.size()); CHECK(vec[0] == 10); CHECK(vec[1] == 20); CHECK(vec[2] == 30); std::list list; list.push_back(10.5); list.push_back(20.5); list.push_back(30.5); json val2 = list; REQUIRE(3 == val2.size()); CHECK(val2[0].as() == Approx(10.5).epsilon(0.000001)); CHECK(val2[1].as() == Approx(20.5).epsilon(0.000001)); CHECK(val2[2].as() == Approx(30.5).epsilon(0.000001)); } TEST_CASE("test_array_as_vector_of_double") { std::string s("[0,1.1,2,3.1]"); json val = json::parse(s); std::vector v = val.as>(); CHECK(4 == v.size()); CHECK(v[0] == Approx(0.0).epsilon(0.0000000001)); CHECK(v[1] == Approx(1.1).epsilon(0.0000000001)); CHECK(v[2] == Approx(2.0).epsilon(0.0000000001)); CHECK(v[3] == Approx(3.1).epsilon(0.0000000001)); } TEST_CASE("test_array_as_vector_of_bool") { std::string s("[true,false,true]"); json val = json::parse(s); std::vector v = val.as>(); CHECK(3 == v.size()); CHECK(v[0] == true); CHECK(v[1] == false); CHECK(v[2] == true); } TEST_CASE("test_array_as_vector_of_string") { std::string s("[\"Hello\",\"World\"]"); json val = json::parse(s); std::vector v = val.as>(); CHECK(2 == v.size()); CHECK(v[0] == "Hello"); CHECK(v[1] == "World"); } TEST_CASE("test_array_as_vector_of_char") { std::string s("[20,30]"); json val = json::parse(s); std::vector v = val.as>(); CHECK(2 == v.size()); CHECK(v[0] == 20); CHECK(v[1] == 30); } TEST_CASE("test_array_as_vector_of_int") { std::string s("[0,1,2,3]"); json val = json::parse(s); std::vector v = val.as>(); CHECK(4 == v.size()); CHECK(0 == v[0]); CHECK(1 == v[1]); CHECK(2 == v[2]); CHECK(3 == v[3]); std::vector v1 = val.as>(); CHECK(4 == v1.size()); CHECK(0 == v1[0]); CHECK(1 == v1[1]); CHECK(2 == v1[2]); CHECK(3 == v1[3]); std::vector v2 = val.as>(); CHECK(4 == v2.size()); CHECK(0 == v2[0]); CHECK(1 == v2[1]); CHECK(2 == v2[2]); CHECK(3 == v2[3]); std::vector v3 = val.as>(); CHECK(4 == v3.size()); CHECK(0 == v3[0]); CHECK(1 == v3[1]); CHECK(2 == v3[2]); CHECK(3 == v3[3]); std::vector v4 = val.as>(); CHECK(4 == v4.size()); CHECK(0 == v4[0]); CHECK(1 == v4[1]); CHECK(2 == v4[2]); CHECK(3 == v4[3]); std::vector v5 = val.as>(); CHECK(4 == v5.size()); CHECK(0 == v5[0]); CHECK(1 == v5[1]); CHECK(2 == v5[2]); CHECK(3 == v5[3]); } TEST_CASE("test_array_as_vector_of_int_on_proxy") { std::string s("[0,1,2,3]"); json val = json::parse(s); json root; root["val"] = val; std::vector v = root["val"].as>(); CHECK(4 == v.size()); CHECK(0 == v[0]); CHECK(1 == v[1]); CHECK(2 == v[2]); CHECK(3 == v[3]); } TEST_CASE("test json_array erase with iterator") { SECTION("json erase with iterator") { json doc(jsoncons::json_array_arg); doc.push_back("a"); doc.push_back("b"); doc.push_back("c"); auto it = doc.array_range().begin(); while (it != doc.array_range().end()) { if (*it == "a" || *it == "c") { it = doc.erase(it); } else { it++; } } CHECK(1 == doc.size()); CHECK(doc[0] == "b"); } SECTION("json erase with iterator 2") { json doc(jsoncons::json_array_arg); doc.push_back("a"); doc.push_back("b"); doc.push_back("c"); auto it = doc.array_range().begin(); while (it != doc.array_range().end()) { if (*it == "a") { it = doc.erase(it,it+2); } else { it++; } } CHECK(1 == doc.size()); CHECK(doc[0] == "c"); } } jsoncons-1.3.2/test/corelib/src/json_as_tests.cpp000066400000000000000000000113651477700171100221330ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include TEST_CASE("json integer as string") { SECTION("0xabcdef") { jsoncons::json doc("0xabcdef"); CHECK(doc.as() == 11259375); } SECTION("0x123456789") { jsoncons::json doc("0x123456789"); CHECK(doc.as() == 4886718345); } SECTION("0XABCDEF") { jsoncons::json doc("0XABCDEF"); CHECK(doc.as() == 11259375u); } SECTION("0X123456789") { jsoncons::json doc("0X123456789"); CHECK(doc.as() == 4886718345); } SECTION("0x0") { jsoncons::json doc("0x0"); CHECK(0 == doc.as()); } SECTION("0777") { jsoncons::json doc("0777"); CHECK(doc.as() == 511); } SECTION("0b1001") { jsoncons::json doc("0b1001"); CHECK(9 == doc.as()); } SECTION("0B1001") { jsoncons::json doc("0B1001"); CHECK(9 == doc.as()); } } TEST_CASE("json::is_object on proxy") { jsoncons::json root = jsoncons::json::parse(R"({"key":"value"})"); CHECK_FALSE(root.contains("key1")); CHECK(root["key1"].is_object()); CHECK(root.contains("key1")); } TEST_CASE("json::as()") { std::string s1("Short"); jsoncons::json j1(s1); CHECK(j1.as() == jsoncons::string_view(s1)); std::string s2("String to long for short string"); jsoncons::json j2(s2); CHECK(j2.as() == jsoncons::string_view(s2)); } TEST_CASE("json::as()") { SECTION("from integer") { jsoncons::json doc(-1000); CHECK(bool(doc.as() == jsoncons::bigint(-1000))); } SECTION("from unsigned integer") { jsoncons::json doc(1000u); CHECK(bool(doc.as() == jsoncons::bigint(1000u))); } SECTION("from double") { jsoncons::json doc(1000.0); CHECK(bool(doc.as() == jsoncons::bigint(1000))); } SECTION("from bigint") { std::string s = "-18446744073709551617"; jsoncons::json doc(s, jsoncons::semantic_tag::bigint); CHECK(bool(doc.as() == jsoncons::bigint::from_string(s))); } } #if (defined(__GNUC__) || defined(__clang__)) && defined(JSONCONS_HAS_INT128) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" TEST_CASE("json::as<__int128>()") { std::string s1 = "-18446744073709551617"; __int128 n; auto result = jsoncons::detail::to_integer_unchecked(s1.data(),s1.size(), n); REQUIRE(result.ec == jsoncons::detail::to_integer_errc()); jsoncons::json doc(s1); __int128 val = doc.as<__int128>(); std::string s2; jsoncons::detail::from_integer(val, s2); std::string s3; jsoncons::detail::from_integer(n, s3); CHECK((n == val)); } TEST_CASE("json::as()") { std::string s1 = "18446744073709551616"; unsigned __int128 n; auto result = jsoncons::detail::to_integer_unchecked(s1.data(),s1.size(), n); REQUIRE(result.ec == jsoncons::detail::to_integer_errc()); jsoncons::json doc(s1); unsigned __int128 val = doc.as(); std::string s2; jsoncons::detail::from_integer(val, s2); std::string s3; jsoncons::detail::from_integer(n, s3); CHECK((n == val)); } #pragma GCC diagnostic pop #endif TEST_CASE("as byte string tests") { SECTION("byte_string_arg hint") { std::vector v = {'H','e','l','l','o'}; jsoncons::json doc(jsoncons::byte_string_arg, v, jsoncons::semantic_tag::base64); jsoncons::json sj(doc.as()); auto u = sj.as>(jsoncons::byte_string_arg, jsoncons::semantic_tag::base64); CHECK(u == v); } SECTION("as std::vector") { std::vector v = {'H','e','l','l','o'}; jsoncons::json doc(jsoncons::byte_string_arg, v, jsoncons::semantic_tag::base64); auto u = doc.as>(); CHECK(u == v); } SECTION("as>(jsoncons::byte_string_arg, ...") { std::vector v = {'H','e','l','l','o'}; jsoncons::json doc(jsoncons::byte_string_arg, v, jsoncons::semantic_tag::base64); jsoncons::json sj(doc.as()); auto u = sj.as>(jsoncons::byte_string_arg, jsoncons::semantic_tag::base64); CHECK(u == v); } } jsoncons-1.3.2/test/corelib/src/json_assignment_tests.cpp000066400000000000000000000406621477700171100237020ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include using namespace jsoncons; #if defined(JSONCONS_HAS_POLYMORPHIC_ALLOCATOR) && JSONCONS_HAS_POLYMORPHIC_ALLOCATOR == 1 #include TEST_CASE("json assignment with pmr allocator") { char buffer1[1024] = {}; // a small buffer on the stack char* last1 = buffer1 + sizeof(buffer1); std::pmr::monotonic_buffer_resource pool1{ std::data(buffer1), std::size(buffer1) }; std::pmr::polymorphic_allocator alloc1(&pool1); char buffer2[1024] = {}; // another small buffer on the stack char* last2 = buffer2 + sizeof(buffer2); std::pmr::monotonic_buffer_resource pool2{ std::data(buffer2), std::size(buffer2) }; std::pmr::polymorphic_allocator alloc2(&pool2); const char* long_key1 = "Key too long for short string"; const char* long_key1_end = long_key1 + strlen(long_key1); const char* long_key2 = "Another key too long for short string"; const char* long_key2_end = long_key2 + strlen(long_key2); const char* long_string1 = "String too long for short string"; const char* long_string1_end = long_string1 + strlen(long_string1); const char* long_string2 = "Another string too long for short string"; const char* long_string2_end = long_string2 + strlen(long_string2); std::vector byte_string = { 'H','e','l','l','o' }; std::vector byte_string2 = { 'W','o','r','l','d' }; SECTION("long string to long string assignment") { jsoncons::pmr::json j1{long_string1, alloc1}; REQUIRE(&pool1 == j1.get_allocator().resource()); auto it = std::search(buffer1, last1, long_string1, long_string1_end); CHECK(it != last1); jsoncons::pmr::json j2{long_string2, alloc2}; REQUIRE(&pool2 == j2.get_allocator().resource()); it = std::search(buffer2, last2, long_string2, long_string2_end); CHECK(it != last2); j1 = j2; REQUIRE(&pool1 == j1.get_allocator().resource()); it = std::search(buffer1, last1, long_string2, long_string2_end); CHECK(j1 == j2); j2 = j1; REQUIRE(&pool2 == j2.get_allocator().resource()); it = std::search(buffer2, last2, long_string2, long_string2_end); CHECK(j1 == j2); } SECTION("long string to long string move assignment") { jsoncons::pmr::json j1{long_string1, alloc1}; REQUIRE(&pool1 == j1.get_allocator().resource()); auto it = std::search(buffer1, last1, long_string1, long_string1_end); CHECK(it != last1); jsoncons::pmr::json j2{long_string2, alloc2}; REQUIRE(&pool2 == j2.get_allocator().resource()); it = std::search(buffer2, last2, long_string2, long_string2_end); CHECK(it != last2); j1 = std::move(j2); REQUIRE(&pool2 == j1.get_allocator().resource()); REQUIRE(&pool1 == j2.get_allocator().resource()); } SECTION("byte string to byte string assignment") { jsoncons::pmr::json j1{byte_string_arg, byte_string, semantic_tag::none, alloc1}; REQUIRE(&pool1 == j1.get_allocator().resource()); auto it = std::search(buffer1, last1, byte_string.data(), byte_string.data()+byte_string.size()); CHECK(it != last1); jsoncons::pmr::json j2{byte_string_arg, byte_string2, semantic_tag::none, alloc2}; REQUIRE(&pool2 == j2.get_allocator().resource()); it = std::search(buffer2, last2, byte_string2.data(), byte_string2.data()+byte_string2.size()); CHECK(it != last2); j1 = j2; REQUIRE(&pool1 == j1.get_allocator().resource()); it = std::search(buffer1, last1, byte_string.data(), byte_string.data()+byte_string.size()); CHECK(j1 == j2); j2 = j1; REQUIRE(&pool2 == j2.get_allocator().resource()); it = std::search(buffer2, last2, byte_string2.data(), byte_string2.data()+byte_string2.size()); CHECK(j1 == j2); } SECTION("byte string to byte string move assignment") { jsoncons::pmr::json j1{byte_string_arg, byte_string, semantic_tag::none, alloc1}; REQUIRE(&pool1 == j1.get_allocator().resource()); auto it = std::search(buffer1, last1, byte_string.data(), byte_string.data()+byte_string.size()); CHECK(it != last1); jsoncons::pmr::json j2{byte_string_arg, byte_string2, semantic_tag::none, alloc2}; REQUIRE(&pool2 == j2.get_allocator().resource()); it = std::search(buffer2, last2, byte_string2.data(), byte_string2.data()+byte_string2.size()); CHECK(it != last2); j1 = std::move(j2); REQUIRE(&pool2 == j1.get_allocator().resource()); REQUIRE(&pool1 == j2.get_allocator().resource()); } SECTION("array to array assignment") { jsoncons::pmr::json j1{jsoncons::json_array_arg, alloc1}; REQUIRE(&pool1 == j1.get_allocator().resource()); j1.push_back(long_string1); auto it = std::search(buffer1, last1, long_string1, long_string1_end); CHECK(it != last1); jsoncons::pmr::json j2{jsoncons::json_array_arg, alloc2}; REQUIRE(&pool2 == j2.get_allocator().resource()); j2.push_back(long_string2); it = std::search(buffer2, last2, long_string2, long_string2_end); CHECK(it != last2); j1 = j2; REQUIRE(&pool1 == j1.get_allocator().resource()); it = std::search(buffer1, last1, long_string2, long_string2_end); CHECK(j1 == j2); j2 = j1; REQUIRE(&pool2 == j2.get_allocator().resource()); it = std::search(buffer2, last2, long_string2, long_string2_end); CHECK(j1 == j2); } SECTION("array to array move assignment") { jsoncons::pmr::json j1{jsoncons::json_array_arg, alloc1}; REQUIRE(&pool1 == j1.get_allocator().resource()); j1.push_back(long_string1); auto it = std::search(buffer1, last1, long_string1, long_string1_end); CHECK(it != last1); jsoncons::pmr::json j2{jsoncons::json_array_arg, alloc2}; REQUIRE(&pool2 == j2.get_allocator().resource()); j2.push_back(long_string2); it = std::search(buffer2, last2, long_string2, long_string2_end); CHECK(it != last2); j1 = std::move(j2); REQUIRE(&pool2 == j1.get_allocator().resource()); REQUIRE(&pool1 == j2.get_allocator().resource()); } SECTION("object to object assignment") { jsoncons::pmr::json j1{jsoncons::json_object_arg, alloc1}; REQUIRE(&pool1 == j1.get_allocator().resource()); j1.insert_or_assign(long_key1, long_string1); auto it = std::search(buffer1, last1, long_key1, long_key1_end); it = std::search(buffer1, last1, long_string1, long_string1_end); CHECK(it != last1); jsoncons::pmr::json j2{jsoncons::json_object_arg, alloc2}; REQUIRE(&pool2 == j2.get_allocator().resource()); j2.try_emplace(long_key2, long_string2); it = std::search(buffer2, last2, long_key2, long_key2_end); it = std::search(buffer2, last2, long_string2, long_string2_end); CHECK(it != last2); j1 = j2; REQUIRE(&pool1 == j1.get_allocator().resource()); it = std::search(buffer1, last1, long_string2, long_string2_end); CHECK(j1 == j2); j2 = j1; REQUIRE(&pool2 == j2.get_allocator().resource()); it = std::search(buffer2, last2, long_string2, long_string2_end); CHECK(j1 == j2); } SECTION("object to object move assignment") { jsoncons::pmr::json j1{jsoncons::json_object_arg, alloc1}; REQUIRE(&pool1 == j1.get_allocator().resource()); j1.insert_or_assign(long_key1, long_string1); auto it = std::search(buffer1, last1, long_key1, long_key1_end); it = std::search(buffer1, last1, long_string1, long_string1_end); CHECK(it != last1); jsoncons::pmr::json j2{jsoncons::json_object_arg, alloc2}; REQUIRE(&pool2 == j2.get_allocator().resource()); j2.try_emplace(long_key2, long_string2); it = std::search(buffer2, last2, long_key2, long_key2_end); it = std::search(buffer2, last2, long_string2, long_string2_end); CHECK(it != last2); j1 = std::move(j2); REQUIRE(&pool2 == j1.get_allocator().resource()); REQUIRE(&pool1 == j2.get_allocator().resource()); } SECTION("long string to number assignment") { jsoncons::pmr::json j1{10}; jsoncons::pmr::json j2{long_string2, alloc2}; REQUIRE(&pool2 == j2.get_allocator().resource()); auto it = std::search(buffer2, last2, long_string2, long_string2_end); CHECK(it != last2); j1 = j2; REQUIRE(j1.get_allocator() == std::pmr::polymorphic_allocator{}); CHECK(j1 == j2); } SECTION("number to long string assignment") { jsoncons::pmr::json j1{10}; jsoncons::pmr::json j2{long_string2, alloc2}; REQUIRE(&pool2 == j2.get_allocator().resource()); auto it = std::search(buffer2, last2, long_string2, long_string2_end); CHECK(it != last2); j2 = j1; CHECK(j2.is_number()); } SECTION("long string to number move assignment") { jsoncons::pmr::json j1{10}; jsoncons::pmr::json j2{long_string2, alloc2}; REQUIRE(&pool2 == j2.get_allocator().resource()); auto it = std::search(buffer2, last2, long_string2, long_string2_end); CHECK(it != last2); j1 = std::move(j2); REQUIRE(&pool2 == j1.get_allocator().resource()); CHECK(j1.as() == long_string2); CHECK(j2.is_number()); } SECTION("number to long string move assignment") { jsoncons::pmr::json j1{10}; jsoncons::pmr::json j2{long_string2, alloc2}; REQUIRE(&pool2 == j2.get_allocator().resource()); auto it = std::search(buffer2, last2, long_string2, long_string2_end); CHECK(it != last2); j2 = std::move(j1); CHECK(j2.is_number()); CHECK(j1.is_string()); REQUIRE(&pool2 == j1.get_allocator().resource()); } SECTION("object to array assignment") { jsoncons::pmr::json j1{jsoncons::json_array_arg, alloc1}; REQUIRE(&pool1 == j1.get_allocator().resource()); j1.push_back(long_string1); auto it = std::search(buffer1, last1, long_string1, long_string1_end); CHECK(it != last1); jsoncons::pmr::json j2{jsoncons::json_object_arg, alloc2}; REQUIRE(&pool2 == j2.get_allocator().resource()); j2.try_emplace(long_key2, long_string2); it = std::search(buffer2, last2, long_key2, long_key2_end); it = std::search(buffer2, last2, long_string2, long_string2_end); CHECK(it != last2); j1 = j2; REQUIRE(&pool1 == j1.get_allocator().resource()); CHECK(j1 == j2); j2 = j1; REQUIRE(&pool2 == j2.get_allocator().resource()); CHECK(j1 == j2); } } #endif // polymorphic_allocator #if defined(JSONCONS_HAS_STATEFUL_ALLOCATOR) && JSONCONS_HAS_STATEFUL_ALLOCATOR == 1 #include #include TEST_CASE("json assignment with scoped allocator") { using cust_allocator = std::scoped_allocator_adaptor>; using cust_json = basic_json; cust_allocator alloc1(1); cust_allocator alloc2(2); const char* long_key1 = "Key too long for short string"; const char* long_key2 = "Another key too long for short string"; const char* long_string1 = "String too long for short string"; const char* long_string2 = "Another string too long for short string"; std::vector byte_string = { 'H','e','l','l','o' }; std::vector byte_string2 = { 'W','o','r','l','d' }; SECTION("long string to long string assignment") { cust_json j1{long_string1, alloc1}; REQUIRE(alloc1 == j1.get_allocator()); cust_json j2{long_string2, alloc2}; REQUIRE(alloc2 == j2.get_allocator()); j1 = j2; REQUIRE(alloc1 == j1.get_allocator()); j2 = j1; REQUIRE(alloc2 == j2.get_allocator()); } SECTION("long string to long string move assignment") { cust_json j1{long_string1, alloc1}; REQUIRE(alloc1 == j1.get_allocator()); cust_json j2{long_string2, alloc2}; REQUIRE(alloc2 == j2.get_allocator()); j1 = std::move(j2); REQUIRE(alloc2 == j1.get_allocator()); REQUIRE(alloc1 == j2.get_allocator()); } SECTION("byte string to byte string assignment") { cust_json j1{byte_string_arg, byte_string, semantic_tag::none, alloc1}; REQUIRE(alloc1 == j1.get_allocator()); cust_json j2{byte_string_arg, byte_string2, semantic_tag::none, alloc2}; REQUIRE(alloc2 == j2.get_allocator()); j1 = j2; REQUIRE(alloc1 == j1.get_allocator()); j2 = j1; REQUIRE(alloc2 == j2.get_allocator()); } SECTION("byte string to byte string move assignment") { cust_json j1{byte_string_arg, byte_string, semantic_tag::none, alloc1}; REQUIRE(alloc1 == j1.get_allocator()); cust_json j2{byte_string_arg, byte_string2, semantic_tag::none, alloc2}; REQUIRE(alloc2 == j2.get_allocator()); j1 = std::move(j2); REQUIRE(alloc2 == j1.get_allocator()); REQUIRE(alloc1 == j2.get_allocator()); } SECTION("array to array assignment") { cust_json j1{jsoncons::json_array_arg, alloc1}; REQUIRE(alloc1 == j1.get_allocator()); j1.push_back(long_string1); cust_json j2{jsoncons::json_array_arg, alloc2}; REQUIRE(alloc2 == j2.get_allocator()); j2.push_back(long_string2); j1 = j2; REQUIRE(alloc1 == j1.get_allocator()); j2 = j1; REQUIRE(alloc2 == j2.get_allocator()); } SECTION("array to array move assignment") { cust_json j1{jsoncons::json_array_arg, alloc1}; REQUIRE(alloc1 == j1.get_allocator()); j1.push_back(long_string1); cust_json j2{jsoncons::json_array_arg, alloc2}; REQUIRE(alloc2 == j2.get_allocator()); j2.push_back(long_string2); j1 = std::move(j2); REQUIRE(alloc2 == j1.get_allocator()); REQUIRE(alloc1 == j2.get_allocator()); } SECTION("object to object assignment") { cust_json j1{jsoncons::json_object_arg, alloc1}; REQUIRE(alloc1 == j1.get_allocator()); j1.insert_or_assign(long_key1, long_string1); cust_json j2{jsoncons::json_object_arg, alloc2}; REQUIRE(alloc2 == j2.get_allocator()); j2.try_emplace(long_key2, long_string2); j1 = j2; REQUIRE(alloc1 == j1.get_allocator()); j2 = j1; REQUIRE(alloc2 == j2.get_allocator()); } SECTION("object to object move assignment") { cust_json j1{jsoncons::json_object_arg, alloc1}; REQUIRE(alloc1 == j1.get_allocator()); j1.insert_or_assign(long_key1, long_string1); cust_json j2{jsoncons::json_object_arg, alloc2}; REQUIRE(alloc2 == j2.get_allocator()); j2.try_emplace(long_key2, long_string2); j1 = std::move(j2); REQUIRE(alloc2 == j1.get_allocator()); REQUIRE(alloc1 == j2.get_allocator()); } SECTION("long string to number assignment") { cust_json j1{10}; cust_json j2{long_string2, alloc2}; REQUIRE(alloc2 == j2.get_allocator()); j1 = j2; REQUIRE(alloc2 == j1.get_allocator()); CHECK(j1 == j2); } SECTION("number to long string assignment") { cust_json j1{10}; cust_json j2{long_string2, alloc2}; REQUIRE(alloc2 == j2.get_allocator()); j2 = j1; CHECK(j2.is_number()); } SECTION("object to array assignment") { cust_json j1{jsoncons::json_array_arg, alloc1}; REQUIRE(alloc1 == j1.get_allocator()); j1.push_back(long_string1); cust_json j2{jsoncons::json_object_arg, alloc2}; REQUIRE(alloc2 == j2.get_allocator()); j2.try_emplace(long_key2, long_string2); j1 = j2; REQUIRE(alloc1 == j1.get_allocator()); CHECK(j1 == j2); j2 = j1; REQUIRE(alloc2 == j2.get_allocator()); CHECK(j1 == j2); } } #endif // scoped_allocator jsoncons-1.3.2/test/corelib/src/json_bitset_traits_tests.cpp000066400000000000000000000067671477700171100244220ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include using namespace jsoncons; TEST_CASE("JSON std::bitset tests") { SECTION("low test") { std::bitset<32> i_bs32(0); std::string s32; encode_json(i_bs32, s32); auto o_bs32 = decode_json>(s32); CHECK(o_bs32 == i_bs32); std::bitset<64> i_bs64(0); std::string s64; encode_json(i_bs64, s64); auto o_bs64 = decode_json>(s64); CHECK(o_bs64 == i_bs64); } SECTION("high test") { std::bitset<32> i_bs32(0xffffffff); std::string s32; encode_json(i_bs32, s32); auto o_bs32 = decode_json>(s32); CHECK(o_bs32 == i_bs32); std::bitset<64> i_bs64(0xffffffffffffffff); std::string s64; encode_json(i_bs64, s64); auto o_bs64 = decode_json>(s64); CHECK(o_bs64 == i_bs64); } SECTION("random test") { std::random_device rd; std::mt19937 gen(rd()); auto rng32 = [&](){return random_binary_string(gen, 32);}; auto rng65 = [&](){return random_binary_string(gen, 65);}; auto rng128 = [&]() {return random_binary_string(gen, 128); }; auto rng129 = [&]() {return random_binary_string(gen, 129); }; auto rng256 = [&]() {return random_binary_string(gen, 256); }; auto rng257 = [&]() {return random_binary_string(gen, 257); }; auto rng512 = [&](){return random_binary_string(gen, 512);}; auto rng513 = [&](){return random_binary_string(gen, 513);}; for (std::size_t i = 0; i < 100; ++i) { std::bitset<32> i_bs32(rng32()); std::string s32; encode_json(i_bs32, s32); auto o_bs32 = decode_json>(s32); CHECK(o_bs32 == i_bs32); std::bitset<65> i_bs65(rng65()); std::string s65; encode_json(i_bs65, s65); auto o_bs65 = decode_json>(s65); CHECK(o_bs65 == i_bs65); std::bitset<128> i_bs128(rng128()); std::string s128; encode_json(i_bs128, s128); auto o_bs128 = decode_json>(s128); CHECK(o_bs128 == i_bs128); std::bitset<129> i_bs129(rng129()); std::string s129; encode_json(i_bs129, s129); auto o_bs129 = decode_json>(s129); CHECK(o_bs129 == i_bs129); std::bitset<256> i_bs256(rng256()); std::string s256; encode_json(i_bs256, s256); auto o_bs256 = decode_json>(s256); CHECK(o_bs256 == i_bs256); std::bitset<257> i_bs257(rng257()); std::string s257; encode_json(i_bs257, s257); auto o_bs257 = decode_json>(s257); CHECK(o_bs257 == i_bs257); std::bitset<512> i_bs512(rng512()); std::string s512; encode_json(i_bs512, s512); auto o_bs512 = decode_json>(s512); CHECK(o_bs512 == i_bs512); std::bitset<513> i_bs513(rng513()); std::string s513; encode_json(i_bs513, s513); auto o_bs513 = decode_json>(s513); CHECK(o_bs513 == i_bs513); } } } jsoncons-1.3.2/test/corelib/src/json_checker_tests.cpp000066400000000000000000000346061477700171100231370ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("test_fail1") { std::string path = "./corelib/input/JSON_checker/fail1.json"; std::fstream is(path); REQUIRE(is); CHECK_NOTHROW(json::parse(is)); } TEST_CASE("test_fail2") { std::string in_file = "./corelib/input/JSON_checker/fail2.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); } CHECK(err == jsoncons::json_errc::unexpected_eof); } TEST_CASE("test_fail3") { std::string in_file = "./corelib/input/JSON_checker/fail3.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); } CHECK(err == jsoncons::json_errc::expected_key); } TEST_CASE("test_fail4") { std::string in_file = "./corelib/input/JSON_checker/fail4.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); } CHECK(err == jsoncons::json_errc::extra_comma); } TEST_CASE("test_fail5") { std::string in_file = "./corelib/input/JSON_checker/fail5.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); } CHECK(err == jsoncons::json_errc::expected_value); } TEST_CASE("test_fail6") { std::string in_file = "./corelib/input/JSON_checker/fail6.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::expected_value); } TEST_CASE("test_fail7") { std::string in_file = "./corelib/input/JSON_checker/fail7.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); } CHECK(err == jsoncons::json_errc::extra_character); } TEST_CASE("test_fail8") { std::string in_file = "./corelib/input/JSON_checker/fail8.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::extra_character); } TEST_CASE("test_fail9") { std::string in_file = "./corelib/input/JSON_checker/fail9.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::extra_comma); } TEST_CASE("test_fail10") { std::string in_file = "./corelib/input/JSON_checker/fail10.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); } CHECK(err == jsoncons::json_errc::extra_character); } TEST_CASE("test_fail11") { std::string in_file = "./corelib/input/JSON_checker/fail11.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::expected_comma_or_rbrace); } TEST_CASE("test_fail12") { std::string in_file = "./corelib/input/JSON_checker/fail12.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::expected_value); } TEST_CASE("test_fail13") { std::string in_file = "./corelib/input/JSON_checker/fail13.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::leading_zero); } TEST_CASE("test_fail14") { std::string in_file = "./corelib/input/JSON_checker/fail14.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::invalid_number); } TEST_CASE("test_fail15") { std::string in_file = "./corelib/input/JSON_checker/fail15.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::illegal_escaped_character); } TEST_CASE("test_fail16") { std::string in_file = "./corelib/input/JSON_checker/fail16.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::expected_value); } TEST_CASE("test_fail17") { std::string in_file = "./corelib/input/JSON_checker/fail17.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::illegal_escaped_character); } TEST_CASE("test_fail18") { std::error_code err; std::string in_file = "./corelib/input/JSON_checker/fail18.json"; std::ifstream is(in_file); REQUIRE(is); JSONCONS_TRY { auto options = json_options{} .max_nesting_depth(19); json::parse(is, options); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::max_nesting_depth_exceeded); } TEST_CASE("test_fail19") { std::string in_file = "./corelib/input/JSON_checker/fail19.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::expected_colon); } TEST_CASE("test_fail20") { std::string in_file = "./corelib/input/JSON_checker/fail20.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::expected_value); } TEST_CASE("test_fail21") { std::string in_file = "./corelib/input/JSON_checker/fail21.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::expected_colon); } TEST_CASE("test_fail22") { std::string in_file = "./corelib/input/JSON_checker/fail22.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::expected_comma_or_rbracket); } TEST_CASE("test_fail23") { std::string in_file = "./corelib/input/JSON_checker/fail23.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::invalid_value); } TEST_CASE("test_fail24") { std::string in_file = "./corelib/input/JSON_checker/fail24.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } // Single quote CHECK(err == jsoncons::json_errc::single_quote); } TEST_CASE("test_fail25") { std::string in_file = "./corelib/input/JSON_checker/fail25.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::illegal_character_in_string); } TEST_CASE("test_fail26") { std::string in_file = "./corelib/input/JSON_checker/fail26.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::illegal_escaped_character); } TEST_CASE("test_fail27") { std::string in_file = "./corelib/input/JSON_checker/fail27.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::illegal_character_in_string); } TEST_CASE("test_fail28") { std::string in_file = "./corelib/input/JSON_checker/fail28.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::illegal_escaped_character); } TEST_CASE("test_fail29") { std::string in_file = "./corelib/input/JSON_checker/fail29.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::expected_value); } TEST_CASE("test_fail30") { std::string in_file = "./corelib/input/JSON_checker/fail30.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::expected_value); } TEST_CASE("test_fail31") { std::string in_file = "./corelib/input/JSON_checker/fail31.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::expected_value); } TEST_CASE("test_fail32") { std::string in_file = "./corelib/input/JSON_checker/fail32.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::unexpected_eof); } TEST_CASE("test_fail33") { std::string in_file = "./corelib/input/JSON_checker/fail33.json"; std::ifstream is(in_file); REQUIRE(is); std::error_code err; JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { err = e.code(); //std::cout << in_file << " " << e.what() << '\n'; } CHECK(err == jsoncons::json_errc::expected_comma_or_rbracket); } TEST_CASE("test_pass1") { std::string in_file = "./corelib/input/JSON_checker/pass1.json"; std::ifstream is(in_file); REQUIRE(is); JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { std::cout << in_file << " " << e.what() << '\n'; throw; } } TEST_CASE("test_pass2") { std::string in_file = "./corelib/input/JSON_checker/pass2.json"; std::ifstream is(in_file); REQUIRE(is); JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { std::cout << in_file << " " << e.what() << '\n'; throw; } } TEST_CASE("test_pass3") { std::string in_file = "./corelib/input/JSON_checker/pass3.json"; std::ifstream is(in_file); REQUIRE(is); JSONCONS_TRY { json::parse(is); } JSONCONS_CATCH (const ser_error& e) { std::cout << in_file << " " << e.what() << '\n'; throw; } } jsoncons-1.3.2/test/corelib/src/json_compare_tests.cpp000066400000000000000000000431161477700171100231550ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("basic_json object == basic_json object") { SECTION("empty, empty") { json o1; json o2; json o3(json_object_arg); CHECK(o1 == o2); CHECK(o2 == o1); CHECK(o1 == o3); CHECK(o1 >= o2); CHECK(o2 <= o1); CHECK(o1 >= o3); CHECK(o3 >= o2); CHECK_FALSE((o1 != o2)); CHECK_FALSE((o2 != o1)); CHECK_FALSE((o1 != o3)); CHECK_FALSE(o1 < o2); CHECK_FALSE(o2 < o1); CHECK_FALSE(o1 < o3); CHECK_FALSE(o1 > o2); CHECK_FALSE(o2 > o1); CHECK_FALSE(o1 > o3); } SECTION("empty and nonempty") { json a; a["c"] = 3; a["a"] = 1; a["b"] = 2; json b; CHECK(a == a); // value and value CHECK(a <= a); // value and value CHECK(a >= a); // value and value CHECK(a != b); // value and value CHECK(a > b); // value and value CHECK(a >= b); // value and value CHECK(b < a); // value and value CHECK(b <= a); // value and value CHECK_FALSE(a < b); // value and value CHECK_FALSE(a <= b); // value and value CHECK_FALSE(b > a); // value and value CHECK_FALSE(b >= a); // value and value } SECTION("nonempty and shorter") { json a; a["a"] = "hello"; a["b"] = 1.0; a["c"] = true; json b; b["a"] = "hello"; b["b"] = 1.0; CHECK(a == a); // value and value CHECK(a <= a); // value and value CHECK(a >= a); // value and value CHECK(a != b); // value and value CHECK(a > b); // value and value CHECK(a >= b); // value and value CHECK(b < a); // value and value CHECK(b <= a); // value and value CHECK_FALSE(a < b); // value and value CHECK_FALSE(a <= b); // value and value CHECK_FALSE(b > a); // value and value CHECK_FALSE(b >= a); // value and value } SECTION("nonempty and different") { json o1; o1["a"] = 1; o1["b"] = 2; o1["c"] = 3; json o2; o2["c"] = 3; o2["a"] = 1; o2["b"] = 2; CHECK(o1 == o2); CHECK(o2 == o1); CHECK_FALSE((o1 != o2)); CHECK_FALSE((o2 != o1)); CHECK(std::is_convertible::value); CHECK(jsoncons::extension_traits::is_basic_json::value); CHECK(jsoncons::extension_traits::is_basic_json::value); CHECK(1 == (o1.at("a"))); // basic_json == int CHECK((1 == o1.at("a"))); // int == basic_json CHECK(1 == (o1["a"])); // proxy == int CHECK((1 == o1["a"])); // int == proxy CHECK((o1.at("b") != 1)); // basic_json == int CHECK((1 != o1.at("b"))); // int == basic_json CHECK((o1["b"] != 1)); // proxy == int CHECK((1 != o1["b"])); // int == proxy } } TEST_CASE("basic_json == basic_json") { SECTION("test 1") { json o1; o1["a"] = 1; o1["b"] = 2; json o2(2); CHECK_FALSE((o1["a"] == o2)); CHECK_FALSE((o2 == o1["a"])); CHECK((o1["a"] == o1["a"])); CHECK_FALSE(o1["a"] == o1["b"]); CHECK(o1["b"] == o2); CHECK((o2 == o1["b"])); } } TEST_CASE("test_object_equals_diff_vals") { json o1; o1["a"] = 1; o1["b"] = 2; o1["c"] = 3; json o2; o2["a"] = 1; o2["b"] = 4; o2["c"] = 3; CHECK_FALSE((o1 == o2)); CHECK_FALSE((o2 == o1)); CHECK(o1 != o2); CHECK(o2 != o1); } TEST_CASE("test_object_equals_diff_el_names") { json o1; o1["a"] = 1; o1["b"] = 2; o1["c"] = 3; json o2; o2["d"] = 1; o2["e"] = 2; o2["f"] = 3; CHECK_FALSE((o1 == o2)); CHECK_FALSE((o2 == o1)); CHECK(o1 != o2); CHECK(o2 != o1); } TEST_CASE("test_object_equals_diff_sizes") { json o1; o1["a"] = 1; o1["b"] = 2; o1["c"] = 3; json o2; o2["a"] = 1; o2["b"] = 2; CHECK_FALSE((o1 == o2)); CHECK_FALSE((o2 == o1)); CHECK(o1 != o2); CHECK(o2 != o1); } TEST_CASE("test_object_equals_subtle_offsets") { json o1; o1["a"] = 1; o1["b"] = 1; json o2; o2["b"] = 1; o2["c"] = 1; CHECK_FALSE((o1 == o2)); CHECK_FALSE((o2 == o1)); CHECK(o1 != o2); CHECK(o2 != o1); } TEST_CASE("test_object_equals_empty_objects") { json def_constructed_1; json def_constructed_2; json parsed_1 = json::parse("{}"); json parsed_2 = json::parse("{}"); json type_constructed_1 = json(json_object_arg); json type_constructed_2 = json(json_object_arg); CHECK(def_constructed_1 == def_constructed_1); CHECK(parsed_1 == parsed_2); CHECK(type_constructed_1 == type_constructed_2); CHECK(def_constructed_1 == parsed_1); CHECK(def_constructed_1 == type_constructed_1); CHECK(parsed_1 == type_constructed_1); } TEST_CASE("test_object_equals_empty_arrays") { json parsed_1 = json::parse("[]"); json parsed_2 = json::parse("[]"); json type_constructed_1(json_array_arg); json type_constructed_2(json_array_arg); CHECK(parsed_1 == parsed_2); CHECK(type_constructed_1 == type_constructed_2); CHECK(parsed_1 == type_constructed_1); } TEST_CASE("test_empty_object_equal") { CHECK(json() == json(json_object_arg)); CHECK(json(json_object_arg) == json()); } TEST_CASE("test_string_not_equals_empty_object") { json o1("42"); json o2; CHECK(o1 != o2); CHECK(o2 != o1); } TEST_CASE("test_byte_strings_equal") { json o1(byte_string({'1','2','3','4','5','6','7','8','9'})); json o2(byte_string{'1','2','3','4','5','6','7','8','9'}); json o3(byte_string{'1','2','3','4','5','6','7','8'}); CHECK(o1 == o2); CHECK(o2 == o1); CHECK(o3 != o1); CHECK(o2 != o3); } TEST_CASE("json comparator equals tests") { json j1(semantic_tag::none); json j2{ json::object(), semantic_tag::none }; CHECK((j1 == j1 && j2 == j2)); CHECK((j1 == j2 && j2 == j1)); json var3{semantic_tag::none }; CHECK((var3 == j1 && j1 == var3)); json var4{ json::object({{"first",1},{"second",2}}), semantic_tag::none }; json var5{ json::object({ { "first",1 },{ "second",2 } }), semantic_tag::none }; CHECK((var3 != var4 && var4 != var3)); CHECK((j2 != var4 && var4 != j2)); CHECK(var4 == var4); CHECK(var4 == var5); CHECK(var5 == var4); json var6(int64_t(100), semantic_tag::none); json var7(uint64_t(100), semantic_tag::none); CHECK((var6 == var7 && var7 == var6)); json var8(100.0, semantic_tag::none); CHECK((var8 == var8 && var6 == var8 && var8 == var6 && var7 == var8 && var8 == var7)); std::string val9("small string"); std::string val11("small string 2"); json var9(val9.data(), val9.length(), semantic_tag::none); json var10(val9.data(),val9.length(), semantic_tag::none); json var11(val11.data(),val11.length(), semantic_tag::none); std::string val12("too long for small string"); std::string val14("too long for small string 2"); json var12(val12.data(),val12.length(), semantic_tag::none); json var13(val12.data(),val12.length(), semantic_tag::none); json var14(val14.data(),val14.length(), semantic_tag::none); CHECK((var9 == var10 && var10 == var9)); CHECK((var9 != var11 && var11 != var9)); CHECK((var12 == var13 && var13 == var12)); CHECK((var12 != var14 && var14 != var12)); json var15(val9.data(),val9.length(), semantic_tag::none, std::allocator()); CHECK((var9 == var15 && var15 == var9)); json var16(static_cast(0), semantic_tag::none); json var17(static_cast(0), semantic_tag::none); CHECK(var16 == var17); CHECK(var17 == var16); } TEST_CASE("basic_json number compare") { SECTION("unsigned unsigned") { json o; o["a"] = std::numeric_limits::max(); o["b"] = std::numeric_limits::lowest(); CHECK(o.at("a") == o.at("a")); // value and value CHECK(o.at("a") == o["a"]); // value and proxy CHECK(o["a"] == o.at("a")); // proxy and value CHECK(o["a"] == o["a"]); // proxy and proxy CHECK(o.at("a") <= o.at("a")); // value and value CHECK(o.at("a") <= o["a"]); // value and proxy CHECK(o["a"] <= o.at("a")); // proxy and value CHECK(o["a"] <= o["a"]); // proxy and proxy CHECK(o.at("a") >= o.at("a")); // value and value CHECK(o.at("a") >= o["a"]); // value and proxy CHECK(o["a"] >= o.at("a")); // proxy and value CHECK(o["a"] >= o["a"]); // proxy and proxy CHECK(o.at("a") != o.at("b")); // value and value CHECK(o.at("a") != o["b"]); // value and proxy CHECK(o["a"] != o.at("b")); // proxy and value CHECK(o["a"] != o["b"]); // proxy and proxy CHECK(o.at("a") > o.at("b")); // value and value CHECK(o.at("a") > o["b"]); // value and proxy CHECK(o["a"] > o.at("b")); // proxy and value CHECK(o["a"] > o["b"]); // proxy and proxy CHECK(o.at("a") >= o.at("b")); // value and value CHECK(o.at("a") >= o["b"]); // value and proxy CHECK(o["a"] >= o.at("b")); // proxy and value CHECK(o["a"] >= o["b"]); // proxy and proxy CHECK_FALSE(o.at("a") < o.at("b")); // value and value CHECK_FALSE(o.at("a") < o["b"]); // value and proxy CHECK_FALSE(o["a"] < o.at("b")); // proxy and value CHECK_FALSE(o["a"] < o["b"]); // proxy and proxy CHECK_FALSE(o.at("a") <= o.at("b")); // value and value CHECK_FALSE(o.at("a") <= o["b"]); // value and proxy CHECK_FALSE(o["a"] <= o.at("b")); // proxy and value CHECK_FALSE(o["a"] <= o["b"]); // proxy and proxy } SECTION("signed signed test") { auto a = std::numeric_limits::max(); auto b = std::numeric_limits::lowest(); CHECK(a == a); // value and value CHECK(a <= a); // value and value CHECK(a >= a); // value and value CHECK(a != b); // value and value CHECK(a > b); // value and value CHECK(a >= b); // value and value CHECK(b < a); // value and value CHECK(b <= a); // value and value CHECK_FALSE(a < b); // value and value CHECK_FALSE(a <= b); // value and value CHECK_FALSE(b > a); // value and value CHECK_FALSE(b >= a); // value and value } SECTION("unsigned signed test") { json a = std::numeric_limits::max(); json b = std::numeric_limits::lowest(); CHECK(a == a); // value and value CHECK(a <= a); // value and value CHECK(a >= a); // value and value CHECK(a != b); // value and value CHECK(a > b); // value and value CHECK(a >= b); // value and value CHECK(b < a); // value and value CHECK(b <= a); // value and value CHECK_FALSE(a < b); // value and value CHECK_FALSE(a <= b); // value and value CHECK_FALSE(b > a); // value and value CHECK_FALSE(b >= a); // value and value } SECTION("signed unsigned test") { json a = std::numeric_limits::max(); json b = std::numeric_limits::lowest(); CHECK(a == a); // value and value CHECK(a <= a); // value and value CHECK(a >= a); // value and value CHECK(a != b); // value and value CHECK(a > b); // value and value CHECK(a >= b); // value and value CHECK(b < a); // value and value CHECK(b <= a); // value and value CHECK_FALSE(a < b); // value and value CHECK_FALSE(a <= b); // value and value CHECK_FALSE(b > a); // value and value CHECK_FALSE(b >= a); // value and value } SECTION("double double test") { json a = std::numeric_limits::max(); json b = std::numeric_limits::lowest(); CHECK(a == a); // value and value CHECK(a <= a); // value and value CHECK(a >= a); // value and value CHECK(a != b); // value and value CHECK(a > b); // value and value CHECK(a >= b); // value and value CHECK(b < a); // value and value CHECK(b <= a); // value and value CHECK_FALSE(a < b); // value and value CHECK_FALSE(a <= b); // value and value CHECK_FALSE(b > a); // value and value CHECK_FALSE(b >= a); // value and value } SECTION("signed double test") { json a = std::numeric_limits::max(); json b = std::numeric_limits::lowest(); CHECK(a == a); // value and value CHECK(a <= a); // value and value CHECK(a >= a); // value and value CHECK(a != b); // value and value CHECK(a > b); // value and value CHECK(a >= b); // value and value CHECK(b < a); // value and value CHECK(b <= a); // value and value CHECK_FALSE(a < b); // value and value CHECK_FALSE(a <= b); // value and value CHECK_FALSE(b > a); // value and value CHECK_FALSE(b >= a); // value and value } SECTION("double signed test") { json a = std::numeric_limits::max(); json b = std::numeric_limits::lowest(); CHECK(a == a); // value and value CHECK(a <= a); // value and value CHECK(a >= a); // value and value CHECK(a != b); // value and value CHECK(a > b); // value and value CHECK(a >= b); // value and value CHECK(b < a); // value and value CHECK(b <= a); // value and value CHECK_FALSE(a < b); // value and value CHECK_FALSE(a <= b); // value and value CHECK_FALSE(b > a); // value and value CHECK_FALSE(b >= a); // value and value } SECTION("unsigned double test") { json a = std::numeric_limits::max(); json b = std::numeric_limits::lowest(); CHECK(a == a); // value and value CHECK(a <= a); // value and value CHECK(a >= a); // value and value CHECK(a != b); // value and value CHECK(a > b); // value and value CHECK(a >= b); // value and value CHECK(b < a); // value and value CHECK(b <= a); // value and value CHECK_FALSE(a < b); // value and value CHECK_FALSE(a <= b); // value and value CHECK_FALSE(b > a); // value and value CHECK_FALSE(b >= a); // value and value } SECTION("double unsigned test") { json a = std::numeric_limits::max(); json b = std::numeric_limits::lowest(); CHECK(a == a); // value and value CHECK(a <= a); // value and value CHECK(a >= a); // value and value CHECK(a != b); // value and value CHECK(a > b); // value and value CHECK(a >= b); // value and value CHECK(b < a); // value and value CHECK(b <= a); // value and value CHECK_FALSE(a < b); // value and value CHECK_FALSE(a <= b); // value and value CHECK_FALSE(b > a); // value and value CHECK_FALSE(b >= a); // value and value } SECTION("double and bigint string") { json a{std::numeric_limits::max()}; json b{std::to_string(std::numeric_limits::lowest()), semantic_tag::bigint}; CHECK_FALSE(a == b); CHECK(a != b); CHECK(a > b); CHECK(a >= b); CHECK(b < a); CHECK(b <= a); CHECK_FALSE(a < b); CHECK_FALSE(a <= b); CHECK_FALSE(b > a); CHECK_FALSE(b >= a); } SECTION("bigint string and double") { json a{ std::to_string(std::numeric_limits::max()), semantic_tag::bigint }; json b{ std::numeric_limits::lowest() }; CHECK_FALSE(a == b); CHECK(a != b); CHECK(a > b); CHECK(a >= b); CHECK(b < a); CHECK(b <= a); CHECK_FALSE(a < b); CHECK_FALSE(a <= b); CHECK_FALSE(b > a); CHECK_FALSE(b >= a); } SECTION("double and non-numeric string") { json a{ std::numeric_limits::max() }; json b{ "Hello world" }; CHECK_FALSE(a == b); CHECK(a != b); CHECK_FALSE(a > b); CHECK_FALSE(a >= b); CHECK_FALSE(b < a); CHECK_FALSE(b <= a); CHECK(a < b); CHECK(a <= b); CHECK(b > a); CHECK(b >= a); } SECTION("non-numeric string and double") { json a{"Hello world"}; json b{ std::numeric_limits::lowest() }; CHECK_FALSE(a == b); CHECK(a != b); CHECK(a > b); CHECK(a >= b); CHECK(b < a); CHECK(b <= a); CHECK_FALSE(a < b); CHECK_FALSE(a <= b); CHECK_FALSE(b > a); CHECK_FALSE(b >= a); } } TEST_CASE("basic_json bool comparator") { SECTION("bool") { json a(true); json b(false); CHECK(a == a); // value and value CHECK(a <= a); // value and value CHECK(a >= a); // value and value CHECK(a != b); // value and value CHECK(a > b); // value and value CHECK(a >= b); // value and value CHECK(b < a); // value and value CHECK(b <= a); // value and value CHECK_FALSE(a < b); // value and value CHECK_FALSE(a <= b); // value and value CHECK_FALSE(b > a); // value and value CHECK_FALSE(b >= a); // value and value } } jsoncons-1.3.2/test/corelib/src/json_const_pointer_arg_tests.cpp000066400000000000000000000177231477700171100252530ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("json_const_reference array tests") { json j = json::parse(R"( ["one", "two", "three"] )"); SECTION("size()") { json v(json_const_pointer_arg, &j); REQUIRE(v.is_array()); CHECK(3 == v.size()); CHECK_FALSE(v.empty()); } SECTION("at()") { json v(json_const_pointer_arg, &j); REQUIRE(v.is_array()); REQUIRE_THROWS(v.at(1)); } SECTION("at() const") { const json v(json_const_pointer_arg, &j); REQUIRE(v.is_array()); CHECK(v.at(1) == std::string("two")); } SECTION("operator[]()") { json v(json_const_pointer_arg, &j); REQUIRE(v.is_array()); REQUIRE_THROWS(v[1]); } SECTION("operator[]() const") { const json v(json_const_pointer_arg, &j); REQUIRE(v.is_array()); CHECK(v[1] == std::string("two")); } SECTION("copy") { json v(json_const_pointer_arg, &j); CHECK(v.storage_kind() == json_storage_kind::json_const_reference); json j2(v); CHECK(j2.storage_kind() == json_storage_kind::json_const_reference); } SECTION("assignment") { json v(json_const_pointer_arg, &j); CHECK(v.storage_kind() == json_storage_kind::json_const_reference); json j2; j2 = v; CHECK(j2.storage_kind() == json_storage_kind::json_const_reference); } } TEST_CASE("json_const_reference object tests") { json j = json::parse(R"( {"one" : 1, "two" : 2, "three" : 3} )"); SECTION("size()") { json v(json_const_pointer_arg, &j); REQUIRE(v.is_object()); CHECK(3 == v.size()); CHECK_FALSE(v.empty()); } SECTION("at()") { json v(json_const_pointer_arg, &j); REQUIRE(v.is_object()); REQUIRE_THROWS(v.at("two")); CHECK(v.contains("two")); CHECK(1 == v.count("two")); CHECK(3 == v.get_value_or("three", 0)); CHECK(4 == v.get_value_or("four", 4)); } SECTION("at() const") { const json v(json_const_pointer_arg, &j); REQUIRE(v.is_object()); CHECK(2 == v.at("two")); CHECK(v.contains("two")); CHECK(1 == v.count("two")); CHECK(3 == v.get_value_or("three", 0)); CHECK(4 == v.get_value_or("four", 4)); } } TEST_CASE("json_const_reference string tests") { json j = json("Hello World"); SECTION("is_string()") { json v(json_const_pointer_arg, &j); REQUIRE(v.is_string()); REQUIRE(v.is_string_view()); CHECK(v.as() == j.as()); } } TEST_CASE("json_const_reference byte_string tests") { std::string data = "abcdefghijk"; json j(byte_string_arg, data); SECTION("is_byte_string()") { json v(json_const_pointer_arg, &j); REQUIRE(v.is_byte_string()); REQUIRE(v.is_byte_string_view()); } } TEST_CASE("json_const_reference bool tests") { json tru(true); json fal(false); SECTION("true") { json v(json_const_pointer_arg, &tru); REQUIRE(v.is_bool()); CHECK(v.as_bool()); } SECTION("false") { json v(json_const_pointer_arg, &fal); REQUIRE(v.is_bool()); CHECK_FALSE(v.as_bool()); } } TEST_CASE("json_const_reference int64 tests") { json j(-100); SECTION("is_int64()") { json v(json_const_pointer_arg, &j); REQUIRE(v.is_int64()); CHECK(v.as() == -100); } } TEST_CASE("json_const_reference uint64 tests") { json j(100); SECTION("is_uint64()") { json v(json_const_pointer_arg, &j); REQUIRE(v.is_uint64()); CHECK(v.as() == 100); } } TEST_CASE("json_const_reference half tests") { json j(half_arg, 100); SECTION("is_half()") { json v(json_const_pointer_arg, &j); REQUIRE(v.is_half()); CHECK(v.as() == 100); } } TEST_CASE("json_const_reference double tests") { json j(123.456); SECTION("is_double()") { json v(json_const_pointer_arg, &j); REQUIRE(v.is_double()); CHECK(v.as_double() == 123.456); } } namespace { void flatten(const json& source, const std::string& identifier, json& result) { json temp(json_array_arg); for (auto& item : source.array_range()) { if (item.is_array()) { for (auto& item_of_item : item.array_range()) { temp.emplace_back(json_const_pointer_arg,std::addressof(item_of_item)); } } else { temp.emplace_back(json_const_pointer_arg, std::addressof(item)); } } for (const auto& item : temp.array_range()) { if (!item.is_null()) { const auto& j = item.contains(identifier) ? item.at(identifier) : json::null(); if (!j.is_null()) { result.emplace_back(json_const_pointer_arg, std::addressof(j)); } } } } } TEST_CASE("json_const_reference identifier tests") { json source = json::parse(R"( {"reservations": [{ "instances": [ {"foo": [{"bar": 1}, {"bar": 2}, {"notbar": 3}, {"bar": 4}]}, {"foo": [{"bar": 5}, {"bar": 6}, {"notbar": [7]}, {"bar": 8}]}, {"foo": "bar"}, {"notfoo": [{"bar": 20}, {"bar": 21}, {"notbar": [7]}, {"bar": 22}]}, {"bar": [{"baz": [1]}, {"baz": [2]}, {"baz": [3]}, {"baz": [4]}]}, {"baz": [{"baz": [1, 2]}, {"baz": []}, {"baz": []}, {"baz": [3, 4]}]}, {"qux": [{"baz": []}, {"baz": [1, 2, 3]}, {"baz": [4]}, {"baz": []}]} ], "otherkey": {"foo": [{"bar": 1}, {"bar": 2}, {"notbar": 3}, {"bar": 4}]} }, { "instances": [ {"a": [{"bar": 1}, {"bar": 2}, {"notbar": 3}, {"bar": 4}]}, {"b": [{"bar": 5}, {"bar": 6}, {"notbar": [7]}, {"bar": 8}]}, {"c": "bar"}, {"notfoo": [{"bar": 23}, {"bar": 24}, {"notbar": [7]}, {"bar": 25}]}, {"qux": [{"baz": []}, {"baz": [1, 2, 3]}, {"baz": [4]}, {"baz": []}]} ], "otherkey": {"foo": [{"bar": 1}, {"bar": 2}, {"notbar": 3}, {"bar": 4}]} } ]} )"); SECTION("test1") { json target; json j1(json_array_arg); json j2(json_array_arg); json j3(json_array_arg); json expected = json::parse("[1,2,4,5,6,8]"); const json v1(json_const_pointer_arg, &source.at("reservations")); flatten(v1, "instances", j1); const json v2(json_const_pointer_arg, &j1); flatten(v2, "foo", j2); const json v3(json_const_pointer_arg, &j2); flatten(v3, "bar", j3); target = j3; CHECK(expected == target); } SECTION("test2") { json expected = json::parse("[1,2,4,5,6,8]"); json target; { json j1(json_array_arg); json j2(json_array_arg); json j3(json_array_arg); const json v1(json_const_pointer_arg, &source.at("reservations")); flatten(v1, "instances", j1); const json v2(json_const_pointer_arg, &j1); flatten(v2, "foo", j2); const json v3(json_const_pointer_arg, &j2); flatten(v3, "bar", j3); target = deep_copy(j3); } CHECK(expected == target); CHECK(target.storage_kind() == json_storage_kind::array); for (const auto& item : target.array_range()) { CHECK(item.storage_kind() == json_storage_kind::uint64); } } } jsoncons-1.3.2/test/corelib/src/json_constructor_tests.cpp000066400000000000000000000547221477700171100241210ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include using namespace jsoncons; #if defined(JSONCONS_HAS_POLYMORPHIC_ALLOCATOR) && JSONCONS_HAS_POLYMORPHIC_ALLOCATOR == 1 #include TEST_CASE("json constructor with pmr allocator") { char buffer1[1024] = {}; // a small buffer on the stack char* last1 = buffer1 + sizeof(buffer1); std::pmr::monotonic_buffer_resource pool1{ std::data(buffer1), std::size(buffer1) }; std::pmr::polymorphic_allocator alloc1(&pool1); char buffer2[1024] = {}; // another small buffer on the stack char* last2 = buffer2 + sizeof(buffer2); std::pmr::monotonic_buffer_resource pool2{ std::data(buffer2), std::size(buffer2) }; std::pmr::polymorphic_allocator alloc2(&pool2); const char* long_key1 = "Key too long for short string"; const char* long_key1_end = long_key1 + strlen(long_key1); const char* long_string1 = "String too long for short string"; const char* long_string1_end = long_string1 + strlen(long_string1); const char* long_string2 = "Another string too long for short string"; const char* long_string2_end = long_string2 + strlen(long_string2); std::vector byte_string1 = { 'H','e','l','l','o' }; SECTION("long string copy constructor") { jsoncons::pmr::json j1{long_string1, alloc1}; REQUIRE(&pool1 == j1.get_allocator().resource()); auto it = std::search(buffer1, last1, long_string1, long_string1_end); CHECK(it != last1); jsoncons::pmr::json j2{j1}; REQUIRE_FALSE(&pool1 == j2.get_allocator().resource()); jsoncons::pmr::json j3{j1, alloc2}; REQUIRE(&pool2 == j3.get_allocator().resource()); it = std::search(buffer2, last2, long_string1, long_string1_end); CHECK(it != last1); } SECTION("long string move constructor") { jsoncons::pmr::json j1{long_string1, alloc1}; REQUIRE(&pool1 == j1.get_allocator().resource()); auto it = std::search(buffer1, last1, long_string1, long_string1_end); CHECK(it != last1); jsoncons::pmr::json j2{std::move(j1)}; REQUIRE(&pool1 == j2.get_allocator().resource()); it = std::search(buffer1, last1, long_string1, long_string1_end); CHECK(it != last1); jsoncons::pmr::json j3{std::move(j2), alloc2}; REQUIRE(&pool2 == j3.get_allocator().resource()); it = std::search(buffer2, last2, long_string1, long_string1_end); CHECK(it != last1); } SECTION("byte string copy constructor") { jsoncons::pmr::json j1{byte_string_arg, byte_string1, semantic_tag::none, alloc1}; REQUIRE(&pool1 == j1.get_allocator().resource()); auto it = std::search(buffer1, last1, byte_string1.data(), byte_string1.data()+byte_string1.size()); CHECK(it != last1); jsoncons::pmr::json j2{j1}; REQUIRE_FALSE(&pool1 == j2.get_allocator().resource()); jsoncons::pmr::json j3{j1, alloc2}; REQUIRE(&pool2 == j3.get_allocator().resource()); it = std::search(buffer2, last2, long_string1, long_string1_end); CHECK(it != last1); } SECTION("byte string move constructor") { jsoncons::pmr::json j1{byte_string_arg, byte_string1, semantic_tag::none, alloc1}; REQUIRE(&pool1 == j1.get_allocator().resource()); auto it = std::search(buffer1, last1, byte_string1.data(), byte_string1.data()+byte_string1.size()); CHECK(it != last1); jsoncons::pmr::json j2{std::move(j1)}; REQUIRE(&pool1 == j2.get_allocator().resource()); jsoncons::pmr::json j3{std::move(j2), alloc2}; REQUIRE(&pool2 == j3.get_allocator().resource()); it = std::search(buffer2, last2, long_string1, long_string1_end); CHECK(it != last1); } SECTION("array copy constructor") { jsoncons::pmr::json j1{jsoncons::json_array_arg, alloc1}; REQUIRE(&pool1 == j1.get_allocator().resource()); j1.push_back(long_string1); j1.push_back(long_string2); auto it = std::search(buffer1, last1, long_string2, long_string2_end); CHECK(it != last1); jsoncons::pmr::json j2{j1}; REQUIRE_FALSE(&pool1 == j2.get_allocator().resource()); jsoncons::pmr::json j3{j1, alloc2}; REQUIRE(&pool2 == j3.get_allocator().resource()); it = std::search(buffer2, last2, long_string1, long_string1_end); CHECK(it != last1); } SECTION("array move constructor") { jsoncons::pmr::json j1{jsoncons::json_array_arg, alloc1}; REQUIRE(&pool1 == j1.get_allocator().resource()); j1.push_back(long_string1); j1.push_back(long_string2); auto it = std::search(buffer1, last1, long_string2, long_string2_end); CHECK(it != last1); jsoncons::pmr::json j2{std::move(j1)}; REQUIRE(&pool1 == j2.get_allocator().resource()); jsoncons::pmr::json j3{std::move(j2), alloc2}; REQUIRE(&pool2 == j3.get_allocator().resource()); it = std::search(buffer2, last2, long_string1, long_string1_end); CHECK(it != last1); } SECTION("object copy constructor") { jsoncons::pmr::json j1{jsoncons::json_object_arg, alloc1}; REQUIRE(&pool1 == j1.get_allocator().resource()); j1.insert_or_assign(long_key1, long_string1); auto it = std::search(buffer1, last1, long_string1, long_string1_end); CHECK(it != last1); jsoncons::pmr::json j2{j1}; REQUIRE_FALSE(&pool1 == j2.get_allocator().resource()); jsoncons::pmr::json j3{j1, alloc2}; REQUIRE(&pool2 == j3.get_allocator().resource()); it = std::search(buffer2, last2, long_key1, long_key1_end); CHECK(it != last1); it = std::search(buffer2, last2, long_string1, long_string1_end); CHECK(it != last1); } SECTION("object move constructor") { jsoncons::pmr::json j1{jsoncons::json_object_arg, alloc1}; REQUIRE(&pool1 == j1.get_allocator().resource()); j1.insert_or_assign(long_key1, long_string1); auto it = std::search(buffer1, last1, long_string1, long_string1_end); CHECK(it != last1); jsoncons::pmr::json j2{std::move(j1)}; REQUIRE(&pool1 == j2.get_allocator().resource()); jsoncons::pmr::json j3{std::move(j2), alloc2}; REQUIRE(&pool2 == j3.get_allocator().resource()); it = std::search(buffer2, last2, long_key1, long_key1_end); CHECK(it != last1); it = std::search(buffer2, last2, long_string1, long_string1_end); CHECK(it != last1); } SECTION("empty object with given allocator") { jsoncons::pmr::json j1{alloc1}; REQUIRE(j1.is_object()); REQUIRE(&pool1 == j1.get_allocator().resource()); } SECTION("object move constructor") { jsoncons::pmr::json j1{jsoncons::json_object_arg, alloc1}; REQUIRE(&pool1 == j1.get_allocator().resource()); j1.insert_or_assign(long_key1, long_string1); auto it = std::search(buffer1, last1, long_string1, long_string1_end); CHECK(it != last1); jsoncons::pmr::json j2{std::move(j1)}; REQUIRE(&pool1 == j2.get_allocator().resource()); jsoncons::pmr::json j3{std::move(j2), alloc2}; REQUIRE(&pool2 == j3.get_allocator().resource()); it = std::search(buffer2, last2, long_key1, long_key1_end); CHECK(it != last1); it = std::search(buffer2, last2, long_string1, long_string1_end); CHECK(it != last1); } } #endif // polymorphic_allocator #if defined(JSONCONS_HAS_STATEFUL_ALLOCATOR) && JSONCONS_HAS_STATEFUL_ALLOCATOR == 1 #include #include TEST_CASE("json constructor with scoped_allocator") { using cust_allocator = std::scoped_allocator_adaptor>; using cust_json = basic_json; cust_allocator alloc1(1); cust_allocator alloc2(2); REQUIRE(std::allocator_traits>::propagate_on_container_swap::value); REQUIRE(std::allocator_traits>::propagate_on_container_move_assignment::value); REQUIRE_FALSE(std::allocator_traits>::propagate_on_container_copy_assignment::value); const char* long_key1 = "Key too long for short string"; const char* long_string1 = "String too long for short string"; const char* long_string2 = "Another string too long for short string"; std::vector byte_string1 = { 'H','e','l','l','o' }; SECTION("long string copy constructor") { cust_json j1{long_string1, alloc1}; REQUIRE(alloc1 == j1.get_allocator()); cust_json j2{j1}; REQUIRE(alloc1 == j2.get_allocator()); cust_json j3{j1, alloc2}; REQUIRE(alloc2 == j3.get_allocator()); REQUIRE_FALSE(alloc1 == j3.get_allocator()); } SECTION("long string move constructor") { cust_json j1{long_string1, alloc1}; REQUIRE(alloc1 == j1.get_allocator()); cust_json j2{std::move(j1)}; REQUIRE(alloc1 == j2.get_allocator()); cust_json j3{std::move(j2), alloc2}; REQUIRE(alloc2 == j3.get_allocator()); REQUIRE_FALSE(alloc1 == j3.get_allocator()); } SECTION("byte string copy constructor") { cust_json j1{byte_string_arg, byte_string1, semantic_tag::none, alloc1}; REQUIRE(alloc1 == j1.get_allocator()); cust_json j2{j1}; REQUIRE(alloc1 == j2.get_allocator()); cust_json j3{j1, alloc2}; REQUIRE(alloc2 == j3.get_allocator()); REQUIRE_FALSE(alloc1 == j3.get_allocator()); } SECTION("byte string move constructor") { cust_json j1{byte_string_arg, byte_string1, semantic_tag::none, alloc1}; REQUIRE(alloc1 == j1.get_allocator()); cust_json j2{std::move(j1)}; REQUIRE(alloc1 == j2.get_allocator()); cust_json j3{std::move(j2), alloc2}; REQUIRE(alloc2 == j3.get_allocator()); } SECTION("array copy constructor") { cust_json j1{jsoncons::json_array_arg, alloc1}; REQUIRE(alloc1 == j1.get_allocator()); j1.push_back(long_string1); j1.push_back(long_string2); cust_json j2{j1}; REQUIRE(alloc1 == j2.get_allocator()); cust_json j3{j1, alloc2}; REQUIRE(alloc2 == j3.get_allocator()); } SECTION("array move constructor") { cust_json j1{jsoncons::json_array_arg, alloc1}; REQUIRE(alloc1 == j1.get_allocator()); j1.push_back(long_string1); j1.push_back(long_string2); cust_json j2{std::move(j1)}; REQUIRE(alloc1 == j2.get_allocator()); cust_json j3{std::move(j2), alloc2}; REQUIRE(alloc2 == j3.get_allocator()); } SECTION("object copy constructor") { cust_json j1{jsoncons::json_object_arg, alloc1}; REQUIRE(alloc1 == j1.get_allocator()); j1.insert_or_assign(long_key1, long_string1); cust_json j2{j1}; REQUIRE(alloc1 == j2.get_allocator()); cust_json j3{j1, alloc2}; REQUIRE(alloc2 == j3.get_allocator()); } SECTION("object move constructor") { cust_json j1{jsoncons::json_object_arg, alloc1}; REQUIRE(alloc1 == j1.get_allocator()); j1.insert_or_assign(long_key1, long_string1); cust_json j2{std::move(j1)}; REQUIRE(alloc1 == j2.get_allocator()); cust_json j3{std::move(j2), alloc2}; REQUIRE(alloc2 == j3.get_allocator()); } SECTION("empty object with given allocator") { cust_json j1{alloc1}; REQUIRE(j1.is_object()); REQUIRE(alloc1 == j1.get_allocator()); } SECTION("object move constructor") { cust_json j1{jsoncons::json_object_arg, alloc1}; REQUIRE(alloc1 == j1.get_allocator()); j1.insert_or_assign(long_key1, long_string1); cust_json j2{std::move(j1)}; REQUIRE(alloc1 == j2.get_allocator()); cust_json j3{std::move(j2), alloc2}; REQUIRE(alloc2 == j3.get_allocator()); } SECTION("iterator constructor") { std::map m = {{"c",1},{"b",2},{"a",3}}; /*cust_json j1{jsoncons::json_object_arg, m.begin(), m.end(), semantic_tag::none, alloc1}; REQUIRE(alloc1 == j1.get_allocator()); REQUIRE(3 == j1.size()); CHECK(3 == j1.at("a")); CHECK(2 == j1.at("b")); CHECK(1 == j1.at("c")); cust_json j2{std::move(j1)}; REQUIRE(alloc1 == j2.get_allocator()); cust_json j3{std::move(j2), alloc2}; REQUIRE(alloc2 == j3.get_allocator());*/ } } #endif // scoped_allocator TEST_CASE("json constructor byte_string_arg tests") { std::string expected_base64url = "Zm9vYmFy"; SECTION("byte_string_arg std::vector") { std::vector bytes = {'f','o','o','b','a','r'}; json doc(byte_string_arg, bytes, semantic_tag::base64url); CHECK(doc.as() == expected_base64url); } SECTION("byte_string_arg std::string") { std::string bytes = {'f','o','o','b','a','r'}; json doc(byte_string_arg, bytes, semantic_tag::base64url); CHECK(doc.as() == expected_base64url); } } TEST_CASE("json constructor tests") { SECTION("json json_object_arg") { json j1(json_object_arg, {{"one",1}}); REQUIRE(j1.is_object()); REQUIRE(1 == j1.size()); CHECK(1 == j1.at("one").as()); json j2(json_object_arg, {{"one",1},{"two",2}}); REQUIRE(j2.is_object()); REQUIRE(2 == j2.size()); CHECK(1 == j2.at("one").as()); CHECK(2 == j2.at("two").as()); } SECTION("json json_array_arg") { json j1(json_array_arg, {1}); REQUIRE(j1.is_array()); REQUIRE(1 == j1.size()); CHECK(1 == j1[0].as()); json j2(json_array_arg, {1,2}); REQUIRE(j2.is_array()); REQUIRE(2 == j2.size()); CHECK(1 == j2[0].as()); CHECK(2 == j2[1].as()); } SECTION("ojson json_object_arg") { ojson j1(json_object_arg, {{"one",1}}); REQUIRE(j1.is_object()); REQUIRE(1 == j1.size()); CHECK(1 == j1.at("one").as()); ojson j2(json_object_arg, {{"one",1},{"two",2}}); REQUIRE(j2.is_object()); REQUIRE(2 == j2.size()); CHECK(1 == j2.at("one").as()); CHECK(2 == j2.at("two").as()); } SECTION("ojson json_array_arg") { ojson j1(json_array_arg, {1}); REQUIRE(j1.is_array()); REQUIRE(1 == j1.size()); CHECK(1 == j1[0].as()); ojson j2(json_array_arg, {1,2}); REQUIRE(j2.is_array()); REQUIRE(2 == j2.size()); CHECK(1 == j2[0].as()); CHECK(2 == j2[1].as()); } } TEST_CASE("json(string_view)") { json::string_view_type sv("Hello world."); json doc(sv); CHECK(doc.as() == sv); CHECK(doc.as_string_view() == sv); } TEST_CASE("json(string, semantic_tag::datetime)") { std::string s("2015-05-07 12:41:07-07:00"); json doc(s, semantic_tag::datetime); CHECK(doc.tag() == semantic_tag::datetime); CHECK(doc.as() == s); } TEST_CASE("json(string, semantic_tag::epoch_second)") { SECTION("positive integer") { int t = 10000; json doc(t, semantic_tag::epoch_second); CHECK(doc.tag() == semantic_tag::epoch_second); CHECK(doc.as() == t); } SECTION("negative integer") { int t = -10000; json doc(t, semantic_tag::epoch_second); CHECK(doc.tag() == semantic_tag::epoch_second); CHECK(doc.as() == t); } SECTION("floating point") { double t = 10000.1; json doc(t, semantic_tag::epoch_second); CHECK(doc.tag() == semantic_tag::epoch_second); CHECK(doc.as() == t); } } TEST_CASE("json get_allocator() tests") { SECTION("short string") { json doc("short"); CHECK(doc.get_allocator() == json::allocator_type()); } SECTION("long string") { json::allocator_type alloc; json doc("string too long for short string", alloc); CHECK(doc.get_allocator() == alloc); } SECTION("byte string") { json::allocator_type alloc; json doc(byte_string({'H','e','l','l','o'}),alloc); CHECK(doc.get_allocator() == alloc); } SECTION("array") { json::allocator_type alloc; json doc(json_array_arg, semantic_tag::none, alloc); REQUIRE(doc.is_array()); CHECK(doc.get_allocator() == alloc); } SECTION("object") { json::allocator_type alloc; json doc(json_object_arg, semantic_tag::none, alloc); REQUIRE(doc.is_object()); CHECK(doc.get_allocator() == alloc); } } TEST_CASE("test_move_constructor") { int64_t val1 = -100; json var1(val1, semantic_tag::none); json var2(std::move(var1)); //CHECK(json_storage_kind::null == var1.storage_kind()); CHECK(json_storage_kind::int64 == var2.storage_kind()); CHECK(var2.as() == val1); uint64_t val3 = 9999; json var3(val3, semantic_tag::none); json var4(std::move(var3)); //CHECK(json_storage_kind::null == var3.storage_kind()); CHECK(json_storage_kind::uint64 == var4.storage_kind()); CHECK(var4.as() == val3); double val5 = 123456789.9; json var5(val5, semantic_tag::none); json var6(std::move(var5)); //CHECK(json_storage_kind::null == var5.storage_kind()); CHECK(json_storage_kind::float64 == var6.storage_kind()); CHECK(var6.as() == val5); std::string val7("Too long for small string"); json var7(val7.data(), val7.length(), semantic_tag::none); json var8(std::move(var7)); //CHECK(json_storage_kind::null == var7.storage_kind()); CHECK(json_storage_kind::long_str == var8.storage_kind()); CHECK(val7 == var8.as()); std::string val9("Small string"); json var9(val9.data(), val9.length(), semantic_tag::none); json var10(std::move(var9)); //CHECK(json_storage_kind::null == var9.storage_kind()); CHECK(json_storage_kind::short_str == var10.storage_kind()); CHECK(val9 == var10.as()); bool val11 = true; json var11(val11, semantic_tag::none); json var12(std::move(var11)); //CHECK(json_storage_kind::null == var11.storage_kind()); CHECK(json_storage_kind::boolean == var12.storage_kind()); CHECK(var12.as() == val11); std::string val13("Too long for small string"); json var13(val13.data(), val13.length(), semantic_tag::none); json var14(std::move(var13)); //CHECK(json_storage_kind::null == var13.storage_kind()); CHECK(json_storage_kind::long_str == var14.storage_kind()); CHECK(val13 == var14.as()); json val15(json_object_arg, {{"first",1},{"second",2} }); json var15(val15); json var16(std::move(var15)); CHECK(json_storage_kind::null == var15.storage_kind()); CHECK(json_storage_kind::object == var16.storage_kind()); CHECK(val15 == var16); json::array val17 = {1,2,3,4}; json var17(val17, semantic_tag::none); json var18(std::move(var17)); CHECK(json_storage_kind::null == var17.storage_kind()); CHECK(json_storage_kind::array == var18.storage_kind()); CHECK(val17 == var18); } TEST_CASE("test_copy_constructor") { int64_t val1 = 123456789; json var1(val1, semantic_tag::none); json var2(var1); CHECK(json_storage_kind::int64 == var1.storage_kind()); CHECK(json_storage_kind::int64 == var2.storage_kind()); CHECK(var2.as() == val1); uint64_t val3 = 123456789; json var3(val3, semantic_tag::none); json var4(var3); CHECK(json_storage_kind::uint64 == var3.storage_kind()); CHECK(json_storage_kind::uint64 == var4.storage_kind()); CHECK(var4.as() == val3); double val5 = 123456789.9; json var5(val5, semantic_tag::none); json var6(var5); CHECK(json_storage_kind::float64 == var5.storage_kind()); CHECK(json_storage_kind::float64 == var6.storage_kind()); CHECK(var6.as() == val5); std::string val9 = "Small string"; json var9(val9.data(), val9.length(), semantic_tag::none); json var10(var9); CHECK(json_storage_kind::short_str == var9.storage_kind()); CHECK(json_storage_kind::short_str == var10.storage_kind()); CHECK(var10.as() == val9); bool val11 = true; json var11(val11, semantic_tag::none); json var12(var11); CHECK(json_storage_kind::boolean == var11.storage_kind()); CHECK(json_storage_kind::boolean == var12.storage_kind()); CHECK(var12.as() == val11); std::string val13 = "Too long for small string"; json var13(val13.data(), val13.length(), semantic_tag::none); json var14(var13); CHECK(json_storage_kind::long_str == var13.storage_kind()); CHECK(json_storage_kind::long_str == var14.storage_kind()); CHECK(var14.as() == val13); json val15(json_object_arg, { {"first",1},{"second",2} }); json var15(val15); json var16(var15); CHECK(json_storage_kind::object == var15.storage_kind()); CHECK(json_storage_kind::object == var16.storage_kind()); CHECK(val15 == var16); json val17(json_array_arg, {1,2,3,4}); json var17(val17); json var18(var17); CHECK(json_storage_kind::array == var17.storage_kind()); CHECK(json_storage_kind::array == var18.storage_kind()); CHECK(val17 == var18); } #if (defined(__GNUC__) || defined(__clang__)) && defined(JSONCONS_HAS_INT128) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" TEST_CASE("json constructor __int64 tests") { SECTION("test 1") { json j1("-18446744073709551617", semantic_tag::bigint); __int128 val1 = j1.as<__int128>(); json j2(val1); CHECK((j2 == j1)); __int128 val2 = j2.as<__int128>(); CHECK((val2 == val1)); } } TEST_CASE("json constructor unsigned __int64 tests") { SECTION("test 1") { json j1("18446744073709551616", semantic_tag::bigint); __int128 val1 = j1.as<__int128>(); json j2(val1); CHECK((j2 == j1)); __int128 val2 = j2.as<__int128>(); CHECK((val2 == val1)); } } #pragma GCC diagnostic pop #endif jsoncons-1.3.2/test/corelib/src/json_cursor_tests.cpp000066400000000000000000000525351477700171100230510ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("json_cursor eof test") { SECTION("string source eof test") { std::string data = ""; std::error_code ec; json_string_cursor cursor(data, ec); CHECK(cursor.eof()); } SECTION("stream source eof test") { std::string data = ""; std::istringstream is(data); std::error_code ec; json_stream_cursor cursor(is, ec); CHECK(cursor.eof()); } SECTION("null stream source eof test") { std::string data = ""; std::error_code ec; json_string_cursor cursor(data, ec); CHECK(cursor.eof()); } } TEST_CASE("json_cursor string_value test") { std::string s = R"("Tom")"; std::istringstream is(s); json_stream_cursor cursor(is); REQUIRE_FALSE(cursor.done()); SECTION("test 1") { CHECK(staj_event_type::string_value == cursor.current().event_type()); CHECK(std::string("Tom") == cursor.current().get()); CHECK((cursor.current().get() == jsoncons::string_view("Tom"))); cursor.next(); CHECK(cursor.done()); } } TEST_CASE("json_cursor string_value as test") { std::string s = R"("-100")"; std::istringstream is(s); json_stream_cursor cursor(is); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::string_value == cursor.current().event_type()); CHECK(-100 == cursor.current().get()); cursor.next(); CHECK(cursor.done()); } TEST_CASE("json_cursor string_value as test") { std::string s = R"("100")"; std::istringstream is(s); json_stream_cursor cursor(is); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::string_value == cursor.current().event_type()); CHECK(100 == cursor.current().get()); CHECK(100 == cursor.current().get()); cursor.next(); CHECK(cursor.done()); } TEST_CASE("json_cursor null_value test") { std::string s = "null"; std::istringstream is(s); json_stream_cursor cursor(is); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::null_value == cursor.current().event_type()); cursor.next(); CHECK(cursor.done()); } TEST_CASE("json_cursor bool_value test") { std::string s = "false"; std::istringstream is(s); json_stream_cursor cursor(is); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::bool_value == cursor.current().event_type()); cursor.next(); CHECK(cursor.done()); } TEST_CASE("json_cursor int64_value test") { std::string s = "-100"; std::istringstream is(s); std::error_code ec; json_stream_cursor cursor(is, ec); REQUIRE_FALSE(ec); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::int64_value == cursor.current().event_type()); CHECK(-100 == cursor.current().get()); cursor.next(ec); REQUIRE_FALSE(ec); CHECK(cursor.done()); } TEST_CASE("json_cursor uint64_value test") { std::string s = "100"; std::istringstream is(s); json_stream_cursor cursor(is); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::uint64_value == cursor.current().event_type()); CHECK(100 == cursor.current().get()); CHECK(100 == cursor.current().get()); cursor.next(); CHECK(cursor.done()); } TEST_CASE("json_cursor string_value as bignum test") { std::string s = "-18446744073709551617"; std::istringstream is("\""+s+"\""); json_stream_cursor cursor(is); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::string_value == cursor.current().event_type()); CHECK(s == cursor.current().get()); cursor.next(); CHECK(cursor.done()); } TEST_CASE("json_cursor bigint value as bignum") { std::string s = "-18446744073709551617"; std::istringstream is(s); json_stream_cursor cursor(is); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::string_value == cursor.current().event_type()); CHECK(semantic_tag::bigint == cursor.current().tag()); cursor.next(); CHECK(cursor.done()); } TEST_CASE("json_cursor double_value test") { std::string s = "100.0"; std::istringstream is(s); json_stream_cursor cursor(is); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::double_value == cursor.current().event_type()); cursor.next(); CHECK(cursor.done()); } TEST_CASE("json_cursor array_value test") { std::string s = R"( [ { "enrollmentNo" : 100, "firstName" : "Tom", "lastName" : "Cochrane", "mark" : 55 }, { "enrollmentNo" : 101, "firstName" : "Catherine", "lastName" : "Smith", "mark" : 95}, { "enrollmentNo" : 102, "firstName" : "William", "lastName" : "Skeleton", "mark" : 60 } ] )"; std::istringstream is(s); json_stream_cursor cursor(is); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::uint64_value == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::uint64_value == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::uint64_value == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::uint64_value == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::uint64_value == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::uint64_value == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); CHECK(cursor.done()); } TEST_CASE("json_cursor object_value test") { std::string s = R"( { "enrollmentNo" : 100, "firstName" : "Tom", "lastName" : "Cochrane", "mark" : 55 } )"; json_string_cursor cursor(s); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::uint64_value == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::uint64_value == cursor.current().event_type()); cursor.next(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); CHECK(cursor.done()); } struct remove_mark_filter { bool reject_next_ = false; bool operator()(const staj_event& event, const ser_context&) { if (event.event_type() == staj_event_type::key && event.get() == "mark") { reject_next_ = true; return false; } else if (reject_next_) { reject_next_ = false; return false; } else { return true; } } }; TEST_CASE("json_cursor with filter tests") { std::string s = R"( [ { "enrollmentNo" : 100, "firstName" : "Tom", "lastName" : "Cochrane", "mark" : 55 }, { "enrollmentNo" : 101, "firstName" : "Catherine", "lastName" : "Smith", "mark" : 95}, { "enrollmentNo" : 102, "firstName" : "William", "lastName" : "Skeleton", "mark" : 60 } ] )"; json_string_cursor cursor(s); auto filtered_c = cursor | remove_mark_filter(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::begin_array == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::begin_object == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::key == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::uint64_value == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::key == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::string_value == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::key == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::string_value == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::end_object == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::begin_object == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::key == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::uint64_value == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::key == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::string_value == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::key == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::string_value == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::end_object == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::begin_object == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::key == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::uint64_value == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::key == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::string_value == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::key == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::string_value == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::end_object == filtered_c.current().event_type()); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(staj_event_type::end_array == filtered_c.current().event_type()); filtered_c.next(); CHECK(filtered_c.done()); } namespace { namespace ns { struct book { std::string author; std::string title; double price; book() : price(0) { } book(const std::string& author, const std::string& title, double price) : author(author), title(title), price(price) { } }; } // namespace ns } // namespace JSONCONS_ALL_MEMBER_TRAITS(ns::book,author,title,price) TEST_CASE("staj event as object") { std::vector books; books.emplace_back("Haruki Murakami", "Kafka on the Shore", 25.17); books.emplace_back("Charles Bukowski", "Women: A Novel", 12.0); std::string buffer; encode_json(books, buffer, indenting::indent); SECTION("test 1") { json_string_cursor cursor(buffer); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::double_value == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::double_value == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); CHECK(cursor.done()); } SECTION("test read_to") { json document = json::parse(buffer); json_string_cursor cursor(buffer); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::begin_object == cursor.current().event_type()); json_decoder decoder; cursor.read_to(decoder); CHECK(staj_event_type::end_object == cursor.current().event_type()); json j0 = decoder.get_result(); CHECK((j0 == document[0])); cursor.next(); json_decoder decoder2; cursor.read_to(decoder2); CHECK(staj_event_type::end_object == cursor.current().event_type()); json j1 = decoder2.get_result(); CHECK((j1 == document[1])); } } TEMPLATE_TEST_CASE("json_cursor reset test", "", (std::pair), (std::pair)) { using cursor_type = typename TestType::first_type; using input_type = typename TestType::second_type; SECTION("keeping same source") { input_type input(R"("Tom" -100 null)"); cursor_type cursor(input); std::error_code ec; CHECK(staj_event_type::string_value == cursor.current().event_type()); CHECK(std::string("Tom") == cursor.current().template get()); CHECK(cursor.current().template get() == jsoncons::string_view("Tom")); REQUIRE_FALSE(cursor.done()); cursor.next(); CHECK(cursor.done()); cursor.reset(); CHECK(staj_event_type::int64_value == cursor.current().event_type()); CHECK(-100 == cursor.current().template get()); REQUIRE_FALSE(cursor.done()); cursor.next(); CHECK(cursor.done()); cursor.reset(ec); REQUIRE_FALSE(ec); CHECK(staj_event_type::null_value == cursor.current().event_type()); REQUIRE_FALSE(cursor.done()); cursor.next(ec); REQUIRE_FALSE(ec); CHECK(cursor.done()); } SECTION("with another source") { input_type input0; input_type input1(R"("Tom")"); input_type input2("bad"); input_type input3("-100"); cursor_type cursor(input0); std::error_code ec; REQUIRE(cursor.done()); cursor.reset(input1); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::string_value == cursor.current().event_type()); CHECK(std::string("Tom") == cursor.current().template get()); CHECK(cursor.current().template get() == jsoncons::string_view("Tom")); cursor.next(); CHECK(cursor.done()); cursor.reset(input2, ec); CHECK(ec == json_errc::syntax_error); CHECK_FALSE(cursor.done()); // Check that cursor can reused be upon reset following an error. ec = json_errc::success; cursor.reset(input3, ec); REQUIRE_FALSE(ec); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::int64_value == cursor.current().event_type()); CHECK(-100 == cursor.current().template get()); cursor.next(ec); REQUIRE_FALSE(ec); CHECK(cursor.done()); } } jsoncons-1.3.2/test/corelib/src/json_encoder_tests.cpp000066400000000000000000000064621477700171100231510ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("test_byte_string_serialization") { std::vector bytes = {'H','e','l','l','o'}; json j(byte_string_arg, bytes); std::ostringstream os; os << j; std::string expected; expected.push_back('\"'); encode_base64url(bytes.begin(),bytes.end(),expected); expected.push_back('\"'); //std::cout << expected << " " << os.str() << '\n'; CHECK(expected == os.str()); } struct json_string_encoder_reset_test_fixture { std::string output1; std::string output2; json_string_encoder encoder; json_string_encoder_reset_test_fixture() : encoder(output1, json_options().indent_size(0).new_line_chars("") .spaces_around_comma(spaces_option::no_spaces)) {} std::string string1() const {return output1;} std::string string2() const {return output2;} }; struct json_stream_encoder_reset_test_fixture { std::ostringstream output1; std::ostringstream output2; json_stream_encoder encoder; json_stream_encoder_reset_test_fixture() : encoder(output1, json_options().indent_size(0).new_line_chars("") .spaces_around_comma(spaces_option::no_spaces)) {} std::string string1() const {return output1.str();} std::string string2() const {return output2.str();} }; struct compact_json_string_encoder_reset_test_fixture { std::string output1; std::string output2; compact_json_string_encoder encoder; compact_json_string_encoder_reset_test_fixture() : encoder(output1) {} std::string string1() const {return output1;} std::string string2() const {return output2;} }; struct compact_json_stream_encoder_reset_test_fixture { std::ostringstream output1; std::ostringstream output2; compact_json_stream_encoder encoder; compact_json_stream_encoder_reset_test_fixture() : encoder(output1) {} std::string string1() const {return output1.str();} std::string string2() const {return output2.str();} }; TEMPLATE_TEST_CASE("test_json_encoder_reset", "", json_string_encoder_reset_test_fixture, json_stream_encoder_reset_test_fixture, compact_json_string_encoder_reset_test_fixture, compact_json_stream_encoder_reset_test_fixture) { using fixture_type = TestType; fixture_type f; // Parially encode, reset, then fully encode to same sink f.encoder.begin_array(); f.encoder.string_value("foo"); f.encoder.uint64_value(42); f.encoder.flush(); CHECK(f.string1() == R"(["foo",42)"); f.encoder.reset(); f.encoder.begin_array(); f.encoder.string_value("foo"); f.encoder.uint64_value(42); f.encoder.end_array(); f.encoder.flush(); CHECK(f.string1() == R"(["foo",42["foo",42])"); // Reset and encode to different sink f.encoder.reset(f.output2); f.encoder.begin_array(); f.encoder.string_value("foo"); f.encoder.uint64_value(42); f.encoder.end_array(); f.encoder.flush(); CHECK(f.string2() == R"(["foo",42])"); } jsoncons-1.3.2/test/corelib/src/json_exception_tests.cpp000066400000000000000000000040001477700171100235120ustar00rootroot00000000000000 // Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("test_object_at") { json a; REQUIRE_THROWS_AS(a.at("key1"), std::out_of_range); REQUIRE_THROWS_AS(static_cast(a).at("key1"), std::out_of_range); a["key1"] = "value1"; REQUIRE_THROWS_AS(a.at("key2"), std::out_of_range); REQUIRE_THROWS_AS(static_cast(a).at("key2"), std::out_of_range); json b(json_array_arg); REQUIRE_THROWS_AS(b.at("key1"), std::runtime_error); REQUIRE_THROWS_AS(static_cast(b).at("key1"), std::runtime_error); } TEST_CASE("test_object_find") { json b(json_array_arg); b.resize(3); REQUIRE_THROWS_AS(b.find("key1"), std::runtime_error); REQUIRE_THROWS_AS(static_cast(b).find("key1"), std::runtime_error); REQUIRE_THROWS_AS(b.find(std::string("key1")), std::runtime_error); REQUIRE_THROWS_AS(static_cast(b).find(std::string("key1")), std::runtime_error); } TEST_CASE("test_array_at") { json a(json_array_arg); REQUIRE_THROWS_AS(a.at(0), std::out_of_range); REQUIRE_THROWS_AS(static_cast(a).at(0), std::out_of_range); a.resize(3); REQUIRE_THROWS_AS(a.at(3), std::out_of_range); REQUIRE_THROWS_AS(static_cast(a).at(3), std::out_of_range); } TEST_CASE("test_object_set") { json b(json_array_arg); b.resize(3); REQUIRE_THROWS_AS(b.insert_or_assign("key1","value1"), std::runtime_error); } TEST_CASE("test json object missing key") { json b; b["key1"] = "value1"; REQUIRE_THROWS_AS(b.push_back(0), std::domain_error); } TEST_CASE("test const json object missing key") { const json b{}; REQUIRE_NOTHROW(b["key1"].as()); REQUIRE_THROWS_AS(b.at("key1").as(), std::out_of_range); } jsoncons-1.3.2/test/corelib/src/json_filter_tests.cpp000066400000000000000000000112161477700171100230100ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #include #include #include using namespace jsoncons; struct warning { std::string name; std::size_t line_number; std::size_t column_number; }; class name_fixup_filter : public json_filter { std::string member_name_; public: std::vector warnings; name_fixup_filter(json_visitor& visitor) : json_filter(visitor) { } private: JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type& name, const ser_context& context, std::error_code& ec) override { member_name_ = std::string(name); if (member_name_ != "name") { this->destination().key(name, context, ec); JSONCONS_VISITOR_RETURN; } else { JSONCONS_VISITOR_RETURN; } } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& s, semantic_tag tag, const ser_context& context, std::error_code&) override { if (member_name_ == "name") { std::size_t end_first = s.find_first_of(" \t"); std::size_t start_last = s.find_first_not_of(" \t", end_first); this->destination().key("first-name", context); string_view_type first = s.substr(0, end_first); this->destination().string_value(first, tag, context); if (start_last != string_view_type::npos) { this->destination().key("last-name", context); string_view_type last = s.substr(start_last); this->destination().string_value(last, tag, context); } else { warnings.push_back(warning{std::string(s), context.line(), context.column()}); } } else { this->destination().string_value(s, tag, context); } JSONCONS_VISITOR_RETURN; } }; TEST_CASE("test_filter") { std::string in_file = "./corelib/input/address-book.json"; std::string out_file = "./corelib/output/address-book-new.json"; std::ifstream is(in_file); std::ofstream os(out_file); json_stream_encoder encoder(os); name_fixup_filter filter(encoder); json_stream_reader reader(is, filter); reader.read_next(); CHECK(1 == filter.warnings.size()); CHECK("John" ==filter.warnings[0].name); CHECK(9 == filter.warnings[0].line_number); CHECK(27 == filter.warnings[0].column_number); } TEST_CASE("test_filter2") { std::string in_file = "./corelib/input/address-book.json"; std::string out_file = "./corelib/output/address-book-new.json"; std::ifstream is(in_file); std::ofstream os(out_file); json_stream_encoder encoder(os); name_fixup_filter filter2(encoder); rename_object_key_filter filter1("email","email2",filter2); json_stream_reader reader(is, filter1); reader.read_next(); CHECK(1 == filter2.warnings.size()); CHECK("John" ==filter2.warnings[0].name); CHECK(9 == filter2.warnings[0].line_number); CHECK(27 == filter2.warnings[0].column_number); } TEST_CASE("test_rename_name") { json j; JSONCONS_TRY { j = json::parse(R"( {"store": {"book": [ {"category": "reference", "author": "Margaret Weis", "title": "Dragonlance Series", "price": 31.96}, {"category": "reference", "author": "Brent Weeks", "title": "Night Angel Trilogy", "price": 14.70 }]}} )"); } JSONCONS_CATCH (const ser_error& e) { std::cout << e.what() << '\n'; } CHECK(j["store"]["book"][0]["price"].as() == Approx(31.96).epsilon(0.001)); std::stringstream ss; json_stream_encoder encoder(ss); rename_object_key_filter filter("price","price2",encoder); j.dump(filter); json j2 = json::parse(ss); CHECK(j2["store"]["book"][0]["price2"].as() == Approx(31.96).epsilon(0.001)); } TEST_CASE("test_chained_filters") { ojson j = ojson::parse(R"({"first":1,"second":2,"fourth":3,"fifth":4})"); json_decoder decoder; rename_object_key_filter filter2("fifth", "fourth", decoder); rename_object_key_filter filter1("fourth", "third", filter2); j.dump(filter1); ojson j2 = decoder.get_result(); CHECK(4 == j2.size()); CHECK(1 == j2["first"]); CHECK(2 == j2["second"]); CHECK(3 == j2["third"]); CHECK(4 == j2["fourth"]); } jsoncons-1.3.2/test/corelib/src/json_in_place_update_tests.cpp000066400000000000000000000160151477700171100246410ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include namespace { class my_in_place_updater : public jsoncons::default_json_visitor { char* data_; std::size_t length_; std::string from_; std::string to_; public: using jsoncons::default_json_visitor::string_view_type; my_in_place_updater(char* data, std::size_t length, const std::string& from, const std::string& to) : data_(data), length_(length), from_(from), to_(to) { (void)length_; } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type& value, jsoncons::semantic_tag, const jsoncons::ser_context& context, std::error_code&) override { if (value == from_) { //std::copy(to_.begin(), to_.end(), data_ + context.position() + 1); auto p = data_ + context.position() + 1; for (auto it = to_.begin(); it != to_.end(); ++it) { *p++ = *it; } } JSONCONS_VISITOR_RETURN; } }; } TEST_CASE("json in-place update tests") { SECTION("test compact\n") { std::string format = "{\"items\": [{\"id\":1, \"name\" : \"abc\", \"expiry\" : \"0420\"}, { \"id\":2,\"name\" : \"%s\",\"expiry\" : \"0720\" }] }"; char input[500]; int length = snprintf(input, 500, format.c_str(), "id"); //std::cout << "(1)\n" << input << "\n"; char expected[500]; snprintf(expected, 500, format.c_str(), "ab"); my_in_place_updater updater(input, (size_t)length, "id", "ab"); jsoncons::json_string_reader reader(input, updater); reader.read(); CHECK(std::string(input) == std::string(expected)); } SECTION("test \n") { std::string format = "{\"items\"\n:\n \n[\n{\"id\"\n:\n1\n,\n \"name\" \n:\n \"abc\"\n,\n \"expiry\" \n:\n \"0420\"\n}\n\n,\n { \"id\"\n:\n2\n,\n\"name\" \n:\n \"%s\"\n,\n\"expiry\" \n:\n \"0720\" \n}\n\n]\n \n}"; char input[500]; int length = snprintf(input, 500, format.c_str(), "id"); //std::cout << "(1)\n" << input << "\n"; char expected[500]; snprintf(expected, 500, format.c_str(), "ab"); my_in_place_updater updater(input, (size_t)length, "id", "ab"); jsoncons::json_string_reader reader(input, updater); reader.read(); CHECK(std::string(input) == std::string(expected)); } SECTION("test \r\n") { std::string format = "{\"items\"\r\n:\r\n \r\n[\r\n{\"id\"\r\n:\r\n1\r\n,\r\n \"name\" \r\n:\r\n \"abc\"\r\n,\r\n \"foo\" \r\n:\r\n 1000.0e-50\r\n,\r\n \"expiry\" \r\n:\r\n \"0420\"\r\n}\r\n\r\n,\r\n { \"id\"\r\n:\r\n2\r\n,\r\n\"name\" \r\n:\r\n \"%s\"\r\n,\r\n\"expiry\" \r\n:\r\n \"0720\" \r\n}\r\n\r\n]\r\n \r\n}"; char input[500]; int length = snprintf(input, 500, format.c_str(), "id"); char expected[500]; snprintf(expected, 500, format.c_str(), "ab"); my_in_place_updater updater(input, (size_t)length, "id", "ab"); jsoncons::json_string_reader reader(input, updater); reader.read(); CHECK(std::string(input) == std::string(expected)); } SECTION("test \r") { std::string format = "{\"items\"\r:\r \r[\r{\"id\"\r:\r1\r,\r \"name\" \r:\r \"abc\"\r,\r \"expiry\" \r:\r \"0420\"\r}\r\r,\r { \"id\"\r:\r2\r,\r\"name\" \r:\r \"%s\"\r,\r\"expiry\" \r:\r \"0720\" \r}\r\r]\r \r}"; char input[500]; int length = snprintf(input, 500, format.c_str(), "id"); char expected[500]; snprintf(expected, 500, format.c_str(), "ab"); my_in_place_updater updater(input, (size_t)length, "id", "ab"); jsoncons::json_string_reader reader(input, updater); reader.read(); CHECK(std::string(input) == std::string(expected)); } SECTION("test /**/ \n") { std::string format = "/*\n \n \n*/\"%s\""; char input[500]; int length = snprintf(input, 500, format.c_str(), "id"); char expected[500]; snprintf(expected, 500, format.c_str(), "ab"); my_in_place_updater updater(input, (size_t)length, "id", "ab"); jsoncons::json_string_reader reader(input, updater); reader.read(); CHECK(std::string(input) == std::string(expected)); } SECTION("test /**/ \r") { std::string format = "/*\r \r \r*/\"%s\""; char input[500]; int length = snprintf(input, 500, format.c_str(), "id"); char expected[500]; snprintf(expected, 500, format.c_str(), "ab"); my_in_place_updater updater(input, (size_t)length, "id", "ab"); jsoncons::json_string_reader reader(input, updater); reader.read(); CHECK(std::string(input) == std::string(expected)); } SECTION("test /**/ \r\n") { std::string format = "/*\r\n \r\n \r\n*/\"%s\""; char input[500]; int length = snprintf(input, 500, format.c_str(), "id"); char expected[500]; snprintf(expected, 500, format.c_str(), "ab"); my_in_place_updater updater(input, (size_t)length, "id", "ab"); jsoncons::json_string_reader reader(input, updater); reader.read(); CHECK(std::string(input) == std::string(expected)); } SECTION("test // \n") { std::string format = "// \n\"%s\""; char input[500]; int length = snprintf(input, 500, format.c_str(), "id"); char expected[500]; snprintf(expected, 500, format.c_str(), "ab"); my_in_place_updater updater(input, (size_t)length, "id", "ab"); jsoncons::json_string_reader reader(input, updater); reader.read(); CHECK(std::string(input) == std::string(expected)); } SECTION("test // \r") { std::string format = "// \r\"%s\""; char input[500]; int length = snprintf(input, 500, format.c_str(), "id"); char expected[500]; snprintf(expected, 500, format.c_str(), "ab"); my_in_place_updater updater(input, (size_t)length, "id", "ab"); jsoncons::json_string_reader reader(input, updater); reader.read(); CHECK(std::string(input) == std::string(expected)); } SECTION("test // \r\n") { std::string format = "// \r\n\"%s\""; char input[500]; int length = snprintf(input, 500, format.c_str(), "id"); char expected[500]; snprintf(expected, 500, format.c_str(), "ab"); my_in_place_updater updater(input, (size_t)length, "id", "ab"); jsoncons::json_string_reader reader(input, updater); reader.read(); CHECK(std::string(input) == std::string(expected)); } } jsoncons-1.3.2/test/corelib/src/json_integer_tests.cpp000066400000000000000000000033011477700171100231540ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("test_integer_limits") { { std::ostringstream os; os << "{\"max int64_t\":" << (std::numeric_limits::max)() << "}"; json val = json::parse(os.str()); REQUIRE(val["max int64_t"].is_int64()); CHECK(val["max int64_t"].as() == (std::numeric_limits::max)()); } { std::ostringstream os; os << "{\"min int64_t\":" << (std::numeric_limits::lowest)() << "}"; json val = json::parse(os.str()); REQUIRE(val["min int64_t"].is_int64()); CHECK(val["min int64_t"].as() == (std::numeric_limits::lowest)()); } // test overflow { std::ostringstream os; os << "{\"int overflow\":-" << (std::numeric_limits::max)() << "0}"; json val = json::parse(os.str()); REQUIRE(val["int overflow"].is()); } { std::ostringstream os; os << "{\"max uint64_t\":" << (std::numeric_limits::max)() << "}"; json val = json::parse(os.str()); REQUIRE(val["max uint64_t"].is_uint64()); CHECK(val["max uint64_t"].as() == (std::numeric_limits::max)()); } { std::ostringstream os; os << "{\"uint overflow\":" << (std::numeric_limits::max)() << "0}"; json val = json::parse(os.str()); REQUIRE(val["uint overflow"].is()); } } jsoncons-1.3.2/test/corelib/src/json_less_tests.cpp000066400000000000000000000060011477700171100224650ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("json null less") { json j1 = null_type(); SECTION("empty object") { json j2; CHECK(j1 < j2); CHECK_FALSE(j2 < j1); } SECTION("object") { json j2; j2["a"] = 1; j2["b"] = 3; j2["c"] = 3; CHECK(j1 < j2); CHECK_FALSE(j2 < j1); } } TEST_CASE("json empty object less") { json j1; SECTION("empty object") { json j2; CHECK_FALSE(j1 < j2); } SECTION("object with no members") { json j2(json_object_arg); CHECK_FALSE(j1 < j2); } SECTION("object with members") { json j2; j2["a"] = 1; j2["b"] = 3; j2["c"] = 3; CHECK(j1 < j2); } } TEST_CASE("json bool less") { json jtrue = true; json jfalse = false; SECTION("bool") { CHECK(jfalse < jtrue); CHECK_FALSE(jtrue < jfalse); } SECTION("null") { json j = null_type(); CHECK(j < jfalse); CHECK(j < jtrue); } } TEST_CASE("json integer less") { SECTION("-1 < 3") { json lhs(-1); json rhs(3); CHECK(lhs < rhs); CHECK(lhs <= rhs); CHECK_FALSE(rhs < lhs); CHECK_FALSE(rhs <= lhs); } SECTION("-1 < uint64_t(3)") { json lhs(-1); json rhs(uint64_t(3)); CHECK(lhs < rhs); CHECK(lhs <= rhs); CHECK_FALSE(rhs < lhs); CHECK_FALSE(rhs <= lhs); } } TEST_CASE("json short string less") { json j1 = "bcd"; SECTION("short string") { json j2 = "cde"; CHECK(j1 < j2); CHECK_FALSE(j2 < j1); json j3 = "bcda"; CHECK(j1 < j3); CHECK_FALSE(j3 < j1); } SECTION("long string") { json j2 = "string too long for short string"; CHECK(j1 < j2); CHECK_FALSE(j2 < j1); json j3 = "a string too long for short string"; CHECK(j3 < j1); CHECK_FALSE(j1 < j3); } } TEST_CASE("json long string less") { json j1 = "a string too long for short string"; SECTION("short string") { json j2 = "a s"; CHECK(j2 < j1); CHECK_FALSE(j1 < j2); json j3 = "bcd"; CHECK(j1 < j3); CHECK_FALSE(j3 < j1); } SECTION("long string") { json j2 = "string too long for short string"; CHECK(j1 < j2); CHECK_FALSE(j2 < j1); } } TEST_CASE("json array of string less") { json j1(json_array_arg); j1.push_back("b"); j1.push_back("c"); j1.push_back("d"); SECTION("array") { json j2(json_array_arg); j2.push_back("a"); j2.push_back("b"); j2.push_back("c"); CHECK(j2 < j1); CHECK_FALSE(j1 < j2); } } jsoncons-1.3.2/test/corelib/src/json_line_split_tests.cpp000066400000000000000000000134751477700171100236760ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include using namespace jsoncons; using namespace jsoncons::literals; bool are_equal(const std::string& s1, const std::string& s2) { std::size_t len1 = s1.size(); std::size_t len2 = s2.size(); std::size_t len = std::min(len1,len2); for (std::size_t i = 0; i < len; ++i) { if (s1[i] != s2[i]) { for (std::size_t j = 0; j <= i; ++j) { std::cout << s1[j]; } std::cout << "|"; std::cout << "\n"; std::cout << i << " s1: " << s1[i] << ", " << (int)s1[i] << " s2: " << s2[i] << ", " << (int)s2[i] << "\n"; std::cout << s1 << "\n"; std::cout << "---\n"; std::cout << s2 << "\n"; return false; } } return true; } TEST_CASE("json_encoder line split tests") { json val = json::parse(R"( { "header" : {"properties": {}}, "data": { "tags" : [], "id" : [1,2,3], "item": [[1,2,3]] } } )"); SECTION("Default line splits") { std::string expected = R"({ "data": { "id": [1,2,3], "item": [ [1,2,3] ], "tags": [] }, "header": { "properties": {} } })"; auto options = json_options{} .spaces_around_comma(spaces_option::no_spaces) .object_array_line_splits(line_split_kind::same_line) .array_array_line_splits(line_split_kind::new_line); std::ostringstream os; os << pretty_print(val, options); CHECK(expected == os.str()); } SECTION("array_array same_line") { auto options = json_options{} .spaces_around_comma(spaces_option::no_spaces) .object_array_line_splits(line_split_kind::same_line) .array_array_line_splits(line_split_kind::same_line); std::string expected = R"({ "data": { "id": [1,2,3], "item": [[1,2,3]], "tags": [] }, "header": { "properties": {} } })"; std::ostringstream os; os << pretty_print(val,options); //std::cout << os.str() << "\n"; CHECK(expected == os.str()); } SECTION("array_array new_line") { auto options = json_options{} .spaces_around_comma(spaces_option::no_spaces) .array_array_line_splits(line_split_kind::new_line) .object_array_line_splits(line_split_kind::same_line); std::string expected = R"({ "data": { "id": [1,2,3], "item": [ [1,2,3] ], "tags": [] }, "header": { "properties": {} } })"; std::ostringstream os; os << pretty_print(val,options); //std::cout << os.str() << "\n"; CHECK(expected == os.str()); } SECTION("array_array multi_line") { auto options = json_options{} .spaces_around_comma(spaces_option::no_spaces) .array_array_line_splits(line_split_kind::multi_line) .object_array_line_splits(line_split_kind::same_line); std::string expected = R"({ "data": { "id": [1,2,3], "item": [ [ 1, 2, 3 ] ], "tags": [] }, "header": { "properties": {} } })"; std::ostringstream os; os << pretty_print(val,options); //std::cout << os.str() << "\n"; CHECK(expected == os.str()); } SECTION("object_array same_line") { auto options = json_options{} .spaces_around_comma(spaces_option::no_spaces) .object_array_line_splits(line_split_kind::same_line) .array_array_line_splits(line_split_kind::new_line); std::string expected = R"({ "data": { "id": [1,2,3], "item": [ [1,2,3] ], "tags": [] }, "header": { "properties": {} } })"; std::ostringstream os; os << pretty_print(val,options); //std::cout << os.str() << "\n"; CHECK(expected == os.str()); } SECTION("object_array new_line") { auto options = json_options{} .spaces_around_comma(spaces_option::no_spaces) .object_array_line_splits(line_split_kind::new_line) .array_array_line_splits(line_split_kind::new_line); std::string expected = R"({ "data": { "id": [ 1,2,3 ], "item": [ [1,2,3] ], "tags": [] }, "header": { "properties": {} } })"; std::ostringstream os; os << pretty_print(val,options); //std::cout << os.str() << "\n"; CHECK(expected == os.str()); } SECTION("") { auto options = json_options{} .spaces_around_comma(spaces_option::no_spaces) .object_array_line_splits(line_split_kind::multi_line) .array_array_line_splits(line_split_kind::same_line); std::string expected = R"({ "data": { "id": [ 1, 2, 3 ], "item": [ [1,2,3] ], "tags": [] }, "header": { "properties": {} } })"; std::ostringstream os; os << pretty_print(val,options); //std::cout << os.str() << "\n"; CHECK(expected == os.str()); } } // array_array_line_splits_(line_split_kind::new_line) TEST_CASE("test_array_of_array_of_string_string_array") { json j = R"( [ ["NY","LON", ["TOR","LON"] ] ] )"_json; //std::cout << pretty_print(j) << '\n'; } jsoncons-1.3.2/test/corelib/src/json_literal_operator_tests.cpp000066400000000000000000000033441477700171100250750ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include using namespace jsoncons; using namespace jsoncons::literals; TEST_CASE("json_literal_operator_test1") { json j = R"( { "StartDate" : "2017-03-01", "MaturityDate" : "2020-12-30", "Currency" : "USD", "DiscountCurve" : "USD-LIBOR", "FixedRate" : 0.01, "PayFrequency" : "6M", "DayCountBasis" : "ACT/360", "Notional" : 1000000 } )"_json; CHECK(j["Currency"] == "USD"); } TEST_CASE("ojson_literal_operator_test1") { ojson j = R"( { "StartDate" : "2017-03-01", "MaturityDate" : "2020-12-30", "Currency" : "USD", "DiscountCurve" : "USD-LIBOR", "FixedRate" : 0.01, "PayFrequency" : "6M", "DayCountBasis" : "ACT/360", "Notional" : 1000000 } )"_ojson; CHECK(j["Currency"] == "USD"); } TEST_CASE("json_literal_operator_test2") { wjson j = LR"( { "StartDate" : "2017-03-01", "MaturityDate" : "2020-12-30", "Currency" : "USD", "DiscountCurve" : "USD-LIBOR", "FixedRate" : 0.01, "PayFrequency" : "6M", "DayCountBasis" : "ACT/360", "Notional" : 1000000 } )"_json; CHECK(j[L"Currency"] == L"USD"); } TEST_CASE("ojson_literal_operator_test2") { wojson j = LR"( { "StartDate" : "2017-03-01", "MaturityDate" : "2020-12-30", "Currency" : "USD", "DiscountCurve" : "USD-LIBOR", "FixedRate" : 0.01, "PayFrequency" : "6M", "DayCountBasis" : "ACT/360", "Notional" : 1000000 } )"_ojson; CHECK(j[L"Currency"] == L"USD"); } jsoncons-1.3.2/test/corelib/src/json_object_tests.cpp000066400000000000000000000677751477700171100230160ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("json(json_object_arg, first, last)") { SECTION("copy map into json") { std::map m = {{"c",1},{"b",2},{"a",3}}; json j(json_object_arg, m.begin(),m.end()); REQUIRE(3 == j.size()); auto it = j.object_range().begin(); CHECK(it++->key() == "a"); CHECK(it++->key() == "b"); CHECK(it++->key() == "c"); } } TEST_CASE("json insert(first,last) test") { SECTION("copy map into json") { std::map m1 = {{"f",4},{"e",5},{"d",6}}; std::map m2 = {{"c",1},{"b",2},{"a",3}}; json j; j.insert(m1.begin(),m1.end()); j.insert(m2.begin(),m2.end()); //std::cout << j << "\n"; REQUIRE(6 == j.size()); auto it = j.object_range().begin(); CHECK(it++->key() == "a"); CHECK(it++->key() == "b"); CHECK(it++->key() == "c"); CHECK(it++->key() == "d"); CHECK(it++->key() == "e"); CHECK(it++->key() == "f"); } // Fails with xenial-armhf SECTION("move map into json") { std::map m1 = {{"a",1},{"b",2},{"c",3}}; std::map m2 = {{"d",4},{"e",5},{"f",6}}; json j; j.insert(std::make_move_iterator(m1.begin()),std::make_move_iterator(m1.end())); j.insert(std::make_move_iterator(m2.begin()),std::make_move_iterator(m2.end())); //std::cout << j << "\n"; REQUIRE(6 == j.size()); auto it = j.object_range().begin(); CHECK(it++->key() == "a"); CHECK(it++->key() == "b"); CHECK(it++->key() == "c"); CHECK(it++->key() == "d"); CHECK(it++->key() == "e"); CHECK(it++->key() == "f"); } } TEST_CASE("json as") { SECTION("empty object as string") { json j; std::string s = j.as(); CHECK("{}" == s); } SECTION("key not found") { JSONCONS_TRY { json j; std::string s = j["empty"].as(); CHECK(s == "{}"); } JSONCONS_CATCH (const std::out_of_range& e) { CHECK(e.what() == std::string("Key not found: 'empty'")); } } #ifdef __cpp_char8_t SECTION("Chinese characters as u8string") { jsoncons::json j; std::u8string s = u8"你好"; j.try_emplace("hello", s); CHECK(j["hello"].as() == s); } #endif } TEST_CASE("parse_duplicate_names") { json j1 = json::parse(R"({"first":1,"second":2,"third":3})"); CHECK(3 == j1.size()); CHECK(1 == j1["first"].as()); CHECK(2 == j1["second"].as()); CHECK(3 == j1["third"].as()); json j2 = json::parse(R"({"first":1,"second":2,"first":3})"); CHECK(2 == j2.size()); CHECK(1 == j2["first"].as()); CHECK(2 == j2["second"].as()); } TEST_CASE("test_erase_member") { json o; o["key"] = "Hello"; CHECK(1 == o.size()); o.erase("key"); CHECK(0 == o.size()); json a; json b(json_object_arg); b["input-file"] = "config_file"; json b_copy = b; a["b"] = std::move(b); CHECK(true == a["b"].is_object()); CHECK(a["b"] == b_copy); } TEST_CASE("test_object_erase_range") { json o; o["key1"] = "value1"; o["key2"] = "value2"; o["key3"] = "value3"; o["key4"] = "value4"; auto first = o.find("key2"); auto last = o.find("key4"); o.erase(first,last); CHECK(2 == o.size()); CHECK(1 == o.count("key1")); CHECK(1 == o.count("key4")); } TEST_CASE("test_empty_object") { json a; CHECK(0 == a.size()); CHECK(a.is_object()); CHECK(a.is_object()); json::object_iterator begin = a.object_range().begin(); json::object_iterator end = a.object_range().end(); for (json::object_iterator it = begin; it != end; ++it) { CHECK(false); } a["key"] = "Hello"; CHECK(1 == a.size()); CHECK(a.is_object()); CHECK(a.is_object()); } TEST_CASE("test_const_empty_object") { const json b; CHECK(0 == b.size()); CHECK(b.is_object()); CHECK(b.is_object()); json::const_object_iterator begin = b.object_range().begin(); json::const_object_iterator end = b.object_range().end(); for (json::const_object_iterator it = begin; it != end; ++it) { CHECK(false); } } TEST_CASE("test_empty_object_reserve") { json c; CHECK(0 == c.size()); CHECK(c.is_object()); CHECK(c.is_object()); c.reserve(100); CHECK(c.capacity() == 100); c["key"] = "Hello"; CHECK(1 == c.size()); CHECK(c.is_object()); CHECK(c.is_object()); CHECK(c.capacity() == 100); } TEST_CASE("test_empty_object_copy") { json a; CHECK(0 == a.size()); CHECK(a.is_object()); CHECK(a.is_object()); json b = a; CHECK(0 == b.size()); CHECK(b.is_object()); CHECK(b.is_object()); } TEST_CASE("test_empty_object_move") { json a; CHECK(0 == a.size()); CHECK(a.is_object()); CHECK(a.is_object()); json b = std::move(a); CHECK(0 == b.size()); CHECK(b.is_object()); CHECK(b.is_object()); } TEST_CASE("test_empty_object_copy_assignment") { json a; CHECK(0 == a.size()); CHECK(a.is_object()); CHECK(a.is_object()); json b = json::make_array(10); CHECK(b.size() == 10); CHECK(b.is_array()); CHECK(b.is_array()); b = a; CHECK(0 == b.size()); CHECK(b.is_object()); CHECK(b.is_object()); json c; c["key"] = "value"; CHECK(1 == c.size()); CHECK(c.is_object()); CHECK(c.is_object()); c = a; CHECK(0 == c.size()); CHECK(c.is_object()); CHECK(c.is_object()); } TEST_CASE("test_empty_object_move_assignment") { json a; CHECK(0 == a.size()); CHECK(a.is_object()); CHECK(a.is_object()); json b = json::make_array(10); CHECK(b.size() == 10); CHECK(b.is_array()); CHECK(b.is_array()); b = std::move(a); CHECK(0 == b.size()); CHECK(b.is_object()); CHECK(b.is_object()); json c; c["key"] = "value"; CHECK(1 == c.size()); CHECK(c.is_object()); CHECK(c.is_object()); c = std::move(b); CHECK(0 == c.size()); CHECK(c.is_object()); CHECK(c.is_object()); } TEST_CASE("at_or_null test") { json a = json::parse(R"( { "key1" : "value1", "key2" : {"key3" : "value3"} } )"); SECTION("1 arg") { const json& j = a.at_or_null("key1"); CHECK(j.as() == std::string("value1")); } SECTION("1 arg proxy") { const json& j = a["key2"].at_or_null("key3"); CHECK(j.as() == std::string("value3")); } SECTION("1 arg default") { const json& j = a.at_or_null("key4"); CHECK(j.is_null()); } SECTION("1 arg proxy default") { const json& j = a["key2"].at_or_null("key4"); CHECK(j.is_null()); } SECTION("1 arg null") { const json& j = json::null().at_or_null("key1"); CHECK(j.is_null()); } } TEST_CASE("get_value_or test") { json a = json::parse(R"( { "key1" : "value1", "key2" : {"key3" : "value3"} } )"); SECTION("2 arg") { std::string s1 = a.at("key1").as(); std::string s1a = a.at("key1").as(); std::string s2 = a.get_value_or("key4","null"); REQUIRE_THROWS_AS(a.at("key4"), std::out_of_range); CHECK(s1 == std::string("value1")); CHECK(s1a == std::string("value1")); CHECK(s2 == std::string("null")); } SECTION("2 arg null") { std::string s2 = json::null().get_value_or("key4","null"); CHECK(s2 == std::string("null")); } } TEST_CASE("test_proxy_get") { json a; a["object1"] = json(); a["object1"]["key1"] = "value1"; std::string s1 = a["object1"].at("key1").as(); std::string s1a = a["object1"].at("key1").as(); std::string s2 = a["object1"].get_value_or("key2",json::null()).as(); CHECK(a["object1"].get_value_or("key2", json::null()).is_null()); //std::cout << s2 << '\n'; REQUIRE_THROWS_AS(a["object1"].at("key2").as(), std::out_of_range); CHECK(std::string("value1") == s1); CHECK(std::string("value1") == s1a); CHECK(std::string("null") == s2); } TEST_CASE("test proxy get_value_or") { json a; a["object1"] = json(); a["object1"]["field1"] = "3.7"; a["object1"]["field2"] = 1.5; std::string s1 = a["object1"].get_value_or("field1","default"); std::string s2 = a["object1"].get_value_or("field2","1.0"); std::string s3 = a["object1"].get_value_or("field3","1.0"); std::string s4 = a["object1"].get_value_or("field2","1.0"); std::string s5 = a["object1"].get_value_or("field3","1.0"); double d1 = a["object1"].get_value_or ("field1",1.0); double d2 = a["object1"].get_value_or ("field2",1.0); double d3 = a["object1"].get_value_or ("field3",1.0); CHECK(std::string("3.7") == s1); CHECK(std::string("1.5") == s2); CHECK(std::string("1.0") == s3); CHECK(std::string("1.5") == s4); CHECK(std::string("1.0") == s5); CHECK(3.7 == d1); CHECK(1.5 == d2); CHECK(1 == d3); } TEST_CASE("test_set_and_proxy_set") { json a; a.insert_or_assign("object1",json()); a.insert_or_assign("field1","value1"); a["object1"].insert_or_assign("field2","value2"); CHECK(std::string("value1") == a["field1"].as()); CHECK(std::string("value2") == a["object1"]["field2"].as()); } TEST_CASE("test_emplace_and_proxy_set") { json a; a.try_emplace("object1",json()); a.try_emplace("field1","value1"); a["object1"].try_emplace("field2","value2"); CHECK(std::string("value1") == a["field1"].as()); CHECK(std::string("value2") == a["object1"]["field2"].as()); } TEST_CASE("test_const_member_read") { json a; a["field1"] = 10; a["field2"]; const json b(a); int val1 = b["field1"].as(); CHECK(val1 == 10); REQUIRE_NOTHROW(b["field2"]); } TEST_CASE("test_proxy_const_member_read") { json a; a["object1"] = json(); a["object1"]["field1"] = "value1"; a["object1"]["field2"]; // Inserts empty object for "field2" const json b(a); std::string s1 = b["object1"]["field1"].as(); REQUIRE_NOTHROW(b["object1"]["field2"]); CHECK(s1 == std::string("value1")); } TEST_CASE("test_object_equals") { json a; a["field1"] = "value1"; json b; b["field1"] = "value1"; CHECK(a == b); json c; c["field1"] = 10; CHECK_FALSE(a == c); } TEST_CASE("json_object_iterator test 1") { SECTION("object_iterator") { json a = json::parse(R"({"name1" : "value1","name2" : "value2","name3" : "value3"})"); json::object_iterator it = a.object_range().begin(); CHECK((*it).key() == "name1"); CHECK((*it).value() == json("value1")); ++it; CHECK((*it).key() == "name2"); CHECK((*it).value() == json("value2")); CHECK((*(it++)).key() == "name2"); CHECK((*it).key() == "name3"); CHECK((*it).value() == json("value3")); CHECK((*(it--)).key() == "name3"); CHECK((*it).value() == json("value2")); CHECK((*(--it)).value() == json("value1")); json::key_value_type member = *it; CHECK(member.key() == "name1"); CHECK(member.value() == json("value1")); } SECTION("const_object_iterator 1") { json a = json::parse(R"({"name1" : "value1","name2" : "value2","name3" : "value3"})"); json::const_object_iterator it = a.object_range().begin(); CHECK((*it).key() == "name1"); CHECK((*it).value() == json("value1")); ++it; CHECK((*it).key() == "name2"); CHECK((*it).value() == json("value2")); CHECK((*(it++)).key() == "name2"); CHECK((*it).key() == "name3"); CHECK((*it).value() == json("value3")); CHECK((*(it--)).key() == "name3"); CHECK((*it).value() == json("value2")); CHECK((*(--it)).value() == json("value1")); json::key_value_type member = *it; CHECK(member.key() == "name1"); CHECK(member.value() == json("value1")); } SECTION("const_object_iterator 2") { const json a = json::parse(R"({"name1" : "value1","name2" : "value2","name3" : "value3"})"); json::const_object_iterator it = static_cast(a).object_range().begin(); CHECK((it == a.object_range().begin())); CHECK_FALSE((it == a.object_range().end())); CHECK((*it).key() == "name1"); CHECK((*it).value() == json("value1")); ++it; CHECK_FALSE((it == a.object_range().end())); CHECK((*it).key() == "name2"); CHECK((*it).value() == json("value2")); CHECK((*(it++)).key() == "name2"); CHECK_FALSE((it == a.object_range().end())); CHECK((*it).key() == "name3"); CHECK((*it).value() == json("value3")); CHECK((*(it--)).key() == "name3"); CHECK((*it).value() == json("value2")); CHECK((*(--it)).value() == json("value1")); CHECK((it == a.object_range().begin())); json::key_value_type member = *it; CHECK(member.key() == "name1"); CHECK(member.value() == json("value1")); //*it = member; // Don't want this to compile } SECTION("json cbegin") { json a = json::parse(R"({"name1" : "value1","name2" : "value2","name3" : "value3"})"); json::const_object_iterator it = a.object_range().cbegin(); CHECK((*it).key() == "name1"); CHECK((*it).value() == json("value1")); ++it; CHECK((*it).key() == "name2"); CHECK((*it).value() == json("value2")); CHECK((*(it++)).key() == "name2"); CHECK((*it).key() == "name3"); CHECK((*it).value() == json("value3")); CHECK((*(it--)).key() == "name3"); CHECK((*it).value() == json("value2")); CHECK((*(--it)).value() == json("value1")); json::key_value_type member = *it; CHECK(member.key() == "name1"); CHECK(member.value() == json("value1")); } SECTION("const json cbegin") { const json a = json::parse(R"({"name1" : "value1","name2" : "value2","name3" : "value3"})"); json::const_object_iterator it = a.object_range().cbegin(); CHECK((*it).key() == "name1"); CHECK((*it).value() == json("value1")); ++it; CHECK((*it).key() == "name2"); CHECK((*it).value() == json("value2")); CHECK((*(it++)).key() == "name2"); CHECK((*it).key() == "name3"); CHECK((*it).value() == json("value3")); CHECK((*(it--)).key() == "name3"); CHECK((*it).value() == json("value2")); CHECK((*(--it)).value() == json("value1")); json::key_value_type member = *it; CHECK(member.key() == "name1"); CHECK(member.value() == json("value1")); } } // accessor tests TEST_CASE("test_get_with_string_default") { json example; std::string s("too long string for short string"); std::string result = example.get_value_or("test", s); CHECK(s == result); } TEST_CASE("test_compare_with_string") { json a; a["key"] = "value"; a["key1"] = "value1"; a["key2"] = "value2"; CHECK(a["key"] == a["key"]); CHECK_FALSE((a["key"] == a["key1"])); CHECK_FALSE((a["key"] == a["key2"])); } TEST_CASE("test_count") { json a; a["key1"] = "value1"; a["key2"] = "value2"; CHECK(1 == a.count("key1")); CHECK(1 == a.count("key2")); CHECK(0 == a.count("key3")); json b = json::parse( "{\"key1\":\"a value\",\"key1\":\"another value\"}" ); CHECK(1 == b.count("key1")); } TEST_CASE("test_find") { json obj; json::object_iterator it = obj.find("key"); CHECK((it == obj.object_range().end())); obj["key1"] = 10; obj["key2"] = true; obj["key3"] = 'c'; obj["key4"] = "value4"; json::object_iterator it2 = obj.find("key"); CHECK((it2 == obj.object_range().end())); json::object_iterator it3 = obj.find("key4"); CHECK_FALSE((it3 == obj.object_range().end())); CHECK(std::string("value4") ==it3->value().as()); } TEST_CASE("test_as") { json obj; obj["field1"] = 10; obj["field2"] = true; obj["char_field"] = 'c'; obj["string_field"] = "char"; std::string s = obj["field1"].as(); CHECK(std::string("10") == s); int int_val = obj["field2"].as(); CHECK(1 == int_val); int short_val = obj["field2"].as(); CHECK(1 == short_val); int ushort_val = obj["field2"].as(); CHECK(ushort_val == static_cast(1)); char char_val = obj["field2"].as(); CHECK(1 == int(char_val)); CHECK(obj["char_field"].is()); CHECK_FALSE(obj["string_field"].is()); json parent; parent["child"] = obj; s = parent["child"]["field1"].as(); CHECK(s == std::string("10")); int_val = parent["child"]["field2"].as(); CHECK(1 == int_val); short_val = parent["child"]["field2"].as(); CHECK(1 == short_val); //json::object x = parent["child"].as(); // Compile time error, "as not supported" json empty; CHECK(empty.is_object()); CHECK(empty.empty()); //json::object y = empty.as(); // Compile time error, "as not supported" } TEST_CASE("test_as2") { json obj; obj["field1"] = "10"; obj["field2"] = "-10"; obj["field3"] = "10.1"; CHECK(10 == obj["field1"].as()); CHECK(-10 ==obj["field2"].as()); CHECK(10.1 == obj["field3"].as()); } TEST_CASE("test_is") { json obj; obj["field1"] = 10; obj["field2"] = -10; obj["field3"] = 10U; CHECK(obj["field1"].storage_kind() == jsoncons::json_storage_kind::int64); CHECK(obj["field2"].storage_kind() == jsoncons::json_storage_kind::int64); CHECK(obj["field3"].storage_kind() == jsoncons::json_storage_kind::uint64); CHECK_FALSE(obj["field1"].is()); CHECK(obj["field1"].is()); CHECK(obj["field1"].is()); CHECK(obj["field1"].is()); CHECK(obj["field1"].is()); CHECK(obj["field1"].is()); CHECK(obj["field1"].is()); CHECK(obj["field1"].is()); CHECK_FALSE(obj["field1"].is()); CHECK_FALSE(obj["field2"].is()); CHECK(obj["field2"].is()); CHECK(obj["field2"].is()); CHECK(obj["field2"].is()); CHECK(obj["field2"].is()); CHECK_FALSE(obj["field2"].is()); CHECK_FALSE(obj["field2"].is()); CHECK_FALSE(obj["field2"].is()); CHECK_FALSE(obj["field2"].is()); CHECK_FALSE(obj["field2"].is()); CHECK_FALSE(obj["field3"].is()); CHECK(obj["field3"].is()); CHECK(obj["field3"].is()); CHECK(obj["field3"].is()); CHECK(obj["field3"].is()); CHECK(obj["field3"].is()); CHECK(obj["field3"].is()); CHECK(obj["field3"].is()); CHECK_FALSE(obj["field3"].is()); } TEST_CASE("test_is2") { json obj = json::parse("{\"field1\":10}"); CHECK(obj["field1"].storage_kind() == jsoncons::json_storage_kind::uint64); CHECK_FALSE(obj["field1"].is()); CHECK(obj["field1"].is()); CHECK(obj["field1"].is()); CHECK(obj["field1"].is()); CHECK(obj["field1"].is()); CHECK(obj["field1"].is()); CHECK(obj["field1"].is()); CHECK_FALSE(obj["field1"].is()); } TEST_CASE("test_is_type") { json obj; CHECK(obj.is_object()); CHECK(obj.is_object()); // tests for proxy is_type methods obj["string"] = "val1"; CHECK(obj.is_object()); CHECK(obj.is_object()); CHECK(obj["string"].is_string()); CHECK(obj["string"].is()); obj["double"] = 10.7; CHECK(obj["double"].is_double()); CHECK(obj["double"].is()); obj["int"] = -10; CHECK(obj["int"].is_int64()); CHECK(obj["int"].is()); obj["uint"] = 10u; CHECK(obj["uint"].is_uint64()); CHECK(obj["uint"].is()); obj["long"] = static_cast(10); CHECK(obj["long"].is_int64()); CHECK(obj["long"].is()); obj["ulong"] = static_cast(10); CHECK(obj["ulong"].is_uint64()); CHECK(obj["ulong"].is()); obj["longlong"] = static_cast(10); CHECK(obj["longlong"].is_int64()); CHECK(obj["longlong"].is()); obj["ulonglong"] = static_cast(10); CHECK(obj["ulonglong"].is_uint64()); CHECK(obj["ulonglong"].is()); obj["true"] = true; CHECK(obj["true"].is_bool()); CHECK(obj["true"].is()); obj["false"] = false; CHECK(obj["false"].is_bool()); CHECK(obj["false"].is()); obj["null1"] = json::null(); CHECK(obj["null1"].is_null()); obj["object"] = json(); CHECK(obj["object"].is_object()); CHECK(obj["object"].is_object()); obj["array"] = json(json_array_arg); CHECK(obj["array"].is_array()); CHECK(obj["array"].is_array()); // tests for json is_type methods json str = obj["string"]; CHECK(str.is()); CHECK(str.is()); } TEST_CASE("test_object_get_defaults") { json obj; obj["field1"] = 1; obj["field3"] = "Toronto"; double x1 = obj.contains("field1") ? obj["field1"].as() : 10.0; double x2 = obj.contains("field2") ? obj["field2"].as() : 20.0; CHECK(x1 == 1.0); CHECK(x2 == 20.0); std::string s1 = obj.get_value_or ("field3", "Montreal"); std::string s2 = obj.get_value_or ("field4", "San Francisco"); CHECK(s1 =="Toronto"); CHECK(s2 == "San Francisco"); } TEST_CASE("test_object_accessing") { json obj; obj["first_name"] = "Jane"; obj["last_name"] = "Roe"; obj["events_attended"] = 10; obj["accept_waiver_of_liability"] = true; CHECK(obj["first_name"].as() == "Jane"); CHECK(obj.at("last_name").as() == "Roe"); CHECK(obj["events_attended"].as() == 10); CHECK(obj["accept_waiver_of_liability"].as()); } TEST_CASE("test_value_not_found_and_defaults") { json obj; obj["first_name"] = "Jane"; obj["last_name"] = "Roe"; CHECK_NOTHROW(obj["outdoor_experience"].as()); std::string experience = obj.contains("outdoor_experience") ? obj["outdoor_experience"].as() : ""; CHECK(experience == "{}"); } TEST_CASE("test_set_override") { json obj; obj["first_name"] = "Jane"; obj["height"] = 0.9; obj["first_name"] = "Joe"; obj["height"] = "0.3"; CHECK(obj["first_name"] == "Joe"); CHECK(obj["height"].as() == Approx(0.3).epsilon(0.00000000001)); } TEST_CASE("try_emplace tests") { json j = json::parse(R"( { "a" : 1, "b" : 2 } )"); json expected = json::parse(R"( { "a" : 1, "b" : 2, "c" : 3 } )"); SECTION("try_emplace(const string_view_type& name, Args&&... args)") { j.try_emplace("c",3); CHECK(expected == j); } SECTION("try_emplace(iterator hint, const string_view_type& name, Args&&... args)") { json::object_iterator it = j.object_range().begin(); j.try_emplace(it,"c",3); CHECK(expected == j); } } TEST_CASE("test json_object erase with iterator") { SECTION("json erase with iterator") { json j(jsoncons::json_object_arg); j.try_emplace("a", 1); j.try_emplace("b", 2); j.try_emplace("c", 3); auto it = j.object_range().begin(); while (it != j.object_range().end()) { if (it->key() == "a" || it->key() == "c") { it = j.erase(it); } else { it++; } } CHECK(1 == j.size()); CHECK(2 == j.at("b")); CHECK(2 == j["b"]); } SECTION("json erase with iterator 2") { json j(jsoncons::json_object_arg); j.try_emplace("a", 1); j.try_emplace("b", 2); j.try_emplace("c", 3); auto it = j.object_range().begin(); while (it != j.object_range().end()) { if (it->key() == "a") { it = j.erase(it,it+2); } else { it++; } } CHECK(1 == j.size()); CHECK(3 == j.at("c")); CHECK(3 == j["c"]); } } TEST_CASE("test empty json_object iterator") { SECTION("test 1") { json j; json::const_object_iterator it; CHECK(!it.has_value()); it = j.find("Min"); CHECK(!it.has_value()); CHECK(!j.object_range().end().has_value()); CHECK ((bool)(it == j.object_range().end())); } } // merge tests TEST_CASE("test_json_merge") { json j = json::parse(R"( { "a" : 1, "b" : 2 } )"); json j2 = j; const json source = json::parse(R"( { "a" : 2, "c" : 3 } )"); const json expected = json::parse(R"( { "a" : 1, "b" : 2, "c" : 3 } )"); SECTION("test 1") { j.merge(source); CHECK(expected == j); j2.merge(j2.object_range().begin()+1,source); CHECK(expected == j2); } SECTION("test 2") { json empty_object; json original = j; j.merge(empty_object); CHECK(j == original); j2.merge(j2.object_range().begin()+1,empty_object); CHECK(j2 == original); } //std::cout << j << '\n'; } TEST_CASE("test_json_merge_move") { json j = json::parse(R"( { "a" : "1", "b" : [1,2,3] } )"); json j2 = j; json source = json::parse(R"( { "a" : "2", "c" : [4,5,6] } )"); json expected = json::parse(R"( { "a" : "1", "b" : [1,2,3], "c" : [4,5,6] } )"); SECTION("test 1") { json source2 = source; j.merge(std::move(source)); CHECK(expected == j); j2.merge(std::move(source2)); CHECK(expected == j2); } } // merge_or_update tests TEST_CASE("test_json_merge_or_update") { json j = json::parse(R"( { "a" : 1, "b" : 2 } )"); json j2 = j; const json source = json::parse(R"( { "a" : 2, "c" : 3 } )"); const json expected = json::parse(R"( { "a" : 2, "b" : 2, "c" : 3 } )"); SECTION("test 1") { j.merge_or_update(source); CHECK(expected == j); j2.merge_or_update(j2.object_range().begin()+1,source); CHECK(expected == j2); } } TEST_CASE("test_json_merge_or_update_move") { json j = json::parse(R"( { "a" : "1", "b" : [1,2,3] } )"); json j2 = j; json source = json::parse(R"( { "a" : "2", "c" : [4,5,6] } )"); json expected = json::parse(R"( { "a" : "2", "b" : [1,2,3], "c" : [4,5,6] } )"); SECTION("test 1") { json source2 = source; j.merge_or_update(std::move(source)); CHECK(expected == j); j2.merge_or_update(std::move(source2)); CHECK(expected == j2); } } jsoncons-1.3.2/test/corelib/src/json_options_tests.cpp000066400000000000000000000366331477700171100232300ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("test json_options max_nesting_depth") { std::string str = R"( { "foo" : [1,2,3], "bar" : [4,5,{"f":6}] } )"; SECTION("success") { json_options options = json_options{} .max_nesting_depth(3); REQUIRE_NOTHROW(json::parse(str, options)); } SECTION("fail") { json_options options = json_options{} .max_nesting_depth(2); REQUIRE_THROWS(json::parse(str, options)); } } TEST_CASE("json_options allow_trailing_comma test") { SECTION("object with trailing comma") { auto options = json_options{} .allow_trailing_comma(true); json expected = json::parse("[1,2,3]"); json val = json::parse("[1,2,3,]", options); CHECK(expected == val); } SECTION("array with trailing comma") { auto options = json_options{} .allow_trailing_comma(true); json expected = json::parse(R"( { "first" : 1, "second" : 2 } )", options); json val = json::parse(R"( { "first" : 1, "second" : 2, } )", options); CHECK(expected == val); } } TEST_CASE("json_options allow_comments test") { SECTION("allow") { auto options = json_options{} .allow_comments(true); json expected = json::parse("[1,2]"); json val = json::parse("[1,2/*,3*/]", options); CHECK(expected == val); } SECTION("don't allow") { auto options = json_options{} .allow_comments(false); REQUIRE_THROWS(json::parse("[1,2/*,3*/]", options)); } } TEST_CASE("test_default_nan_replacement") { json obj; obj["field1"] = std::sqrt(-1.0); obj["field2"] = 1.79e308 * 1000; obj["field3"] = -1.79e308 * 1000; std::ostringstream os; os << print(obj); std::string expected = R"({"field1":null,"field2":null,"field3":null})"; CHECK(expected == os.str()); } TEST_CASE("test inf_to_num") { json j; j["field1"] = std::sqrt(-1.0); j["field2"] = 1.79e308 * 1000; j["field3"] = -1.79e308 * 1000; SECTION("inf_to_num") { auto options = json_options{} .inf_to_num("1e9999"); std::ostringstream os; os << print(j, options); std::string expected = R"({"field1":null,"field2":1e9999,"field3":-1e9999})"; CHECK(expected == os.str()); } } TEST_CASE("object: nan_to_str, inf_to_str, neginf_to_str test") { json j; j["field1"] = std::sqrt(-1.0); j["field2"] = 1.79e308 * 1000; j["field3"] = -1.79e308 * 1000; SECTION("pretty_print nan_to_str, inf_to_str, neginf_to_str") { auto options = json_options{} .nan_to_str("NaN") .inf_to_str("Inf") .neginf_to_str("NegInf") .line_splits(line_split_kind::same_line); std::ostringstream os; os << pretty_print(j, options); //std::cout << os.str() << "\n"; std::string expected = R"({"field1": "NaN", "field2": "Inf", "field3": "NegInf"})"; CHECK(expected == os.str()); } SECTION("print nan_to_str, inf_to_str, neginf_to_str") { auto options = json_options{} .nan_to_str("NaN") .inf_to_str("Inf") .inf_to_str("NegInf"); std::ostringstream os; os << print(j, options); //std::cout << os.str() << "\n"; std::string expected = R"({"field1":"NaN","field2":"NegInf","field3":"-NegInf"})"; CHECK(expected == os.str()); } } TEST_CASE("array: nan_to_str, inf_to_str, neginf_to_str test") { json j(json_array_arg); j.push_back(std::sqrt(-1.0)); j.push_back(1.79e308 * 1000); j.push_back(-1.79e308 * 1000); SECTION("pretty_print nan_to_str, inf_to_str, neginf_to_str") { auto options = json_options{} .nan_to_str("NaN") .inf_to_str("Inf") .neginf_to_str("NegInf") .line_splits(line_split_kind::same_line); std::ostringstream os; os << pretty_print(j, options); //std::cout << os.str() << "\n"; std::string expected = R"(["NaN", "Inf", "NegInf"])"; CHECK(expected == os.str()); } SECTION("print nan_to_str, inf_to_str, neginf_to_str") { auto options = json_options{} .nan_to_str("NaN") .inf_to_str("Inf") .inf_to_str("NegInf"); std::ostringstream os; os << print(j, options); //std::cout << os.str() << "\n"; std::string expected = R"(["NaN","NegInf","-NegInf"])"; CHECK(expected == os.str()); } } TEST_CASE("test_read_write_read_nan_replacement") { json j; j["field1"] = std::sqrt(-1.0); j["field2"] = 1.79e308 * 1000; j["field3"] = -1.79e308 * 1000; auto options = json_options{} .nan_to_str("MyNaN") .inf_to_str("MyInf"); std::ostringstream os; os << pretty_print(j, options); //std::cout << os.str() << "\n\n"; json j2 = json::parse(os.str(),options); json expected; expected["field1"] = std::nan(""); expected["field2"] = std::numeric_limits::infinity(); expected["field3"] = -std::numeric_limits::infinity(); std::string output1; std::string output2; j.dump(output1, options); expected.dump(output2, options); CHECK(output1 == output2); CHECK(expected.to_string() == j.to_string()); } TEST_CASE("object_array empty array") { std::string s = R"( { "foo": [] } )"; SECTION("same_line") { json j = json::parse(s); auto options = json_options{} .object_array_line_splits(line_split_kind::same_line); std::ostringstream os; os << pretty_print(j, options); std::string expected = R"({ "foo": [] })"; CHECK(expected == os.str()); } SECTION("new_line") { json j = json::parse(s); auto options = json_options{} .object_array_line_splits(line_split_kind::new_line); std::ostringstream os; os << pretty_print(j, options); std::string expected = R"({ "foo": [] })"; CHECK(expected == os.str()); } SECTION("multi_line") { json j = json::parse(s); auto options = json_options{} .object_array_line_splits(line_split_kind::multi_line); std::ostringstream os; os << pretty_print(j, options); std::string expected = R"({ "foo": [] })"; CHECK(expected == os.str()); } } TEST_CASE("object_array with/without line_length_limit") { std::string s = R"( { "foo": ["bar", "baz", [1, 2, 3]], "qux": [1, 2, 3, null, 123, 45.3, 342334, 234] } )"; SECTION("same_line") { std::string expected = R"({ "foo": ["bar","baz", [1,2,3] ], "qux": [1,2,3,null,123,45.3,342334,234] })"; json j = json::parse(s); auto options = json_options{} .line_length_limit(120) .spaces_around_comma(spaces_option::no_spaces) .object_array_line_splits(line_split_kind::same_line) .array_array_line_splits(line_split_kind::new_line); std::ostringstream os; os << pretty_print(j, options); CHECK(expected == os.str()); } SECTION("new_line") { std::string expected = R"({ "foo": [ "bar","baz", [1,2,3] ], "qux": [ 1,2,3,null,123,45.3,342334,234 ] })"; json j = json::parse(s); auto options = json_options{} .line_length_limit(120) .spaces_around_comma(spaces_option::no_spaces) .array_array_line_splits(line_split_kind::new_line) .object_array_line_splits(line_split_kind::new_line); std::ostringstream os; os << pretty_print(j, options); //std::cout << pretty_print(j, options) << "\n"; CHECK(expected == os.str()); } SECTION("multi_line") { std::string expected = R"({ "foo": [ "bar", "baz", [1,2,3] ], "qux": [ 1, 2, 3, null, 123, 45.3, 342334, 234 ] })"; json j = json::parse(s); auto options = json_options{} .spaces_around_comma(spaces_option::no_spaces) .array_array_line_splits(line_split_kind::same_line); std::ostringstream os; os << pretty_print(j, options); //std::cout << pretty_print(j, options) << "\n"; CHECK(expected == os.str()); } SECTION("same_line with line length limit") { std::string expected = R"({ "foo": ["bar","baz", [1,2,3] ], "qux": [1,2,3,null, 123,45.3,342334, 234 ] })"; json j = json::parse(s); auto options = json_options{} .line_length_limit(20) .spaces_around_comma(spaces_option::no_spaces) .object_array_line_splits(line_split_kind::same_line) .array_array_line_splits(line_split_kind::new_line); std::ostringstream os; os << pretty_print(j, options); //std::cout << pretty_print(j, options) << "\n"; CHECK(expected == os.str()); } SECTION("new_line with line length limit") // Revisit 234 { std::string expected = R"({ "foo": [ "bar","baz", [1,2,3] ], "qux": [ 1,2,3,null,123, 45.3,342334,234 ] })"; json j = json::parse(s); auto options = json_options{} .line_length_limit(20) .spaces_around_comma(spaces_option::no_spaces) .object_array_line_splits(line_split_kind::new_line) .array_array_line_splits(line_split_kind::new_line); std::ostringstream os; os << pretty_print(j, options); //std::cout << pretty_print(j, options) << "\n"; CHECK(expected == os.str()); } } TEST_CASE("json_options line_indent") { SECTION("array with line_indent_kind::same_line") { std::string j_str = R"(["1", "2", 3, 4])"; jsoncons::json j_arr = jsoncons::json::parse(j_str); auto options = json_options{} .spaces_around_comma(jsoncons::spaces_option::space_after) .line_splits(jsoncons::line_split_kind::same_line); std::string buffer; jsoncons::encode_json(j_arr, buffer, options, jsoncons::indenting::indent); CHECK(j_str == buffer); } SECTION("array with line_indent_kind::same_line") { std::string j_str = R"(["1", ["2", 3, 4]])"; jsoncons::json j_arr = jsoncons::json::parse(j_str); auto options = json_options{} .spaces_around_comma(jsoncons::spaces_option::space_after) .line_splits(jsoncons::line_split_kind::same_line); std::string buffer; jsoncons::encode_json(j_arr, buffer, options, jsoncons::indenting::indent); CHECK(j_str == buffer); } } TEST_CASE("array_object with/without line_length_limit") { std::string s = R"( [ { "author": "Graham Greene", "title": "The Comedians" }, { "author": "Koji Suzuki", "title": "ring" }, { "author": "Haruki Murakami", "title": "A Wild Sheep Chase" } ] )"; SECTION("same_line") { std::string expected = R"([ {"author": "Graham Greene","title": "The Comedians"}, {"author": "Koji Suzuki","title": "ring"}, {"author": "Haruki Murakami","title": "A Wild Sheep Chase"} ])"; json j = json::parse(s); auto options = json_options{} .line_length_limit(120) .spaces_around_comma(spaces_option::no_spaces) .array_object_line_splits(line_split_kind::same_line); std::ostringstream os; os << pretty_print(j, options); //std::cout << pretty_print(j, options) << "\n"; CHECK(expected == os.str()); } SECTION("new_line") { std::string expected = R"([ {"author": "Graham Greene","title": "The Comedians"}, {"author": "Koji Suzuki","title": "ring"}, {"author": "Haruki Murakami","title": "A Wild Sheep Chase"} ])"; json j = json::parse(s); auto options = json_options{} .line_length_limit(120) .spaces_around_comma(spaces_option::no_spaces) .array_object_line_splits(line_split_kind::new_line); std::ostringstream os; os << pretty_print(j, options); //std::cout << pretty_print(j, options) << "\n"; CHECK(expected == os.str()); } SECTION("multi_line (default)") { std::string expected = R"([ { "author": "Graham Greene", "title": "The Comedians" }, { "author": "Koji Suzuki", "title": "ring" }, { "author": "Haruki Murakami", "title": "A Wild Sheep Chase" } ])"; json j = json::parse(s); auto options = json_options{} .spaces_around_comma(spaces_option::no_spaces); std::ostringstream os; os << pretty_print(j, options); //std::cout << pretty_print(j, options) << "\n"; CHECK(expected == os.str()); } SECTION("same_line with line length limit") { std::string expected = R"([ {"author": "Graham Greene", "title": "The Comedians"}, {"author": "Koji Suzuki", "title": "ring"}, {"author": "Haruki Murakami", "title": "A Wild Sheep Chase"} ])"; json j = json::parse(s); auto options = json_options{} .line_length_limit(20) .spaces_around_comma(spaces_option::no_spaces) .array_object_line_splits(line_split_kind::same_line); std::ostringstream os; os << pretty_print(j, options); //std::cout << pretty_print(j, options) << "\n"; CHECK(expected == os.str()); } SECTION("new_line with line length limit") { std::string expected = R"([ {"author": "Graham Greene", "title": "The Comedians"}, {"author": "Koji Suzuki", "title": "ring"}, {"author": "Haruki Murakami", "title": "A Wild Sheep Chase"} ])"; json j = json::parse(s); auto options = json_options{} .line_length_limit(20) .spaces_around_comma(spaces_option::no_spaces) .array_object_line_splits(line_split_kind::new_line); std::ostringstream os; os << pretty_print(j, options); CHECK(expected == os.str()); //std::cout << pretty_print(j, options) << "\n"; } } TEST_CASE("json_options tests") { SECTION("pad_inside_array_brackets") { std::string s = R"({ "foo": [ 1, 2 ] })"; json j = json::parse(s); auto options = json_options{} .pad_inside_array_brackets(true) .object_array_line_splits(line_split_kind::same_line); std::ostringstream os; j.dump_pretty(os, options); CHECK(os.str() == s); } SECTION("pad_inside_object_braces") { std::string s = R"([ { "foo": 1 } ])"; json j = json::parse(s); auto options = json_options{} .pad_inside_object_braces(true) .array_object_line_splits(line_split_kind::same_line); std::ostringstream os; j.dump_pretty(os, options); CHECK(os.str() == s); } } jsoncons-1.3.2/test/corelib/src/json_parser_error_tests.cpp000066400000000000000000000165541477700171100242420ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include using namespace jsoncons; void test_parse_error(const std::string& text, const std::error_code& ec) { REQUIRE_THROWS(json::parse(text)); JSONCONS_TRY { json::parse(text); } JSONCONS_CATCH (const ser_error& e) { if (e.code() != ec) { std::cout << text << '\n'; std::cout << e.code().value() << " " << e.what() << '\n'; } CHECK(ec == e.code()); } } void test_parse_ec(const std::string& text, const std::error_code& expected) { std::error_code ec; std::istringstream is(text); json_decoder decoder; json_stream_reader reader(is,decoder); reader.read(ec); //std::cerr << text << '\n'; //std::cerr << ec.message() // << " at line " << reader.line() // << " and column " << reader.column() << '\n'; CHECK(ec); CHECK(expected == ec); } TEST_CASE("test_parse_missing_separator") { std::string jtext = R"({"field1"{}})"; test_parse_error(jtext, jsoncons::json_errc::expected_colon); test_parse_ec(jtext, jsoncons::json_errc::expected_colon); } TEST_CASE("test_invalid_value") { std::string jtext = R"({"field1":ru})"; test_parse_error(jtext,jsoncons::json_errc::expected_value); test_parse_ec(jtext, jsoncons::json_errc::expected_value); } TEST_CASE("test_unexpected_end_of_file") { std::string jtext = R"({"field1":{})"; test_parse_error(jtext, jsoncons::json_errc::unexpected_eof); test_parse_ec(jtext, jsoncons::json_errc::unexpected_eof); } TEST_CASE("test_value_not_found") { std::string jtext = R"({"name":})"; test_parse_error(jtext, jsoncons::json_errc::expected_value); test_parse_ec(jtext, jsoncons::json_errc::expected_value); } TEST_CASE("test_escaped_characters") { std::string input("[\"\\n\\b\\f\\r\\t\"]"); std::string expected("\n\b\f\r\t"); json o = json::parse(input); CHECK(expected == o[0].as()); } TEST_CASE("test_expected_colon") { test_parse_error("{\"name\" 10}", jsoncons::json_errc::expected_colon); test_parse_error("{\"name\" true}", jsoncons::json_errc::expected_colon); test_parse_error("{\"name\" false}", jsoncons::json_errc::expected_colon); test_parse_error("{\"name\" null}", jsoncons::json_errc::expected_colon); test_parse_error("{\"name\" \"value\"}", jsoncons::json_errc::expected_colon); test_parse_error("{\"name\" {}}", jsoncons::json_errc::expected_colon); test_parse_error("{\"name\" []}", jsoncons::json_errc::expected_colon); } TEST_CASE("test_expected_key") { test_parse_error("{10}", jsoncons::json_errc::expected_key); test_parse_error("{true}", jsoncons::json_errc::expected_key); test_parse_error("{false}", jsoncons::json_errc::expected_key); test_parse_error("{null}", jsoncons::json_errc::expected_key); test_parse_error("{{}}", jsoncons::json_errc::expected_key); test_parse_error("{[]}", jsoncons::json_errc::expected_key); } TEST_CASE("test_expected_value") { test_parse_error("[tru]", jsoncons::json_errc::invalid_value); test_parse_error("[fa]", jsoncons::json_errc::invalid_value); test_parse_error("[n]", jsoncons::json_errc::invalid_value); } TEST_CASE("test_parse_primitive_pass") { json val; CHECK_NOTHROW((val=json::parse("null"))); CHECK(val == json::null()); CHECK_NOTHROW((val=json::parse("false"))); CHECK(val == json(false)); CHECK_NOTHROW((val=json::parse("true"))); CHECK(val == json(true)); CHECK_NOTHROW((val=json::parse("10"))); CHECK(val == json(10)); CHECK_NOTHROW((val=json::parse("1.999"))); CHECK(val == json(1.999)); CHECK_NOTHROW((val=json::parse("\"string\""))); CHECK(val == json("string")); } TEST_CASE("test_parse_empty_structures") { json val; CHECK_NOTHROW((val=json::parse("{}"))); CHECK_NOTHROW((val=json::parse("[]"))); CHECK_NOTHROW((val=json::parse("{\"object\":{},\"array\":[]}"))); CHECK_NOTHROW((val=json::parse("[[],{}]"))); } TEST_CASE("test_parse_primitive_fail") { test_parse_error("null {}", jsoncons::json_errc::extra_character); test_parse_error("n ", jsoncons::json_errc::invalid_value); test_parse_error("nu ", jsoncons::json_errc::invalid_value); test_parse_error("nul ", jsoncons::json_errc::invalid_value); test_parse_error("false {}", jsoncons::json_errc::extra_character); test_parse_error("fals ", jsoncons::json_errc::invalid_value); test_parse_error("true []", jsoncons::json_errc::extra_character); test_parse_error("tru ", jsoncons::json_errc::invalid_value); test_parse_error("10 {}", jsoncons::json_errc::extra_character); test_parse_error("1a ", jsoncons::json_errc::invalid_number); test_parse_error("1.999 []", jsoncons::json_errc::extra_character); test_parse_error("1e0-1", jsoncons::json_errc::invalid_number); test_parse_error("\"string\"{}", jsoncons::json_errc::extra_character); test_parse_error("\"string\"[]", jsoncons::json_errc::extra_character); } TEST_CASE("test_multiple") { std::string in="{\"a\":1,\"b\":2,\"c\":3}{\"a\":4,\"b\":5,\"c\":6}"; //std::cout << in << '\n'; std::istringstream is(in); jsoncons::json_decoder decoder; json_stream_reader reader(is,decoder); REQUIRE_FALSE(reader.eof()); reader.read_next(); CHECK_FALSE(reader.eof()); json val = decoder.get_result(); CHECK(1 == val["a"].as()); REQUIRE_FALSE(reader.eof()); reader.read_next(); CHECK(reader.eof()); json val2 = decoder.get_result(); CHECK(4 == val2["a"].as()); } TEST_CASE("test_uinteger_overflow") { uint64_t m = (std::numeric_limits::max)(); std::string s1 = std::to_string(m); std::string s2 = s1; s2.push_back('0'); json j1 = json::parse(s1); CHECK(j1.is_uint64()); CHECK(m == j1.as()); json j2 = json::parse(s2); CHECK_FALSE(j2.is_uint64()); CHECK(j2.is()); CHECK(s2 == j2.as()); } TEST_CASE("test_negative_integer_overflow") { int64_t m = (std::numeric_limits::lowest)(); std::string s1 = std::to_string(m); std::string s2 = s1; s2.push_back('0'); json j1 = json::parse(s1); CHECK(m == j1.as()); json j2 = json::parse(s2); CHECK_FALSE(j2.is_int64()); CHECK(j2.is_bignum()); CHECK(s2 == j2.as()); } TEST_CASE("test_positive_integer_overflow") { int64_t m = (std::numeric_limits::max)(); std::string s1 = std::to_string(m); std::string s2 = s1; s2.push_back('0'); json j1 = json::parse(s1); CHECK(m == j1.as()); json j2 = json::parse(s2); CHECK_FALSE(j2.is_int64()); CHECK(j2.is()); CHECK(s2 == j2.as()); } TEST_CASE("test json_parser errors") { SECTION("empty string") { std::vector vec{ "", " ", " \t ", " \n "}; for (const auto& str : vec) { jsoncons::json_string_reader reader(str); std::error_code ec; reader.read(ec); reader.check_done(); CHECK(ec == json_errc::unexpected_eof); } } } jsoncons-1.3.2/test/corelib/src/json_parser_position_tests.cpp000066400000000000000000000174771477700171100247620ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include using namespace jsoncons; namespace { class string_locator : public jsoncons::default_json_visitor { std::string path_; std::string from_; std::vector current_; std::vector& positions_; std::vector < std::pair> arrayIndexes; //Position in current_, value std::vector arrayObjects_; bool check = false; bool alreadyUpdated = false; public: using jsoncons::default_json_visitor::string_view_type; string_locator(const std::string& path, const std::string& from, std::vector& positions) : path_(path), from_(from), positions_(positions) { } std::string buildNormalizedPath(const std::vector& iKeyList) { //Init std::string aNormalizedPath = "$"; //For each key in the current stack for (auto& key : iKeyList) { aNormalizedPath += "[" + key + "]"; } return aNormalizedPath; } void custom_visit(const ser_context& context) { if (check) { arrayObjects_.push_back(current_.size()); } check = false; std::string aNormPath; if (arrayObjects_.size() > 0 && arrayObjects_.back() == current_.size() && arrayIndexes.size() > 0) { auto& p = arrayIndexes.back(); current_.at(p.first) = std::to_string(p.second); aNormPath = buildNormalizedPath(current_); p.second += 1; } else { aNormPath = buildNormalizedPath(current_); } //std::cout << aNormPath << '\n'; if (path_ == aNormPath) { positions_.push_back(context.position()); } alreadyUpdated = false; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_object(semantic_tag, const ser_context&, std::error_code&) override { //If we are in an array of objects and we are at the same depth (current_.size()) of the object if (arrayObjects_.size() > 0 && arrayObjects_.back() == current_.size()) { auto& p = arrayIndexes.back(); p.second += 1; current_.at(p.first) = std::to_string(p.second); }else if (check) { //we have an array of objects //we save the size of the current stack in a vector //so when we are again at this size it means we need to update the index arrayObjects_.push_back(current_.size()); } current_.emplace_back(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_object(const ser_context&, std::error_code&) override { current_.pop_back(); check = false; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_key(const string_view_type& key, const ser_context&, std::error_code&) override { if (!current_.empty()) { current_.back() = std::string("'") + std::string(key) + std::string("'"); } check = false; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_begin_array(semantic_tag, const ser_context&, std::error_code&) override { current_.emplace_back(std::to_string(0)); arrayIndexes.emplace_back(std::make_pair(current_.size()-1,0)); check = true; JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_end_array(const ser_context&, std::error_code&) override { current_.pop_back(); arrayIndexes.pop_back(); check = false; arrayObjects_.pop_back(); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_string(const string_view_type&, jsoncons::semantic_tag, const jsoncons::ser_context& context, std::error_code&) override { custom_visit(context); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_null(semantic_tag, const ser_context&, std::error_code&) override { JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_uint64(uint64_t, semantic_tag, const ser_context& context, std::error_code&) override { custom_visit(context); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_int64(int64_t, semantic_tag, const ser_context& context, std::error_code&) override { custom_visit(context); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_double(double, semantic_tag, const ser_context& context, std::error_code&) override { custom_visit(context); JSONCONS_VISITOR_RETURN; } JSONCONS_VISITOR_RETURN_TYPE visit_bool(bool, semantic_tag, const ser_context& context, std::error_code&) override { custom_visit(context); JSONCONS_VISITOR_RETURN; } }; void update_in_place(std::string& input, const std::string& path, std::vector& positions) { string_locator updater(path, "", positions); jsoncons::json_string_reader reader(input, updater); reader.read(); } } TEST_CASE("json_parser position") { SECTION("test 1") { std::string input1 = R"( { "Parent": { "Child": { "Test": 4444333322221111, "NegativeInt": -4444333322221111, "Double" : 12345.6789, "NegativeDouble" : -12345.6789 } } } )"; std::string input2 = R"( { "Parent": { "Child": { "Test": "4444333322221111" } } } )"; try { std::vector positions; update_in_place(input1, "$['Parent']['Child']['Test']", positions); REQUIRE(1 == positions.size()); CHECK(input1.substr(positions.back(),16) == std::string("4444333322221111")); positions.clear(); update_in_place(input2, "$['Parent']['Child']['Test']", positions); REQUIRE(1 == positions.size()); CHECK(input2.substr(positions.back(),18) == std::string("\"4444333322221111\"")); positions.clear(); update_in_place(input1, "$['Parent']['Child']['NegativeInt']", positions); REQUIRE(1 == positions.size()); CHECK(input1.substr(positions.back(),17) == std::string("-4444333322221111")); positions.clear(); update_in_place(input1, "$['Parent']['Child']['Double']", positions); REQUIRE(1 == positions.size()); CHECK(input1.substr(positions.back(),10) == std::string("12345.6789")); positions.clear(); update_in_place(input1, "$['Parent']['Child']['NegativeDouble']", positions); REQUIRE(1 == positions.size()); CHECK(input1.substr(positions.back(),11) == std::string("-12345.6789")); } catch (std::exception& e) { std::cout << e.what() << "\n"; } } } jsoncons-1.3.2/test/corelib/src/json_parser_recovery_tests.cpp000066400000000000000000000066761477700171100247530ustar00rootroot00000000000000 // Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("test_array_extra_comma") { SECTION("using err_handler") { allow_trailing_commas err_handler; json expected = json::parse("[1,2,3]"); auto options = json_options{} .err_handler(err_handler); json val = json::parse("[1,2,3,]", options); CHECK(expected == val); } SECTION("with option") { auto options = json_options{} .allow_trailing_comma(true); json expected = json::parse("[1,2,3]"); json val = json::parse("[1,2,3,]", options); CHECK(expected == val); } } TEST_CASE("test_object_extra_comma") { SECTION("using err_handler") { allow_trailing_commas err_handler; json expected = json::parse(R"( { "first" : 1, "second" : 2 } )", err_handler); json val = json::parse(R"( { "first" : 1, "second" : 2, } )", err_handler); CHECK(expected == val); } SECTION("with option") { auto options = json_options{} .allow_trailing_comma(true); json expected = json::parse(R"( { "first" : 1, "second" : 2 } )", options); json val = json::parse(R"( { "first" : 1, "second" : 2, } )", options); CHECK(expected == val); } } TEST_CASE("test json_parser error recovery") { SECTION("illegal control character") { auto err_handler = [](const std::error_code& ec, const ser_context&) noexcept -> bool { return ec == json_errc::illegal_control_character; }; std::string str; str.push_back('"'); str.push_back('C'); str.push_back(0x0e); str.push_back('a'); str.push_back('t'); str.push_back('"'); auto j = jsoncons::json::parse(str, err_handler); REQUIRE(j.is_string()); CHECK(j.as_string() == "Cat"); } SECTION("\r") { auto err_handler = [](const std::error_code& ec, const ser_context&) noexcept -> bool { return ec == json_errc::illegal_character_in_string; }; std::string str; str.push_back('C'); str.push_back('\r'); str.push_back('a'); str.push_back('t'); std::string str2; str2.push_back('"'); str2.append(str); str2.push_back('"'); auto j = jsoncons::json::parse(str2, err_handler); REQUIRE(j.is_string()); CHECK(j.as_string() == "Cat"); } SECTION("\n") { auto err_handler = [](const std::error_code& ec, const ser_context&) noexcept -> bool { return ec == json_errc::illegal_character_in_string; }; std::string str; str.push_back('C'); str.push_back('\n'); str.push_back('a'); str.push_back('t'); std::string str2; str2.push_back('"'); str2.append(str); str2.push_back('"'); auto j = jsoncons::json::parse(str2, err_handler); REQUIRE(j.is_string()); CHECK(j.as_string() == "Cat"); } } jsoncons-1.3.2/test/corelib/src/json_parser_tests.cpp000066400000000000000000000222451477700171100230230ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("Test cyrillic.json") { std::string path = "./corelib/input/cyrillic.json"; std::fstream is(path); if (!is) { std::cout << "Cannot open " << path << '\n'; } REQUIRE(is); json j = json::parse(is); } TEST_CASE("test_object2") { json source = json::parse(R"( { "a" : "2", "c" : [4,5,6] } )"); std::cout << source << '\n'; } TEST_CASE("test_object_with_three_members") { std::string input = "{\"A\":\"Jane\", \"B\":\"Roe\",\"C\":10}"; json val = json::parse(input); CHECK(true == val.is_object()); CHECK(3 == val.size()); } TEST_CASE("test_double") { json val = json::parse("42.229999999999997"); } TEST_CASE("test_array_of_integer") { std::string s = "[1,2,3]"; json j1 = json::parse(s); CHECK(true == j1.is_array()); CHECK(3 == j1.size()); std::istringstream is(s); json j2 = json::parse(is); CHECK(true == j2.is_array()); CHECK(3 == j2.size()); } TEST_CASE("test_skip_bom") { std::string s = "\xEF\xBB\xBF[1,2,3]"; json j1 = json::parse(s); CHECK(true == j1.is_array()); CHECK(3 == j1.size()); std::istringstream is(s); json j2 = json::parse(is); CHECK(true == j2.is_array()); CHECK(3 == j2.size()); } TEST_CASE("test_parse_empty_object") { jsoncons::json_decoder decoder; json_parser parser; parser.reset(); static std::string s("{}"); parser.update(s.data(),s.length()); parser.parse_some(decoder); parser.finish_parse(decoder); CHECK(parser.done()); json j = decoder.get_result(); } TEST_CASE("test_parse_array") { jsoncons::json_decoder decoder; json_parser parser; parser.reset(); static std::string s("[]"); parser.update(s.data(),s.length()); parser.parse_some(decoder); parser.finish_parse(decoder); CHECK(parser.done()); json j = decoder.get_result(); } TEST_CASE("test_parse_string") { jsoncons::json_decoder decoder; json_parser parser; parser.reset(); static std::string s("\"\""); parser.update(s.data(),s.length()); parser.parse_some(decoder); parser.finish_parse(decoder); CHECK(parser.done()); json j = decoder.get_result(); } TEST_CASE("test_parse_integer") { jsoncons::json_decoder decoder; json_parser parser; parser.reset(); static std::string s("10"); parser.update(s.data(),s.length()); parser.parse_some(decoder); parser.finish_parse(decoder); CHECK(parser.done()); json j = decoder.get_result(); } TEST_CASE("test_parse_integer_space") { jsoncons::json_decoder decoder; json_parser parser; parser.reset(); static std::string s("10 "); parser.update(s.data(),s.length()); parser.parse_some(decoder); parser.finish_parse(decoder); CHECK(parser.done()); json j = decoder.get_result(); } TEST_CASE("test_parse_double_space") { jsoncons::json_decoder decoder; json_parser parser; parser.reset(); static std::string s("10.0 "); parser.update(s.data(),s.length()); parser.parse_some(decoder); parser.finish_parse(decoder); CHECK(parser.done()); json j = decoder.get_result(); } TEST_CASE("test_parse_false") { jsoncons::json_decoder decoder; json_parser parser; parser.reset(); static std::string s("false"); parser.update(s.data(),s.length()); parser.parse_some(decoder); parser.finish_parse(decoder); CHECK(parser.done()); json j = decoder.get_result(); } TEST_CASE("test_parse_true") { jsoncons::json_decoder decoder; json_parser parser; parser.reset(); static std::string s("true"); parser.update(s.data(),s.length()); parser.parse_some(decoder); parser.finish_parse(decoder); CHECK(parser.done()); json j = decoder.get_result(); } TEST_CASE("test_parse_null") { jsoncons::json_decoder decoder; json_parser parser; parser.reset(); static std::string s("null"); parser.update(s.data(),s.length()); parser.parse_some(decoder); parser.finish_parse(decoder); CHECK(parser.done()); json j = decoder.get_result(); } TEST_CASE("test incremental parsing") { SECTION("array of bool") { jsoncons::json_decoder decoder; json_parser parser; parser.reset(); parser.update("[fal",4); parser.parse_some(decoder); CHECK_FALSE(parser.done()); CHECK(parser.source_exhausted()); parser.update("se]",3); parser.parse_some(decoder); parser.finish_parse(decoder); CHECK(parser.done()); json j = decoder.get_result(); REQUIRE(j.is_array()); CHECK_FALSE(j[0].as()); } } TEST_CASE("test_parser_reinitialization") { jsoncons::json_decoder decoder; json_parser parser; parser.reset(); parser.update("false true", 10); parser.finish_parse(decoder); CHECK(parser.done()); CHECK_FALSE(parser.source_exhausted()); json j1 = decoder.get_result(); REQUIRE(j1.is_bool()); CHECK_FALSE(j1.as()); parser.reinitialize(); parser.update("-42", 3); parser.finish_parse(decoder); CHECK(parser.done()); CHECK(parser.source_exhausted()); json j2 = decoder.get_result(); REQUIRE(j2.is_int64()); CHECK(j2.as() == -42); } TEST_CASE("test_diagnostics_visitor", "") { SECTION("narrow char") { std::ostringstream os; json_diagnostics_visitor visitor(os, " "); json_parser parser; std::string input(R"({"foo":[42,null]})"); parser.update(input.data(), input.size()); parser.finish_parse(visitor); std::ostringstream expected; expected << "visit_begin_object" << '\n' << " visit_key:foo" << '\n' << " visit_begin_array" << '\n' << " visit_uint64:42" << '\n' << " visit_null" << '\n' << " visit_end_array" << '\n' << "visit_end_object" << '\n'; CHECK(os.str() == expected.str()); } SECTION("wide char") { std::wostringstream os; wjson_diagnostics_visitor visitor(os, L" "); wjson_parser parser; std::wstring input(LR"({"foo":[42,null]})"); parser.update(input.data(), input.size()); parser.finish_parse(visitor); std::wostringstream expected; expected << L"visit_begin_object" << '\n' << L" visit_key:foo" << '\n' << L" visit_begin_array" << '\n' << L" visit_uint64:42" << '\n' << L" visit_null" << '\n' << L" visit_end_array" << '\n' << L"visit_end_object" << '\n'; CHECK(os.str() == expected.str()); } } TEST_CASE("json_parser skip space tests") { SECTION("test 1") { jsoncons::json_decoder decoder; json_parser parser; std::string line1 = "[false\r"; std::string line2 = ",true]"; parser.update(line1.data(), line1.size()); parser.parse_some(decoder); CHECK_FALSE(parser.done()); CHECK(parser.source_exhausted()); parser.update(line2.data(), line2.size()); parser.parse_some(decoder); //std::cout << "position:" << parser.position() << "line:" << parser.line() << "column:" << parser.column() << "\n"; CHECK(12 == parser.position()); CHECK(2 == parser.line()); CHECK(7 == parser.column()); } SECTION("test 2") { jsoncons::json_decoder decoder; json_parser parser; std::string line1 = "[false\r"; std::string line2 = "\n,true]"; parser.update(line1.data(), line1.size()); parser.parse_some(decoder); CHECK_FALSE(parser.done()); CHECK(parser.source_exhausted()); parser.update(line2.data(), line2.size()); parser.parse_some(decoder); //std::cout << "position:" << parser.position() << "line:" << parser.line() << "column:" << parser.column() << "\n"; CHECK(13 == parser.position()); CHECK(2 == parser.line()); CHECK(7 == parser.column()); } SECTION("test 3") { jsoncons::json_decoder decoder; json_parser parser; std::string line1 = "[false\n"; std::string line2 = ",true]"; parser.update(line1.data(), line1.size()); parser.parse_some(decoder); CHECK_FALSE(parser.done()); CHECK(parser.source_exhausted()); parser.update(line2.data(), line2.size()); parser.parse_some(decoder); //std::cout << "position:" << parser.position() << "line:" << parser.line() << "column:" << parser.column() << "\n"; CHECK(12 == parser.position()); CHECK(2 == parser.line()); CHECK(7 == parser.column()); } } jsoncons-1.3.2/test/corelib/src/json_pointer_arg_tests.cpp000066400000000000000000000214661477700171100240440ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("json_reference array tests") { json j = json::parse(R"( [1, "two", "three"] )"); SECTION("size()") { json v(json_pointer_arg, &j); REQUIRE(v.is_array()); CHECK(v.get_allocator() == j.get_allocator()); REQUIRE(j.size() == v.size()); v.resize(4); REQUIRE(4 == v.size()); CHECK(json{} == v[3]); v.resize(5, json{jsoncons::null_arg}); REQUIRE(5 == v.size()); CHECK(json{} == v[3]); CHECK(json::null() == v[4]); CHECK(v[4].is_null()); } SECTION("compare with json_const_pointer_arg") { json other{ j }; json j1(json_pointer_arg, &other); json j2(json_const_pointer_arg, &other); CHECK(j1 == j2); CHECK(j == j1); CHECK(j == j2); j[0] = "one"; CHECK(j1 == j2); CHECK_FALSE(j == j1); CHECK_FALSE(j == j2); } SECTION("capacity()") { json v(json_pointer_arg, &j); REQUIRE(v.is_array()); CHECK(j.capacity() == v.capacity()); v.reserve(4); REQUIRE(4 == v.capacity()); } SECTION("empty()") { json v(json_pointer_arg, &j); REQUIRE(v.is_array()); CHECK_FALSE(v.empty()); } SECTION("is_int64()") { json v(json_pointer_arg, &j); REQUIRE(v.is_array()); CHECK(v[0].is_int64()); CHECK_FALSE(v[1].is_int64()); } SECTION("is_number()") { json v(json_pointer_arg, &j); REQUIRE(v.is_array()); CHECK(v[0].is_number()); CHECK_FALSE(v[1].is_number()); } SECTION("operator[]") { json expected = json::parse(R"( [1, "two", "four"] )"); json v(json_pointer_arg, &j); CHECK(v.storage_kind() == json_storage_kind::json_reference); j[2] = "four"; CHECK(expected == v); } SECTION("const operator[]") { const json v(json_pointer_arg, &j); CHECK(v.storage_kind() == json_storage_kind::json_reference); CHECK("three" == v[2]); } SECTION("at()") { json v(json_pointer_arg, &j); REQUIRE(v.is_array()); REQUIRE_NOTHROW(v.at(1)); CHECK("two" == v[1]); } SECTION("const at()") { const json v(json_pointer_arg, &j); REQUIRE(v.is_array()); REQUIRE_NOTHROW(v.at(1)); CHECK("two" == v[1]); } SECTION("copy") { json v(json_pointer_arg, &j); CHECK(v.storage_kind() == json_storage_kind::json_reference); json j2(v); CHECK(j2.storage_kind() == json_storage_kind::json_reference); } SECTION("assignment") { json v(json_pointer_arg, &j); CHECK(v.storage_kind() == json_storage_kind::json_reference); json j2; j2 = v; CHECK(j2.storage_kind() == json_storage_kind::json_reference); } SECTION("push_back") { json expected = json::parse(R"( [1, "two", "three", "four"] )"); json v(json_pointer_arg, &j); CHECK(v.storage_kind() == json_storage_kind::json_reference); j.push_back("four"); CHECK(expected == v); } SECTION("emplace_back") { json expected = json::parse(R"( [1, "two", "three", "four"] )"); json v(json_pointer_arg, &j); CHECK(v.storage_kind() == json_storage_kind::json_reference); j.emplace_back("four"); CHECK(expected == v); } } TEST_CASE("json_reference object tests") { json j = json::parse(R"( {"one" : 1, "two" : 2, "three" : 3} )"); SECTION("size()") { json v(json_pointer_arg, &j); REQUIRE(v.is_object()); CHECK(3 == v.size()); CHECK_FALSE(v.empty()); } SECTION("compare with json_const_pointer_arg") { json other{ j }; json j1(json_pointer_arg, &other); json j2(json_const_pointer_arg, &other); CHECK(j1 == j2); CHECK(j == j1); CHECK(j == j2); j["one"] = 4; CHECK(j1 == j2); CHECK_FALSE(j == j1); CHECK_FALSE(j == j2); } SECTION("at()") { json v(json_pointer_arg, &j); REQUIRE(v.is_object()); REQUIRE_NOTHROW(v.at("two")); CHECK(v.contains("two")); CHECK(1 == v.count("two")); CHECK(3 == v.get_value_or("three", 0)); CHECK(4 == v.get_value_or("four", 4)); v.at("one") = "first"; CHECK("first" == v.at("one")); } SECTION("insert_or_assign()") { json expected = json::parse(R"( {"one" : 1, "two" : 2, "three" : "third", "four" : 4} )"); json v(json_pointer_arg, &j); REQUIRE(v.is_object()); REQUIRE_NOTHROW(v.at("two")); CHECK(v.contains("two")); CHECK(1 == v.count("two")); CHECK(3 == v.get_value_or("three", 0)); CHECK(4 == v.get_value_or("four", 4)); v.insert_or_assign("four", 4); v.insert_or_assign("three", "third"); CHECK(expected == v); } SECTION("try_emplace()") { json expected = json::parse(R"( {"one" : 1, "two" : 2, "three" : 3, "four" : 4} )"); json v(json_pointer_arg, &j); REQUIRE(v.is_object()); REQUIRE_NOTHROW(v.at("two")); CHECK(v.contains("two")); CHECK(1 == v.count("two")); CHECK(3 == v.get_value_or("three", 0)); CHECK(4 == v.get_value_or("four", 4)); v.try_emplace("four", 4); v.try_emplace("three", "third"); // does nothing CHECK(expected == v); } SECTION("merge()") { json expected1 = json::parse(R"( {"one" : 1, "two" : 2, "three" : 3, "four" : 4} )"); json expected2 = json::parse(R"( {"one" : 1, "two" : 2, "three" : 3, "four" : 4, "five" : 5} )"); json j1 = json::parse(R"( {"three" : "third", "four" : 4} )"); json v(json_pointer_arg, &j); REQUIRE(v.is_object()); v.merge(j1); CHECK(expected1 == v); json j2 = json::parse(R"( {"five" : 5} )"); j2.merge(v); CHECK(expected2 == j2); } SECTION("merge_or_update()") { json expected1 = json::parse(R"( {"one" : 1, "two" : 2, "three" : "third", "four" : 4} )"); json expected2 = json::parse(R"( {"one" : 1, "two" : 2, "three" : "third", "four" : 4, "five" : 5} )"); json j1 = json::parse(R"( {"three" : "third", "four" : 4} )"); json v(json_pointer_arg, &j); REQUIRE(v.is_object()); v.merge_or_update(j1); CHECK(expected1 == v); json j2 = json::parse(R"( {"five" : 5} )"); j2.merge_or_update(v); CHECK(expected2 == j2); } } TEST_CASE("json_reference string tests") { json j = json("Hello World"); SECTION("is_string()") { json v(json_pointer_arg, &j); REQUIRE(v.is_string()); REQUIRE(v.is_string_view()); CHECK(v.as() == j.as()); } } TEST_CASE("json_reference byte_string tests") { std::string data = "abcdefghijk"; json j(byte_string_arg, data); SECTION("is_byte_string()") { json v(json_pointer_arg, &j); REQUIRE(v.is_byte_string()); REQUIRE(v.is_byte_string_view()); } } TEST_CASE("json_reference bool tests") { json tru(true); json fal(false); SECTION("true") { json v(json_pointer_arg, &tru); REQUIRE(v.is_bool()); CHECK(v.as_bool()); } SECTION("false") { json v(json_pointer_arg, &fal); REQUIRE(v.is_bool()); CHECK_FALSE(v.as_bool()); } } TEST_CASE("json_reference null tests") { json null(jsoncons::null_arg); SECTION("null") { json v(json_pointer_arg, &null); REQUIRE(v.is_null()); } } TEST_CASE("json_reference int64 tests") { json j(-100); SECTION("is_int64()") { json v(json_pointer_arg, &j); REQUIRE(v.is_int64()); CHECK(v.as() == -100); } } TEST_CASE("json_reference uint64 tests") { json j(100); SECTION("is_uint64()") { json v(json_pointer_arg, &j); REQUIRE(v.is_uint64()); CHECK(v.as() == 100); } } TEST_CASE("json_reference half tests") { json j(half_arg, 100); SECTION("is_half()") { json v(json_pointer_arg, &j); REQUIRE(v.is_half()); CHECK(v.as() == 100); } } TEST_CASE("json_reference double tests") { json j(123.456); SECTION("is_double()") { json v(json_pointer_arg, &j); REQUIRE(v.is_double()); CHECK(v.as_double() == 123.456); } } jsoncons-1.3.2/test/corelib/src/json_push_back_tests.cpp000066400000000000000000000023701477700171100234630ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("json array deeply nested tests") { SECTION("test 1") { json doc(json_array_arg); json* ref = &doc; for (std::size_t j = 0; j < 10000; ++j) { json val(json_array_arg, semantic_tag::none); ref->push_back(val); ref = &ref->at(0); } } } TEST_CASE("json_object deeply nested tests") { SECTION("test 1") { json doc(json_object_arg); json* ref = &doc; for (std::size_t j = 0; j < 10000; ++j) { json val(json_object_arg, semantic_tag::none); ref->try_emplace("0",val); ref = &ref->at(0); } } SECTION("test 2") { ojson doc(json_object_arg); ojson* ref = &doc; for (std::size_t j = 0; j < 10000; ++j) { ojson val(json_object_arg, semantic_tag::none); ref->try_emplace("0",val); ref = &ref->at(0); } } } jsoncons-1.3.2/test/corelib/src/json_reader_exception_tests.cpp000066400000000000000000000152631477700171100250510ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("json_reader exception tests") { SECTION("filename invalid") { std::string in_file = "./corelib/input/json-exception--1.json"; std::ifstream is(in_file, std::ios::binary); json_decoder decoder; json_stream_reader reader(is,decoder); REQUIRE_THROWS(reader.read_next()); CHECK(false == decoder.is_valid()); } SECTION("test_exception_left_brace") { std::string in_file = "./corelib/input/json-exception-1.json"; std::ifstream is(in_file); REQUIRE(is); json_decoder decoder; JSONCONS_TRY { json_stream_reader reader(is,decoder); reader.read_next(); } JSONCONS_CATCH (const ser_error& e) { CHECK(e.code() == json_errc::expected_comma_or_rbracket); CHECK(14 == e.line()); CHECK(30 == e.column()); } CHECK(false == decoder.is_valid()); } SECTION("test_exception_rbrace") { std::string in_file = "./corelib/input/json-exception-2.json"; std::ifstream is(in_file); REQUIRE(is); json_decoder decoder; JSONCONS_TRY { json_stream_reader reader(is,decoder); reader.read_next(); CHECK(false); } JSONCONS_CATCH (const ser_error& e) { //std::cout << e.what() << '\n'; CHECK(e.code() == json_errc::expected_comma_or_rbrace); CHECK(17 == e.line()); CHECK(6 == e.column()); } CHECK(false == decoder.is_valid()); } SECTION("test_exception_array_eof") { std::istringstream is("[100"); json_decoder decoder; JSONCONS_TRY { json_stream_reader reader(is,decoder); reader.read_next(); CHECK(false); } JSONCONS_CATCH (const ser_error& e) { CHECK(e.code() == json_errc::unexpected_eof); CHECK(1 == e.line()); CHECK(5 == e.column()); } CHECK(false == decoder.is_valid()); } SECTION("test_exception_unicode_eof") { std::istringstream is("[\"\\u"); json_decoder decoder; JSONCONS_TRY { json_stream_reader reader(is,decoder); reader.read_next(); CHECK(false); } JSONCONS_CATCH (const ser_error& e) { //std::cout << e.what() << '\n'; CHECK(e.code() == json_errc::unexpected_eof); CHECK(1 == e.line()); CHECK(5 == e.column()); } CHECK(false == decoder.is_valid()); } SECTION("test_exception_tru_eof") { std::istringstream is("[tru"); json_decoder decoder; JSONCONS_TRY { json_stream_reader reader(is,decoder); reader.read_next(); CHECK(false); } JSONCONS_CATCH (const ser_error& e) { //std::cout << e.what() << '\n'; CHECK(e.code() == json_errc::unexpected_eof); CHECK(1 == e.line()); CHECK(5 == e.column()); } CHECK(false == decoder.is_valid()); } SECTION("test_exception_fals_eof") { std::istringstream is("[fals"); json_decoder decoder; JSONCONS_TRY { json_stream_reader reader(is,decoder); reader.read_next(); CHECK(false); } JSONCONS_CATCH (const ser_error& e) { //std::cout << e.what() << '\n'; CHECK(e.code() == json_errc::unexpected_eof); CHECK(1 == e.line()); CHECK(6 == e.column()); } CHECK(false == decoder.is_valid()); } SECTION("test_exception_nul_eof") { std::istringstream is("[nul"); json_decoder decoder; JSONCONS_TRY { json_stream_reader reader(is,decoder); reader.read_next(); CHECK(false); } JSONCONS_CATCH (const ser_error& e) { //std::cout << e.what() << '\n'; CHECK(e.code() == json_errc::unexpected_eof); CHECK(1 == e.line()); CHECK(5 == e.column()); } CHECK(false == decoder.is_valid()); } SECTION("json_errc::unexpected_eof false true") { std::istringstream is("[true"); json_decoder decoder; JSONCONS_TRY { json_stream_reader reader(is,decoder); reader.read_next(); CHECK(false); } JSONCONS_CATCH (const ser_error& e) { CHECK(e.code() == json_errc::unexpected_eof); CHECK(1 == e.line()); CHECK(6 == e.column()); } CHECK(false == decoder.is_valid()); } SECTION("json_errc::unexpected_eof false") { std::istringstream is("[false"); json_decoder decoder; JSONCONS_TRY { json_stream_reader reader(is,decoder); reader.read_next(); CHECK(false); } JSONCONS_CATCH (const ser_error& e) { CHECK(e.code() == json_errc::unexpected_eof); CHECK(1 == e.line()); CHECK(7 == e.column()); } CHECK(false == decoder.is_valid()); } SECTION("json_errc::unexpected_eof null") { std::istringstream is("[null"); json_decoder decoder; JSONCONS_TRY { json_stream_reader reader(is,decoder); reader.read_next(); CHECK(false); } JSONCONS_CATCH (const ser_error& e) { CHECK(e.code() == json_errc::unexpected_eof); CHECK(1 == e.line()); CHECK(6 == e.column()); } CHECK(false == decoder.is_valid()); } SECTION("unexpected_eof quote char") { std::string input("{\"field1\":\n\"value}"); REQUIRE_THROWS_AS(json::parse(input),ser_error); JSONCONS_TRY { json::parse(input); CHECK(false); } JSONCONS_CATCH (const ser_error& e) { CHECK(json_errc::unexpected_eof == e.code()); CHECK(2 == e.line()); CHECK(8 == e.column()); } } } jsoncons-1.3.2/test/corelib/src/json_reader_tests.cpp000066400000000000000000000267221477700171100227750ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include using namespace jsoncons; TEST_CASE("test json_reader buffered read") { SECTION("string with split buffer") { std::string str(stream_source::default_max_buffer_size+10, '1'); for (std::size_t i = 0; i < str.size(); i+= 2) { str[i] = '0'; } std::string input; input.push_back('"'); input.append(str); input.push_back('"'); std::stringstream is(input); auto j = json::parse(is); REQUIRE(j.is_string()); CHECK(j.as() == str); } SECTION("number with split buffer") { std::string str(stream_source::default_max_buffer_size-7, 'a'); std::string neg_num("-123456789.123456789"); std::string input; input.push_back('['); input.push_back('"'); input.append(str); input.push_back('"'); input.push_back(','); input.append(neg_num); input.push_back(']'); std::stringstream is(input); auto j = json::parse(is); REQUIRE(j.is_array()); REQUIRE(2 == j.size()); CHECK(j[1].as() == -123456789.123456789); } SECTION("false with split buffer") { std::string str; str.push_back('['); str.push_back('"'); str.append(stream_source::default_max_buffer_size-8, 'a'); str.push_back('"'); str.push_back(','); str.append("false"); str.push_back(']'); std::stringstream is(str); auto j = json::parse(is); REQUIRE(j.is_array()); REQUIRE(2 == j.size()); CHECK_FALSE(j[1].as()); } SECTION("true with split buffer") { std::string str; str.push_back('['); str.push_back('"'); str.append(stream_source::default_max_buffer_size - 6, 'a'); str.push_back('"'); str.push_back(','); str.append("true"); str.push_back(']'); std::stringstream is(str); auto j = json::parse(is); REQUIRE(j.is_array()); REQUIRE(2 == j.size()); CHECK(j[1].as()); } SECTION("null with split buffer") { std::string str; str.push_back('['); str.push_back('"'); str.append(stream_source::default_max_buffer_size - 5, 'a'); str.push_back('"'); str.push_back(','); str.append("null"); str.push_back(']'); std::stringstream is(str); auto j = json::parse(is); REQUIRE(j.is_array()); REQUIRE(2 == j.size()); CHECK(j[1].is_null()); } } void test_json_reader_error(const std::string& text, const std::error_code& ec) { REQUIRE_THROWS(json::parse(text)); JSONCONS_TRY { json::parse(text); } JSONCONS_CATCH (const ser_error& e) { if (e.code() != ec) { std::cout << text << '\n'; std::cout << e.code().value() << " " << e.what() << '\n'; } CHECK(ec == e.code()); } } void test_json_reader_ec(const std::string& text, const std::error_code& expected) { std::error_code ec; std::istringstream is(text); json_decoder decoder; json_stream_reader reader(is,decoder); reader.read(ec); //std::cerr << text << '\n'; //std::cerr << ec.message() // << " at line " << reader.line() // << " and column " << reader.column() << '\n'; CHECK(ec); CHECK(expected == ec); } TEST_CASE("test_missing_separator") { std::string jtext = R"({"field1"{}})"; test_json_reader_error(jtext, jsoncons::json_errc::expected_colon); test_json_reader_ec(jtext, jsoncons::json_errc::expected_colon); } TEST_CASE("test_read_invalid_value") { std::string jtext = R"({"field1":ru})"; test_json_reader_error(jtext,jsoncons::json_errc::expected_value); test_json_reader_ec(jtext, jsoncons::json_errc::expected_value); } TEST_CASE("test_read_unexpected_end_of_file") { std::string jtext = R"({"field1":{})"; test_json_reader_error(jtext, jsoncons::json_errc::unexpected_eof); test_json_reader_ec(jtext, jsoncons::json_errc::unexpected_eof); } TEST_CASE("test_read_value_not_found") { std::string jtext = R"({"name":})"; test_json_reader_error(jtext, jsoncons::json_errc::expected_value); test_json_reader_ec(jtext, jsoncons::json_errc::expected_value); } TEST_CASE("test_read_escaped_characters") { std::string input("[\"\\n\\b\\f\\r\\t\"]"); std::string expected("\n\b\f\r\t"); json o = json::parse(input); CHECK(expected == o[0].as()); } TEST_CASE("test_read_expected_colon") { test_json_reader_error("{\"name\" 10}", jsoncons::json_errc::expected_colon); test_json_reader_error("{\"name\" true}", jsoncons::json_errc::expected_colon); test_json_reader_error("{\"name\" false}", jsoncons::json_errc::expected_colon); test_json_reader_error("{\"name\" null}", jsoncons::json_errc::expected_colon); test_json_reader_error("{\"name\" \"value\"}", jsoncons::json_errc::expected_colon); test_json_reader_error("{\"name\" {}}", jsoncons::json_errc::expected_colon); test_json_reader_error("{\"name\" []}", jsoncons::json_errc::expected_colon); } TEST_CASE("test_read_expected_key") { test_json_reader_error("{10}", jsoncons::json_errc::expected_key); test_json_reader_error("{true}", jsoncons::json_errc::expected_key); test_json_reader_error("{false}", jsoncons::json_errc::expected_key); test_json_reader_error("{null}", jsoncons::json_errc::expected_key); test_json_reader_error("{{}}", jsoncons::json_errc::expected_key); test_json_reader_error("{[]}", jsoncons::json_errc::expected_key); } TEST_CASE("test_read_expected_value") { test_json_reader_error("[tru]", jsoncons::json_errc::invalid_value); test_json_reader_error("[fa]", jsoncons::json_errc::invalid_value); test_json_reader_error("[n]", jsoncons::json_errc::invalid_value); } TEST_CASE("test_read_primitive_pass") { json val; CHECK_NOTHROW((val=json::parse("null"))); CHECK(val == json::null()); CHECK_NOTHROW((val=json::parse("false"))); CHECK(val == json(false)); CHECK_NOTHROW((val=json::parse("true"))); CHECK(val == json(true)); CHECK_NOTHROW((val=json::parse("10"))); CHECK(val == json(10)); CHECK_NOTHROW((val=json::parse("1.999"))); CHECK(val == json(1.999)); CHECK_NOTHROW((val=json::parse("\"string\""))); CHECK(val == json("string")); } TEST_CASE("test_read_empty_structures") { json val; CHECK_NOTHROW((val=json::parse("{}"))); CHECK_NOTHROW((val=json::parse("[]"))); CHECK_NOTHROW((val=json::parse("{\"object\":{},\"array\":[]}"))); CHECK_NOTHROW((val=json::parse("[[],{}]"))); } TEST_CASE("test_read_primitive_fail") { test_json_reader_error("null {}", jsoncons::json_errc::extra_character); test_json_reader_error("n ", jsoncons::json_errc::invalid_value); test_json_reader_error("nu ", jsoncons::json_errc::invalid_value); test_json_reader_error("nul ", jsoncons::json_errc::invalid_value); test_json_reader_error("false {}", jsoncons::json_errc::extra_character); test_json_reader_error("fals ", jsoncons::json_errc::invalid_value); test_json_reader_error("true []", jsoncons::json_errc::extra_character); test_json_reader_error("tru ", jsoncons::json_errc::invalid_value); test_json_reader_error("10 {}", jsoncons::json_errc::extra_character); test_json_reader_error("1a ", jsoncons::json_errc::invalid_number); test_json_reader_error("1.999 []", jsoncons::json_errc::extra_character); test_json_reader_error("1e0-1", jsoncons::json_errc::invalid_number); test_json_reader_error("\"string\"{}", jsoncons::json_errc::extra_character); test_json_reader_error("\"string\"[]", jsoncons::json_errc::extra_character); } TEST_CASE("test_read_multiple") { std::string in="{\"a\":1,\"b\":2,\"c\":3}{\"a\":4,\"b\":5,\"c\":6}"; //std::cout << in << '\n'; std::istringstream is(in); jsoncons::json_decoder decoder; json_stream_reader reader(is,decoder); REQUIRE_FALSE(reader.eof()); reader.read_next(); json val = decoder.get_result(); CHECK(1 == val["a"].as()); REQUIRE_FALSE(reader.eof()); reader.read_next(); json val2 = decoder.get_result(); CHECK(4 == val2["a"].as()); CHECK(reader.eof()); } TEST_CASE("json_reader read from string test") { std::string s = R"( { "store": { "book": [ { "category": "reference", "author": "Margaret Weis", "title": "Dragonlance Series", "price": 31.96 }, { "category": "reference", "author": "Brent Weeks", "title": "Night Angel Trilogy", "price": 14.70 } ] } } )"; json_decoder decoder; json_string_reader reader(s, decoder); reader.read(); json j = decoder.get_result(); REQUIRE(j.is_object()); REQUIRE(1 == j.size()); REQUIRE(j[0].is_object()); REQUIRE(1 == j[0].size()); REQUIRE(j[0][0].is_array()); REQUIRE(2 == j[0][0].size()); CHECK(j[0][0][0]["category"].as() == std::string("reference")); CHECK(j[0][0][1]["author"].as() == std::string("Brent Weeks")); } TEST_CASE("json_reader json lines") { SECTION("json lines") { std::string data = R"( ["Name", "Session", "Score", "Completed"] ["Gilbert", "2013", 24, true] ["Alexa", "2013", 29, true] ["May", "2012B", 14, false] ["Deloise", "2012A", 19, true] )"; std::stringstream is(data); json_decoder decoder; json_stream_reader reader(is, decoder); REQUIRE(!reader.eof()); reader.read_next(); CHECK(decoder.get_result() == json::parse(R"(["Name", "Session", "Score", "Completed"])")); REQUIRE(!reader.eof()); reader.read_next(); REQUIRE(!reader.eof()); reader.read_next(); REQUIRE(!reader.eof()); reader.read_next(); REQUIRE(!reader.eof()); reader.read_next(); CHECK(decoder.get_result() == json::parse(R"(["Deloise", "2012A", 19, true])")); CHECK(reader.eof()); } } #if defined(JSONCONS_HAS_STATEFUL_ALLOCATOR) && JSONCONS_HAS_STATEFUL_ALLOCATOR == 1 #include #include template using MyScopedAllocator = std::scoped_allocator_adaptor>; TEST_CASE("json_reader stateful allocator tests") { std::string input = R"( { "store": { "book": [ { "category": "reference", "author": "Margaret Weis", "title": "Dragonlance Series", "price": 31.96 }, { "category": "reference", "author": "Brent Weeks", "title": "Night Angel Trilogy", "price": 14.70 } ] } } )"; SECTION("stateful allocator") { using cust_json = basic_json>; MyScopedAllocator my_allocator{1}; json_decoder> decoder(my_allocator, my_allocator); basic_json_reader,MyScopedAllocator> reader(input, decoder, my_allocator); reader.read(); cust_json j = decoder.get_result(); //std::cout << pretty_print(j) << "\n"; } } #endif jsoncons-1.3.2/test/corelib/src/json_storage_tests.cpp000066400000000000000000000105371477700171100231740ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include using namespace jsoncons; TEST_CASE("test json_storage_kind") { SECTION("is_trivial_storage") { CHECK(is_trivial_storage(json_storage_kind::null)); CHECK(is_trivial_storage(json_storage_kind::boolean)); CHECK(is_trivial_storage(json_storage_kind::uint64)); CHECK(is_trivial_storage(json_storage_kind::int64)); CHECK(is_trivial_storage(json_storage_kind::half_float)); CHECK(is_trivial_storage(json_storage_kind::short_str)); CHECK(is_trivial_storage(json_storage_kind::empty_object)); CHECK(is_trivial_storage(json_storage_kind::json_const_reference)); CHECK(is_trivial_storage(json_storage_kind::json_reference)); CHECK_FALSE(is_trivial_storage(json_storage_kind::long_str)); CHECK_FALSE(is_trivial_storage(json_storage_kind::byte_str)); CHECK_FALSE(is_trivial_storage(json_storage_kind::array)); CHECK_FALSE(is_trivial_storage(json_storage_kind::object)); } SECTION("is_string_storage") { CHECK_FALSE(is_string_storage(json_storage_kind::null)); CHECK_FALSE(is_string_storage(json_storage_kind::boolean)); CHECK_FALSE(is_string_storage(json_storage_kind::uint64)); CHECK_FALSE(is_string_storage(json_storage_kind::int64)); CHECK_FALSE(is_string_storage(json_storage_kind::half_float)); CHECK(is_string_storage(json_storage_kind::short_str)); CHECK_FALSE(is_string_storage(json_storage_kind::empty_object)); CHECK_FALSE(is_string_storage(json_storage_kind::json_const_reference)); CHECK_FALSE(is_string_storage(json_storage_kind::json_reference)); CHECK(is_string_storage(json_storage_kind::long_str)); CHECK_FALSE(is_string_storage(json_storage_kind::byte_str)); CHECK_FALSE(is_string_storage(json_storage_kind::array)); CHECK_FALSE(is_string_storage(json_storage_kind::object)); } } TEST_CASE("test semantic_tag") { SECTION("is_number") { CHECK_FALSE(is_number_tag(semantic_tag::none)); CHECK_FALSE(is_number_tag(semantic_tag::undefined)); CHECK_FALSE(is_number_tag(semantic_tag::datetime)); CHECK_FALSE(is_number_tag(semantic_tag::epoch_second)); CHECK_FALSE(is_number_tag(semantic_tag::epoch_milli)); CHECK_FALSE(is_number_tag(semantic_tag::epoch_nano)); CHECK_FALSE(is_number_tag(semantic_tag::base64)); CHECK_FALSE(is_number_tag(semantic_tag::base64url)); CHECK_FALSE(is_number_tag(semantic_tag::uri)); CHECK_FALSE(is_number_tag(semantic_tag::clamped)); CHECK_FALSE(is_number_tag(semantic_tag::multi_dim_row_major)); CHECK_FALSE(is_number_tag(semantic_tag::multi_dim_column_major)); CHECK(is_number_tag(semantic_tag::bigint)); CHECK(is_number_tag(semantic_tag::bigdec)); CHECK(is_number_tag(semantic_tag::bigfloat)); CHECK(is_number_tag(semantic_tag::float128)); CHECK_FALSE(is_number_tag(semantic_tag::ext)); CHECK_FALSE(is_number_tag(semantic_tag::id)); CHECK_FALSE(is_number_tag(semantic_tag::regex)); CHECK_FALSE(is_number_tag(semantic_tag::code)); } } TEST_CASE("json storage tests") { json var1(int64_t(-100), semantic_tag::none); CHECK(json_storage_kind::int64 == var1.storage_kind()); json var2(uint64_t(100), semantic_tag::none); CHECK(json_storage_kind::uint64 == var2.storage_kind()); json var3("Small string", 12, semantic_tag::none); CHECK(json_storage_kind::short_str == var3.storage_kind()); json var4("Too long to fit in small string", 31, semantic_tag::none); CHECK(json_storage_kind::long_str == var4.storage_kind()); json var5(true, semantic_tag::none); CHECK(json_storage_kind::boolean == var5.storage_kind()); json var6(semantic_tag::none); CHECK(json_storage_kind::empty_object == var6.storage_kind()); json var7{ null_type(), semantic_tag::none }; CHECK(json_storage_kind::null == var7.storage_kind()); json var8{ json::object(json::allocator_type()), semantic_tag::none }; CHECK(json_storage_kind::object == var8.storage_kind()); json var9(123456789.9, semantic_tag::none); CHECK(json_storage_kind::float64 == var9.storage_kind()); } jsoncons-1.3.2/test/corelib/src/json_swap_tests.cpp000066400000000000000000000060361477700171100225010ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include using namespace jsoncons; void check_swap(const json& j1, const json& j2) { json j3 = j1; json j4 = j2; j3.swap(j4); CHECK(j1 == j4); CHECK(j2 == j3); } TEST_CASE("test_swap") { json j1 = json::null(); json j2 = false; json j3 = -2000; json j4 = 2000U; json j5 = 2000.1234; json j6 = "Small"; json j7 = "String too large for small string"; json j8 = json::parse("[1,2,3,4]"); json j9; json j10 = json(json_object_arg); j10["Name"] = "John Smith"; check_swap(j1,j1); check_swap(j1,j2); check_swap(j1,j3); check_swap(j1,j4); check_swap(j1,j5); check_swap(j1,j6); check_swap(j1,j7); check_swap(j1,j8); check_swap(j1,j9); check_swap(j1,j10); check_swap(j2,j1); check_swap(j2,j2); check_swap(j2,j3); check_swap(j2,j4); check_swap(j2,j5); check_swap(j2,j6); check_swap(j2,j7); check_swap(j2,j8); check_swap(j2,j9); check_swap(j2,j10); check_swap(j3,j1); check_swap(j3,j2); check_swap(j3,j3); check_swap(j3,j4); check_swap(j3,j5); check_swap(j3,j6); check_swap(j3,j7); check_swap(j3,j8); check_swap(j3,j9); check_swap(j3,j10); check_swap(j4,j1); check_swap(j4,j2); check_swap(j4,j3); check_swap(j4,j4); check_swap(j4,j5); check_swap(j4,j6); check_swap(j4,j7); check_swap(j4,j8); check_swap(j4,j9); check_swap(j4,j10); check_swap(j5,j1); check_swap(j5,j2); check_swap(j5,j3); check_swap(j5,j4); check_swap(j5,j5); check_swap(j5,j6); check_swap(j5,j7); check_swap(j5,j8); check_swap(j5,j9); check_swap(j5,j10); check_swap(j6,j1); check_swap(j6,j2); check_swap(j6,j3); check_swap(j6,j4); check_swap(j6,j5); check_swap(j6,j6); check_swap(j6,j7); check_swap(j6,j8); check_swap(j6,j9); check_swap(j6,j10); check_swap(j7,j1); check_swap(j7,j2); check_swap(j7,j3); check_swap(j7,j4); check_swap(j7,j5); check_swap(j7,j6); check_swap(j7,j7); check_swap(j7,j8); check_swap(j7,j9); check_swap(j7,j10); check_swap(j8,j1); check_swap(j8,j2); check_swap(j8,j3); check_swap(j8,j4); check_swap(j8,j5); check_swap(j8,j6); check_swap(j8,j7); check_swap(j8,j8); check_swap(j8,j9); check_swap(j8,j10); check_swap(j9,j1); check_swap(j9,j2); check_swap(j9,j3); check_swap(j9,j4); check_swap(j9,j5); check_swap(j9,j6); check_swap(j9,j7); check_swap(j9,j8); check_swap(j9,j9); check_swap(j9,j10); check_swap(j10,j1); check_swap(j10,j2); check_swap(j10,j3); check_swap(j10,j4); check_swap(j10,j5); check_swap(j10,j6); check_swap(j10,j7); check_swap(j10,j8); check_swap(j10,j9); check_swap(j10,j10); } jsoncons-1.3.2/test/corelib/src/json_traits_macro_functional_tests.cpp000066400000000000000000001263351477700171100264450ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include namespace { namespace ns { class Person_NCGN { std::string name_; jsoncons::optional socialSecurityNumber_; jsoncons::optional birthDate_; public: Person_NCGN(const std::string& name, const jsoncons::optional& socialSecurityNumber, const jsoncons::optional& birthDate = jsoncons::optional()) : name_(name), socialSecurityNumber_(socialSecurityNumber), birthDate_(birthDate) { } std::string getName() const { return name_; } jsoncons::optional getSocialSecurityNumber() const { return socialSecurityNumber_; } jsoncons::optional getBirthDate() const { return birthDate_; } }; class Person_ACGN { std::string name_; jsoncons::optional socialSecurityNumber_; public: Person_ACGN(const std::string& name, const jsoncons::optional& socialSecurityNumber) : name_(name), socialSecurityNumber_(socialSecurityNumber) { } std::string getName() const { return name_; } jsoncons::optional getSocialSecurityNumber() const { return socialSecurityNumber_; } }; class Employee_NMN { public: std::string name_; std::string surname_; Employee_NMN() = default; Employee_NMN(const std::string& name, const std::string& surname) : name_(name), surname_(surname) { } friend bool operator<(const Employee_NMN& lhs, const Employee_NMN& rhs) { if (lhs.surname_ < rhs.surname_) return true; return lhs.name_ < rhs.name_; } }; class Company_NMN { public: std::string name_; std::vector employeeIds_; jsoncons::optional rating_; Company_NMN() = default; Company_NMN(const std::string& name, const std::vector& employeeIds) : name_(name), employeeIds_(employeeIds), rating_() { } }; class Employee_AMN { public: std::string name_; std::string surname_; Employee_AMN() = default; Employee_AMN(const std::string& name, const std::string& surname) : name_(name), surname_(surname) { } friend bool operator<(const Employee_AMN& lhs, const Employee_AMN& rhs) { if (lhs.surname_ < rhs.surname_) return true; return lhs.name_ < rhs.name_; } }; class Company_AMN { public: std::string name_; std::vector employeeIds_; Company_AMN() = default; Company_AMN(const std::string& name, const std::vector& employeeIds) : name_(name), employeeIds_(employeeIds) { } }; class Employee_NGSN { std::string name_; std::string surname_; public: Employee_NGSN() = default; Employee_NGSN(const std::string& name, const std::string& surname) : name_(name), surname_(surname) { } std::string getName() const { return name_; } void setName(const std::string& name) { name_ = name; } std::string getSurname()const { return surname_; } void setSurname(const std::string& surname) { surname_ = surname; } friend bool operator<(const Employee_NGSN& lhs, const Employee_NGSN& rhs) { if (lhs.surname_ < rhs.surname_) return true; return lhs.name_ < rhs.name_; } }; class Company_NGSN { std::string name_; std::vector employeeIds_; jsoncons::optional rating_; public: Company_NGSN() = default; Company_NGSN(const std::string& name, const std::vector& employeeIds) : name_(name), employeeIds_(employeeIds), rating_() { } std::string getName() const { return name_; } void setName(const std::string& name) { name_ = name; } const std::vector getIds() const { return employeeIds_; } void setIds(const std::vector& employeeIds) { employeeIds_ = employeeIds; } const jsoncons::optional& getRating() const { return rating_; } void setRating(const jsoncons::optional& rating) { rating_ = rating; } }; class Employee_AGSN { std::string name_; std::string surname_; public: Employee_AGSN() = default; Employee_AGSN(const std::string& name, const std::string& surname) : name_(name), surname_(surname) { } std::string getName() const { return name_; } void setName(const std::string& name) { name_ = name; } std::string getSurname()const { return surname_; } void setSurname(const std::string& surname) { surname_ = surname; } friend bool operator<(const Employee_AGSN& lhs, const Employee_AGSN& rhs) { if (lhs.surname_ < rhs.surname_) return true; return lhs.name_ < rhs.name_; } }; class Company_AGSN { std::string name_; std::vector employeeIds_; public: Company_AGSN() = default; Company_AGSN(const std::string& name, const std::vector& employeeIds) : name_(name), employeeIds_(employeeIds) { } std::string getName() const { return name_; } void setName(const std::string& name) { name_ = name; } const std::vector getIds() const { return employeeIds_; } void setIds(const std::vector& employeeIds) { employeeIds_ = employeeIds; } }; class Employee_NCGN { std::string name_; std::string surname_; public: Employee_NCGN(const std::string& name, const std::string& surname) : name_(name), surname_(surname) { } std::string getName() const { return name_; } std::string getSurname()const { return surname_; } friend bool operator<(const Employee_NCGN& lhs, const Employee_NCGN& rhs) { if (lhs.surname_ < rhs.surname_) return true; return lhs.name_ < rhs.name_; } }; class Company_NCGN { std::string name_; std::vector employeeIds_; jsoncons::optional rating_; public: Company_NCGN(const std::string& name, const std::vector& employeeIds, const jsoncons::optional& rating = jsoncons::optional()) : name_(name), employeeIds_(employeeIds), rating_(rating) { } std::string getName() const { return name_; } const std::vector getIds() const { return employeeIds_; } const jsoncons::optional& getRating() const { return rating_; } }; class Employee_ACGN { std::string name_; std::string surname_; public: Employee_ACGN(const std::string& name, const std::string& surname) : name_(name), surname_(surname) { } std::string getName() const { return name_; } std::string getSurname() const { return surname_; } friend bool operator<(const Employee_ACGN& lhs, const Employee_ACGN& rhs) { if (lhs.surname_ < rhs.surname_) return true; return lhs.name_ < rhs.name_; } }; class Company_ACGN { std::string name_; std::vector employeeIds_; public: Company_ACGN(const std::string& name, const std::vector& employeeIds) : name_(name), employeeIds_(employeeIds) { } std::string getName() const { return name_; } const std::vector getIds() const { return employeeIds_; } }; template std::vector fromEmployeesToIds(const std::vector& employees) { static std::map employee_id_map = {{Employee("John", "Smith"), 1},{Employee("Jane", "Doe"), 2}}; std::vector ids; for (auto employee : employees) { ids.push_back(employee_id_map.at(employee)); } return ids; } template std::vector toEmployeesFromIds(const std::vector& ids) { static std::map id_employee_map = {{1, Employee("John", "Smith")},{2, Employee("Jane", "Doe")}}; std::vector employees; for (auto id : ids) { employees.push_back(id_employee_map.at(id)); } return employees; } class Shape_ACGN { public: virtual ~Shape_ACGN() = default; virtual double area() const = 0; }; class Rectangle_ACGN : public Shape_ACGN { double height_; double width_; public: Rectangle_ACGN(double height, double width) : height_(height), width_(width) { } double height() const { return height_; } double width() const { return width_; } double area() const override { return height_ * width_; } }; class Triangle_ACGN : public Shape_ACGN { double height_; double width_; public: Triangle_ACGN(double height, double width) : height_(height), width_(width) { } double height() const { return height_; } double width() const { return width_; } double area() const override { return (height_ * width_)/2.0; } const std::string& type() const { static const std::string type_ = "triangle"; return type_; } }; class Circle_ACGN : public Shape_ACGN { double radius_; public: Circle_ACGN(double radius) : radius_(radius) { } double radius() const { return radius_; } double area() const override { constexpr double pi = 3.14159265358979323846; return pi*radius_*radius_; } const std::string& type() const { static const std::string type_ = "circle"; return type_; } }; class Shape_AGSN { public: virtual ~Shape_AGSN() = default; virtual double area() const = 0; }; class Rectangle_AGSN : public Shape_AGSN { double height_; double width_; public: Rectangle_AGSN() : height_(0), width_(0) { } double getHeight() const { return height_; } void setHeight(double value) { height_ = value; } double getWidth() const { return width_; } void setWidth(double value) { width_ = value; } double area() const override { return height_ * width_; } }; class Triangle_AGSN : public Shape_AGSN { double height_; double width_; public: Triangle_AGSN() : height_(0), width_(0) { } double getHeight() const { return height_; } void setHeight(double value) { height_ = value; } double getWidth() const { return width_; } void setWidth(double value) { width_ = value; } double area() const override { return (height_ * width_)/2.0; } const std::string& getType() const { static const std::string type_ = "triangle"; return type_; } }; class Circle_AGSN : public Shape_AGSN { double radius_; public: Circle_AGSN() : radius_(0) { } double getRadius() const { return radius_; } void setRadius(double value) { radius_ = value; } double area() const override { constexpr double pi = 3.14159265358979323846; return pi*radius_*radius_; } const std::string& getType() const { static const std::string type_ = "circle"; return type_; } }; class Shape_NGSN { public: virtual ~Shape_NGSN() = default; virtual double area() const = 0; }; class Rectangle_NGSN : public Shape_NGSN { double height_; double width_; public: Rectangle_NGSN() : height_(0), width_(0) { } double getHeight() const { return height_; } void setHeight(double value) { height_ = value; } double getWidth() const { return width_; } void setWidth(double value) { width_ = value; } double area() const override { return height_ * width_; } }; class Triangle_NGSN : public Shape_NGSN { double height_; double width_; public: Triangle_NGSN() : height_(0), width_(0) { } double getHeight() const { return height_; } void setHeight(double value) { height_ = value; } double getWidth() const { return width_; } void setWidth(double value) { width_ = value; } double area() const override { return (height_ * width_)/2.0; } const std::string& getType() const { static const std::string type_ = "triangle"; return type_; } }; class Circle_NGSN : public Shape_NGSN { double radius_; public: Circle_NGSN() : radius_(0) { } double getRadius() const { return radius_; } void setRadius(double value) { radius_ = value; } double area() const override { constexpr double pi = 3.14159265358979323846; return pi*radius_*radius_; } const std::string& getType() const { static const std::string type_ = "circle"; return type_; } }; class Shape_AMN { public: virtual ~Shape_AMN() = default; virtual double area() const = 0; }; class Rectangle_AMN : public Shape_AMN { JSONCONS_TYPE_TRAITS_FRIEND double height_; double width_; public: Rectangle_AMN() : height_(0), width_(0) { } double area() const override { return height_ * width_; } }; class Triangle_AMN : public Shape_AMN { JSONCONS_TYPE_TRAITS_FRIEND static const std::string type_; double height_; double width_; public: Triangle_AMN() : height_(0), width_(0) { } double area() const override { return (height_ * width_)/2.0; } }; const std::string Triangle_AMN::type_ = "triangle"; class Circle_AMN : public Shape_AMN { JSONCONS_TYPE_TRAITS_FRIEND static const std::string type_; double radius_; public: Circle_AMN() : radius_(0) { } double radius() const { return radius_; } double area() const override { constexpr double pi = 3.14159265358979323846; return pi*radius_*radius_; } }; const std::string Circle_AMN::type_ = "circle"; class Shape_NMN { public: virtual ~Shape_NMN() = default; virtual double area() const = 0; }; class Rectangle_NMN : public Shape_NMN { JSONCONS_TYPE_TRAITS_FRIEND double height_; double width_; public: Rectangle_NMN() : height_(0), width_(0) { } double area() const override { return height_ * width_; } }; class Triangle_NMN : public Shape_NMN { JSONCONS_TYPE_TRAITS_FRIEND static const std::string type_; double height_; double width_; public: Triangle_NMN() : height_(0), width_(0) { } double area() const override { return (height_ * width_)/2.0; } }; const std::string Triangle_NMN::type_ = "triangle"; class Circle_NMN : public Shape_NMN { JSONCONS_TYPE_TRAITS_FRIEND static const std::string type_; double radius_; public: Circle_NMN() : radius_(0) { } double radius() const { return radius_; } double area() const override { constexpr double pi = 3.14159265358979323846; return pi*radius_*radius_; } }; const std::string Circle_NMN::type_ = "circle"; const auto rectangle_marker = [](double) noexcept {return "rectangle"; }; //const auto triangle_marker = [](double) noexcept {return "triangle";}; //const auto circle_marker = [](double) noexcept {return "circle";}; } // namespace } // ns JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Rectangle_ACGN, (height,"type",JSONCONS_RDONLY, [](const std::string& type) noexcept{return type == "rectangle";}, ns::rectangle_marker), (height, "height", JSONCONS_RDWR), (width, "width") ) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Triangle_ACGN, (type,"type", JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "triangle";}), (height, "height"), (width, "width") ) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Circle_ACGN, (type,"type", JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "circle";}), (radius, "radius") ) JSONCONS_POLYMORPHIC_TRAITS(ns::Shape_ACGN,ns::Rectangle_ACGN,ns::Triangle_ACGN,ns::Circle_ACGN) JSONCONS_ALL_GETTER_SETTER_NAME_TRAITS(ns::Rectangle_AGSN, (getHeight, ,"type",JSONCONS_RDONLY, [](const std::string& type) noexcept{return type == "rectangle";}, ns::rectangle_marker), (getHeight, setHeight, "height"), (getWidth, setWidth, "width") ) JSONCONS_ALL_GETTER_SETTER_NAME_TRAITS(ns::Triangle_AGSN, (getType,,"type", JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "triangle";}), (getHeight, setHeight, "height"), (getWidth, setWidth, "width") ) JSONCONS_ALL_GETTER_SETTER_NAME_TRAITS(ns::Circle_AGSN, (getType,,"type", JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "circle";}), (getRadius, setRadius, "radius") ) JSONCONS_POLYMORPHIC_TRAITS(ns::Shape_AGSN,ns::Rectangle_AGSN,ns::Triangle_AGSN,ns::Circle_AGSN) JSONCONS_N_GETTER_SETTER_NAME_TRAITS(ns::Rectangle_NGSN, 3, (getHeight, ,"type",JSONCONS_RDONLY, [](const std::string& type) noexcept{return type == "rectangle";}, ns::rectangle_marker), (getHeight, setHeight, "height"), (getWidth, setWidth, "width") ) JSONCONS_N_GETTER_SETTER_NAME_TRAITS(ns::Triangle_NGSN, 3, (getType,,"type", JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "triangle";}), (getHeight, setHeight, "height"), (getWidth, setWidth, "width") ) JSONCONS_N_GETTER_SETTER_NAME_TRAITS(ns::Circle_NGSN, 2, (getType,,"type", JSONCONS_RDONLY, [](const std::string& type) {return type == "circle";}), (getRadius, setRadius, "radius") ) JSONCONS_POLYMORPHIC_TRAITS(ns::Shape_NGSN,ns::Rectangle_NGSN,ns::Triangle_NGSN,ns::Circle_NGSN) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::Rectangle_AMN, (height_,"type",JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "rectangle"; }, ns::rectangle_marker), (height_, "height"), (width_, "width") ) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::Triangle_AMN, (type_,"type", JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "triangle";}), (height_, "height"), (width_, "width") ) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::Circle_AMN, (type_,"type", JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "circle";}), (radius_, "radius") ) JSONCONS_POLYMORPHIC_TRAITS(ns::Shape_AMN,ns::Rectangle_AMN,ns::Triangle_AMN,ns::Circle_AMN) JSONCONS_N_MEMBER_NAME_TRAITS(ns::Rectangle_NMN, 3, (height_,"type",JSONCONS_RDONLY, [](const std::string& type) noexcept{return type == "rectangle";}, ns::rectangle_marker), (height_, "height"), (width_, "width") ) JSONCONS_N_MEMBER_NAME_TRAITS(ns::Triangle_NMN, 3, (type_,"type", JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "triangle";}), (height_, "height"), (width_, "width") ) JSONCONS_N_MEMBER_NAME_TRAITS(ns::Circle_NMN, 2, (type_,"type", JSONCONS_RDONLY, [](const std::string& type) noexcept {return type == "circle";}), (radius_, "radius") ) JSONCONS_POLYMORPHIC_TRAITS(ns::Shape_NMN,ns::Rectangle_NMN,ns::Triangle_NMN,ns::Circle_NMN) JSONCONS_N_MEMBER_NAME_TRAITS(ns::Employee_NMN, 2, (name_, "employee_name"), (surname_, "employee_surname") ) JSONCONS_N_MEMBER_NAME_TRAITS(ns::Company_NMN, 2, (name_, "company"), (employeeIds_, "resources", JSONCONS_RDWR, jsoncons::always_true(), ns::toEmployeesFromIds, ns::fromEmployeesToIds), (rating_, "rating") ) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::Employee_AMN, (name_, "employee_name"), (surname_, "employee_surname") ) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::Company_AMN, (name_, "company"), (employeeIds_, "resources", JSONCONS_RDWR, jsoncons::always_true(), ns::toEmployeesFromIds, ns::fromEmployeesToIds) ) JSONCONS_N_GETTER_SETTER_NAME_TRAITS(ns::Employee_NGSN, 2, (getName, setName, "employee_name"), (getSurname, setSurname, "employee_surname") ) JSONCONS_N_GETTER_SETTER_NAME_TRAITS(ns::Company_NGSN, 2, (getName, setName, "company"), (getIds, setIds, "resources", JSONCONS_RDWR, jsoncons::always_true(), ns::toEmployeesFromIds, ns::fromEmployeesToIds), (getRating, setRating, "rating") ) JSONCONS_ALL_GETTER_SETTER_NAME_TRAITS(ns::Employee_AGSN, (getName, setName, "employee_name"), (getSurname, setSurname, "employee_surname") ) JSONCONS_ALL_GETTER_SETTER_NAME_TRAITS(ns::Company_AGSN, (getName, setName, "company"), (getIds, setIds, "resources", JSONCONS_RDWR, jsoncons::always_true(), ns::toEmployeesFromIds, ns::fromEmployeesToIds) ) JSONCONS_N_CTOR_GETTER_NAME_TRAITS(ns::Employee_NCGN, 2, (getName, "employee_name"), (getSurname, "employee_surname") ) JSONCONS_N_CTOR_GETTER_NAME_TRAITS(ns::Company_NCGN, 2, (getName, "company"), (getIds, "resources", JSONCONS_RDWR, jsoncons::always_true(), ns::toEmployeesFromIds, ns::fromEmployeesToIds), (getRating, "rating") ) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Employee_ACGN, (getName, "employee_name"), (getSurname, "employee_surname") ) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Company_ACGN, (getName, "company"), (getIds, "resources", JSONCONS_RDWR, jsoncons::always_true{}, ns::toEmployeesFromIds, ns::fromEmployeesToIds) ) JSONCONS_N_CTOR_GETTER_NAME_TRAITS(ns::Person_NCGN, 2, (getName, "name"), (getSocialSecurityNumber, "social_security_number", JSONCONS_RDWR, jsoncons::always_true{}, jsoncons::identity(), [] (const jsoncons::optional& unvalidated) { if (!unvalidated) { return unvalidated; } std::regex myRegex(("^(\\d{9})$")); if (!std::regex_match(*unvalidated, myRegex) ) { throw std::runtime_error("Invalid social security number"); } return jsoncons::optional(unvalidated); } ), (getBirthDate, "birth_date") ) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::Person_ACGN, (getName, "name"), (getSocialSecurityNumber, "social_security_number", JSONCONS_RDWR, [] (const jsoncons::optional& unvalidated) { if (!unvalidated) { return false; } std::regex myRegex("^(\\d{9})$"); return std::regex_match(*unvalidated, myRegex); }, jsoncons::identity(), [] (const jsoncons::optional& unvalidated) { if (!unvalidated) { return unvalidated; } std::regex myRegex(("^(\\d{9})$")); if (!std::regex_match(*unvalidated, myRegex) ) { return jsoncons::optional(); } return unvalidated; } ) ) using namespace jsoncons; TEST_CASE("JSONCONS_N_GETTER_SETTER_NAME_TRAITS transform tests") { SECTION("test 1") { std::vector ids = {1,2}; ns::Company_NGSN company("Example", ids); std::string output1; encode_json(company, output1); //std::cout << output1 << "\n\n"; auto company2 = decode_json(output1); std::string output2; encode_json(company, output2); CHECK(output2 == output1); auto j = decode_json(output2); CHECK(j.is()); CHECK(j.is()); } } TEST_CASE("JSONCONS_ALL_GETTER_SETTER_NAME_TRAITS transform tests") { SECTION("test 1") { std::vector ids = {1,2}; ns::Company_AGSN company("Example", ids); std::string output1; encode_json(company, output1); //std::cout << output1 << "\n\n"; auto company2 = decode_json(output1); std::string output2; encode_json(company, output2); CHECK(output2 == output1); auto j = decode_json(output2); CHECK(j.is()); CHECK(j.is()); } } TEST_CASE("JSONCONS_N_CTOR_GETTER_NAME_TRAITS transform tests") { SECTION("test 1") { std::vector employees = {ns::Employee_NCGN("John", "Smith"), ns::Employee_NCGN("Jane", "Doe")}; std::string output1; encode_json(employees, output1, indenting::indent); auto employees2 = decode_json>(output1); std::string output2; encode_json(employees2, output2, indenting::indent); CHECK(output2 == output1); auto j = decode_json(output2); CHECK(j.is>()); } SECTION("test 2") { std::vector ids = {1,2}; ns::Company_NCGN company("Example", ids); std::string output1; encode_json(company, output1); //std::cout << output1 << "\n\n"; auto company2 = decode_json(output1); std::string output2; encode_json(company, output2); CHECK(output2 == output1); auto j = decode_json(output2); CHECK(j.is()); CHECK(j.is()); } } TEST_CASE("JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS transform tests") { SECTION("test 1") { std::vector ids = {1,2}; ns::Company_ACGN company("Example", ids); std::string output1; encode_json(company, output1); //std::cout << output1 << "\n\n"; auto company2 = decode_json(output1); std::string output2; encode_json(company, output2); CHECK(output2 == output1); auto j = decode_json(output2); CHECK(j.is()); CHECK(j.is()); } } TEST_CASE("JSONCONS_N_MEMBER_NAME_TRAITS transform tests") { SECTION("test 1") { std::vector ids = {1,2}; ns::Company_NMN company("Example", ids); std::string output1; encode_json(company, output1); //std::cout << output1 << "\n\n"; auto company2 = decode_json(output1); std::string output2; encode_json(company, output2); CHECK(output2 == output1); auto j = decode_json(output2); CHECK(j.is()); CHECK(j.is()); } } TEST_CASE("JSONCONS_ALL_MEMBER_NAME_TRAITS transform tests") { SECTION("test 1") { std::vector ids = {1,2}; ns::Company_AMN company("Example", ids); std::string output1; encode_json(company, output1); //std::cout << output1 << "\n\n"; auto company2 = decode_json(output1); std::string output2; encode_json(company, output2); CHECK(output2 == output1); auto j = decode_json(output2); CHECK(j.is()); CHECK(j.is()); } } #if defined(JSONCONS_HAS_STD_REGEX) TEST_CASE("JSONCONS_N_CTOR_GETTER_NAME_TRAITS validation tests") { SECTION("test 1") { std::vector persons = {ns::Person_NCGN("John Smith", "123456789"), ns::Person_NCGN("Jane Doe", "234567890")}; std::string output1; encode_json(persons, output1, indenting::indent); auto persons2 = decode_json>(output1); std::string output2; encode_json(persons2, output2, indenting::indent); CHECK(output2 == output1); auto j = decode_json(output2); CHECK(j.is>()); } } TEST_CASE("JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS validation tests") { SECTION("success") { std::vector persons = {ns::Person_ACGN("John Smith", "123456789"), ns::Person_ACGN("Jane Doe", "123456789")}; std::string output1; encode_json(persons, output1, indenting::indent); auto persons2 = decode_json>(output1); std::string output2; encode_json(persons2, output2, indenting::indent); CHECK(output2 == output1); auto j = decode_json(output2); CHECK(j.is>()); } SECTION("failure") { std::vector persons1 = {ns::Person_ACGN("John Smith", "123456789"), ns::Person_ACGN("Jane Doe", "12345678")}; std::string output1; encode_json(persons1, output1, indenting::indent); CHECK_THROWS(decode_json>(output1)); } } #endif TEST_CASE("JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS polymorphic and variant tests") { std::string input = R"( [ {"type" : "rectangle", "width" : 2.0, "height" : 1.5 }, {"type" : "triangle", "width" : 3.0, "height" : 2.0 }, {"type" : "circle", "radius" : 1.0 } ] )"; SECTION("polymorphic test") { auto shapes = decode_json>>(input); REQUIRE(3 == shapes.size()); std::string output; encode_json(shapes, output, indenting::indent); auto j = decode_json(input); REQUIRE(j.is_array()); REQUIRE(3 == j.size()); CHECK(j[0].is()); CHECK_FALSE(j[0].is()); CHECK_FALSE(j[0].is()); CHECK(j[1].is()); CHECK_FALSE(j[1].is()); CHECK_FALSE(j[1].is()); CHECK(j[2].is()); CHECK_FALSE(j[2].is()); CHECK_FALSE(j[2].is()); auto j2 = decode_json(output); CHECK(j2 == j); } #if defined(JSONCONS_HAS_STD_VARIANT) SECTION("variant test") { using shapes_t = std::variant; auto shapes = decode_json>(input); REQUIRE(3 == shapes.size()); /*auto visitor = [](auto&& shape) { using T = std::decay_t; if constexpr (std::is_same_v) std::cout << "rectangle area: " << shape.area() << '\n'; else if constexpr (std::is_same_v) std::cout << "triangle area: " << shape.area() << '\n'; else if constexpr (std::is_same_v) std::cout << "circle area: " << shape.area() << '\n'; }; for (const auto& shape : shapes) { std::visit(visitor, shape); }*/ std::string output; encode_json(shapes, output, indenting::indent); //std::cout << output << "\n"; } #endif } TEST_CASE("JSONCONS_ALL_GETTER_SETTER_NAME_TRAITS polymorphic and variant tests") { std::string input = R"( [ {"type" : "rectangle", "width" : 2.0, "height" : 1.5 }, {"type" : "triangle", "width" : 3.0, "height" : 2.0 }, {"type" : "circle", "radius" : 1.0 } ] )"; SECTION("polymorphic test") { auto shapes = decode_json>>(input); REQUIRE(3 == shapes.size()); std::string output; encode_json(shapes, output, indenting::indent); auto j = decode_json(input); REQUIRE(j.is_array()); REQUIRE(3 == j.size()); CHECK(j[0].is()); CHECK_FALSE(j[0].is()); CHECK_FALSE(j[0].is()); CHECK(j[1].is()); CHECK_FALSE(j[1].is()); CHECK_FALSE(j[1].is()); CHECK(j[2].is()); CHECK_FALSE(j[2].is()); CHECK_FALSE(j[2].is()); auto j2 = decode_json(output); CHECK(j2 == j); } #if defined(JSONCONS_HAS_STD_VARIANT) SECTION("variant test") { using shapes_t = std::variant; auto shapes = decode_json>(input); REQUIRE(3 == shapes.size()); /*auto visitor = [](auto&& shape) { using T = std::decay_t; if constexpr (std::is_same_v) std::cout << "rectangle area: " << shape.area() << '\n'; else if constexpr (std::is_same_v) std::cout << "triangle area: " << shape.area() << '\n'; else if constexpr (std::is_same_v) std::cout << "circle area: " << shape.area() << '\n'; }; for (const auto& shape : shapes) { std::visit(visitor, shape); }*/ std::string output; encode_json(shapes, output, indenting::indent); //std::cout << output << "\n"; } #endif } TEST_CASE("JSONCONS_N_GETTER_SETTER_NAME_TRAITS polymorphic and variant tests") { std::string input = R"( [ {"type" : "rectangle", "width" : 2.0, "height" : 1.5 }, {"type" : "triangle", "width" : 3.0, "height" : 2.0 }, {"type" : "circle", "radius" : 1.0 } ] )"; SECTION("polymorphic test") { auto shapes = decode_json>>(input); REQUIRE(3 == shapes.size()); std::string output; encode_json(shapes, output, indenting::indent); auto j = decode_json(input); REQUIRE(j.is_array()); REQUIRE(3 == j.size()); CHECK(j[0].is()); CHECK_FALSE(j[0].is()); CHECK_FALSE(j[0].is()); CHECK(j[1].is()); CHECK_FALSE(j[1].is()); CHECK_FALSE(j[1].is()); CHECK(j[2].is()); CHECK_FALSE(j[2].is()); CHECK_FALSE(j[2].is()); auto j2 = decode_json(output); CHECK(j2 == j); } #if defined(JSONCONS_HAS_STD_VARIANT) SECTION("variant test") { using shapes_t = std::variant; auto shapes = decode_json>(input); REQUIRE(3 == shapes.size()); /*auto visitor = [](auto&& shape) { using T = std::decay_t; if constexpr (std::is_same_v) std::cout << "rectangle area: " << shape.area() << '\n'; else if constexpr (std::is_same_v) std::cout << "triangle area: " << shape.area() << '\n'; else if constexpr (std::is_same_v) std::cout << "circle area: " << shape.area() << '\n'; }; for (const auto& shape : shapes) { std::visit(visitor, shape); }*/ std::string output; encode_json(shapes, output, indenting::indent); //std::cout << output << "\n"; } #endif } TEST_CASE("JSONCONS_ALL_MEMBER_NAME_TRAITS polymorphic and variant tests") { std::string input = R"( [ {"type" : "rectangle", "width" : 2.0, "height" : 1.5 }, {"type" : "triangle", "width" : 3.0, "height" : 2.0 }, {"type" : "circle", "radius" : 1.0 } ] )"; SECTION("polymorphic test") { auto shapes = decode_json>>(input); REQUIRE(3 == shapes.size()); std::string output; encode_json(shapes, output, indenting::indent); auto j = decode_json(input); REQUIRE(j.is_array()); REQUIRE(3 == j.size()); CHECK(j[0].is()); CHECK_FALSE(j[0].is()); CHECK_FALSE(j[0].is()); CHECK(j[1].is()); CHECK_FALSE(j[1].is()); CHECK_FALSE(j[1].is()); CHECK(j[2].is()); CHECK_FALSE(j[2].is()); CHECK_FALSE(j[2].is()); auto j2 = decode_json(output); CHECK(j2 == j); } #if defined(JSONCONS_HAS_STD_VARIANT) SECTION("variant test") { using shapes_t = std::variant; auto shapes = decode_json>(input); REQUIRE(3 == shapes.size()); /*auto visitor = [](auto&& shape) { using T = std::decay_t; if constexpr (std::is_same_v) std::cout << "rectangle area: " << shape.area() << '\n'; else if constexpr (std::is_same_v) std::cout << "triangle area: " << shape.area() << '\n'; else if constexpr (std::is_same_v) std::cout << "circle area: " << shape.area() << '\n'; }; for (const auto& shape : shapes) { std::visit(visitor, shape); }*/ std::string output; encode_json(shapes, output, indenting::indent); //std::cout << output << "\n"; } #endif } TEST_CASE("JSONCONS_N_MEMBER_NAME_TRAITS polymorphic and variant tests") { std::string input = R"( [ {"type" : "rectangle", "width" : 2.0, "height" : 1.5 }, {"type" : "triangle", "width" : 3.0, "height" : 2.0 }, {"type" : "circle", "radius" : 1.0 } ] )"; SECTION("polymorphic test") { auto shapes = decode_json>>(input); REQUIRE(3 == shapes.size()); std::string output; encode_json(shapes, output, indenting::indent); auto j = decode_json(input); REQUIRE(j.is_array()); REQUIRE(3 == j.size()); CHECK(j[0].is()); CHECK_FALSE(j[0].is()); CHECK_FALSE(j[0].is()); CHECK(j[1].is()); CHECK_FALSE(j[1].is()); CHECK_FALSE(j[1].is()); CHECK(j[2].is()); CHECK_FALSE(j[2].is()); CHECK_FALSE(j[2].is()); auto j2 = decode_json(output); CHECK(j2 == j); } #if defined(JSONCONS_HAS_STD_VARIANT) SECTION("variant test") { using shapes_t = std::variant; auto shapes = decode_json>(input); REQUIRE(3 == shapes.size()); /*auto visitor = [](auto&& shape) { using T = std::decay_t; if constexpr (std::is_same_v) std::cout << "rectangle area: " << shape.area() << '\n'; else if constexpr (std::is_same_v) std::cout << "triangle area: " << shape.area() << '\n'; else if constexpr (std::is_same_v) std::cout << "circle area: " << shape.area() << '\n'; }; for (const auto& shape : shapes) { std::visit(visitor, shape); }*/ std::string output; encode_json(shapes, output, indenting::indent); //std::cout << output << "\n"; } #endif } jsoncons-1.3.2/test/corelib/src/json_traits_macro_limit_tests.cpp000066400000000000000000000141171477700171100254130ustar00rootroot00000000000000// Copyright 2022 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include using namespace jsoncons; namespace { namespace ns { struct MyStruct { std::string s1; std::string s2; std::string s3; std::string s4; std::string s5; std::string s6; std::string s7; std::string s8; std::string s9; std::string s10; std::string s11; std::string s12; std::string s13; std::string s14; std::string s15; std::string s16; std::string s17; std::string s18; std::string s19; std::string s20; std::string s21; std::string s22; std::string s23; std::string s24; std::string s25; std::string s26; std::string s27; std::string s28; std::string s29; std::string s30; std::string s31; std::string s32; std::string s33; std::string s34; std::string s35; std::string s36; std::string s37; std::string s38; std::string s39; std::string s40; std::string s41; std::string s42; std::string s43; std::string s44; std::string s45; std::string s46; std::string s47; std::string s48; std::string s49; std::string s50; std::string s51; std::string s52; std::string s53; std::string s54; std::string s55; std::string s56; std::string s57; std::string s58; std::string s59; std::string s60; std::string s61; std::string s62; std::string s63; std::string s64; std::string s65; std::string s66; std::string s67; std::string s68; std::string s69; std::string s70; }; bool operator==(const MyStruct& lhs, const MyStruct& rhs) { return (lhs.s1 == rhs.s1 && lhs.s2 == rhs.s2 && lhs.s3 == rhs.s3 && lhs.s4 == rhs.s4 && lhs.s5 == rhs.s5 && lhs.s6 == rhs.s6 && lhs.s7 == rhs.s7 && lhs.s8 == rhs.s8 && lhs.s9 == rhs.s9 && lhs.s10 == rhs.s10 && lhs.s11 == rhs.s11 && lhs.s12 == rhs.s12 && lhs.s13 == rhs.s13 && lhs.s14 == rhs.s14 && lhs.s15 == rhs.s15 && lhs.s16 == rhs.s16 && lhs.s17 == rhs.s17 && lhs.s18 == rhs.s18 && lhs.s19 == rhs.s19 && lhs.s20 == rhs.s20 && lhs.s21 == rhs.s21 && lhs.s22 == rhs.s22 && lhs.s23 == rhs.s23 && lhs.s24 == rhs.s24 && lhs.s25 == rhs.s25 && lhs.s26 == rhs.s26 && lhs.s27 == rhs.s27 && lhs.s28 == rhs.s28 && lhs.s29 == rhs.s29 && lhs.s30 == rhs.s30 && lhs.s31 == rhs.s31 && lhs.s32 == rhs.s32 && lhs.s33 == rhs.s33 && lhs.s34 == rhs.s34 && lhs.s35 == rhs.s35 && lhs.s36 == rhs.s36 && lhs.s37 == rhs.s37 && lhs.s38 == rhs.s38 && lhs.s39 == rhs.s39 && lhs.s40 == rhs.s40 && lhs.s41 == rhs.s41 && lhs.s42 == rhs.s42 && lhs.s43 == rhs.s43 && lhs.s44 == rhs.s44 && lhs.s45 == rhs.s45 && lhs.s46 == rhs.s46 && lhs.s47 == rhs.s47 && lhs.s48 == rhs.s48 && lhs.s49 == rhs.s49 && lhs.s50 == rhs.s50 && lhs.s51 == rhs.s51 && lhs.s52 == rhs.s52 && lhs.s53 == rhs.s53 && lhs.s54 == rhs.s54 && lhs.s55 == rhs.s55 && lhs.s56 == rhs.s56 && lhs.s57 == rhs.s57 && lhs.s58 == rhs.s58 && lhs.s59 == rhs.s59 && lhs.s60 == rhs.s60 && lhs.s61 == rhs.s61 && lhs.s62 == rhs.s62 && lhs.s63 == rhs.s63 && lhs.s64 == rhs.s64 && lhs.s65 == rhs.s65 && lhs.s66 == rhs.s66 && lhs.s67 == rhs.s67 && lhs.s68 == rhs.s68 && lhs.s69 == rhs.s69 && lhs.s70 == rhs.s70); } } // namespace ns } // namespace JSONCONS_ALL_MEMBER_TRAITS(ns::MyStruct, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31, s32, s33, s34, s35, s36, s37, s38, s39, s40, s41, s42, s43, s44, s45, s46, s47, s48, s49, s50, s51, s52, s53, s54, s55, s56, s57, s58, s59, s60, s61, s62, s63, s64, s65, s66, s67, s68, s69, s70) TEST_CASE("json traits limits tests") { ns::MyStruct val = {"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","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","52","53","54","55","56","57","58","59","60", "61","62","63","64","65","66","67","68","69","70"}; SECTION("test1") { std::string buf; jsoncons::encode_json(val,buf); ns::MyStruct val2 = jsoncons::decode_json(buf); CHECK(val == val2); } } jsoncons-1.3.2/test/corelib/src/json_traits_macro_tests.cpp000066400000000000000000001064241477700171100242200ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include using namespace jsoncons; namespace { namespace ns { template struct TemplatedStruct { T1 aT1; T2 aT2; }; template struct MyStruct { T1 typeContent; std::string someString; }; template struct MyStruct2 { T1 typeContent; std::string someString; }; template struct MyStruct3 { T1 typeContent_; std::string someString_; public: MyStruct3(T1 typeContent, const std::string& someString) : typeContent_(typeContent), someString_(someString) { } const T1& typeContent() const {return typeContent_;} const std::string& someString() const {return someString_;} }; struct book1a { std::string author; std::string title; double price; }; struct book1b { std::string author; std::string title; double price; std::string isbn; }; struct book1c { std::string author; std::string title; double price; jsoncons::optional isbn; }; class book2a { std::string author_; std::string title_; double price_; public: book2a(const std::string& author, const std::string& title, double price) : author_(author), title_(title), price_(price) { } book2a(const book2a&) = default; book2a(book2a&&) = default; book2a& operator=(const book2a&) = default; book2a& operator=(book2a&&) = default; const std::string& author() const { return author_; } const std::string& title() const { return title_; } double price() const { return price_; } }; class book2b { std::string author_; std::string title_; double price_; std::string isbn_; jsoncons::optional publisher_; public: book2b(const std::string& author, const std::string& title, double price, const std::string& isbn, const jsoncons::optional& publisher) : author_(author), title_(title), price_(price), isbn_(isbn), publisher_(publisher) { } book2b(const book2b&) = default; book2b(book2b&&) = default; book2b& operator=(const book2b&) = default; book2b& operator=(book2b&&) = default; const std::string& author() const { return author_; } const std::string& title() const { return title_; } double price() const { return price_; } const std::string& isbn() const { return isbn_; } const jsoncons::optional& publisher() const { return publisher_; } }; class book3a { std::string author_; std::string title_; double price_; public: book3a() : author_(), title_(), price_() { } book3a(const book3a&) = default; book3a(book3a&&) = default; book3a& operator=(const book3a&) = default; book3a& operator=(book3a&&) = default; const std::string& getAuthor() const { return author_; } void setAuthor(const std::string& value) { author_ = value; } const std::string& getTitle() const { return title_; } void setTitle(const std::string& value) { title_ = value; } double getPrice() const { return price_; } void setPrice(double value) { price_ = value; } }; class book3b { std::string author_; std::string title_; double price_; std::string isbn_; public: book3b() : author_(), title_(), price_(), isbn_() { } book3b(const book3b&) = default; book3b(book3b&&) = default; book3b& operator=(const book3b&) = default; book3b& operator=(book3b&&) = default; const std::string& getAuthor() const { return author_; } void setAuthor(const std::string& value) { author_ = value; } const std::string& getTitle() const { return title_; } void setTitle(const std::string& value) { title_ = value; } double getPrice() const { return price_; } void setPrice(double value) { price_ = value; } const std::string& getIsbn() const { return isbn_; } void setIsbn(const std::string& value) { isbn_ = value; } }; class book3c { std::string author_; std::string title_; double price_; jsoncons::optional isbn_; public: book3c() : author_(), title_(), price_(), isbn_() { } book3c(const book3c&) = default; book3c(book3c&&) = default; book3c& operator=(const book3c&) = default; book3c& operator=(book3c&&) = default; const std::string& getAuthor() const { return author_; } void setAuthor(const std::string& value) { author_ = value; } const std::string& getTitle() const { return title_; } void setTitle(const std::string& value) { title_ = value; } double getPrice() const { return price_; } void setPrice(double value) { price_ = value; } const jsoncons::optional& getIsbn() const { return isbn_; } void setIsbn(const jsoncons::optional& value) { isbn_ = value; } }; enum class float_format {scientific = 1,fixed = 2,hex = 4,general = fixed | scientific}; class Employee { std::string firstName_; std::string lastName_; public: Employee(const std::string& firstName, const std::string& lastName) : firstName_(firstName), lastName_(lastName) { } virtual ~Employee() noexcept = default; virtual double calculatePay() const = 0; const std::string& firstName() const {return firstName_;} const std::string& lastName() const {return lastName_;} }; class HourlyEmployee : public Employee { double wage_; unsigned hours_; public: HourlyEmployee(const std::string& firstName, const std::string& lastName, double wage, unsigned hours) : Employee(firstName, lastName), wage_(wage), hours_(hours) { } HourlyEmployee(const HourlyEmployee&) = default; HourlyEmployee(HourlyEmployee&&) = default; HourlyEmployee& operator=(const HourlyEmployee&) = default; HourlyEmployee& operator=(HourlyEmployee&&) = default; double wage() const {return wage_;} unsigned hours() const {return hours_;} double calculatePay() const override { return wage_*hours_; } }; class CommissionedEmployee : public Employee { double baseSalary_; double commission_; unsigned sales_; public: CommissionedEmployee(const std::string& firstName, const std::string& lastName, double baseSalary, double commission, unsigned sales) : Employee(firstName, lastName), baseSalary_(baseSalary), commission_(commission), sales_(sales) { } CommissionedEmployee(const CommissionedEmployee&) = default; CommissionedEmployee(CommissionedEmployee&&) = default; CommissionedEmployee& operator=(const CommissionedEmployee&) = default; CommissionedEmployee& operator=(CommissionedEmployee&&) = default; double baseSalary() const { return baseSalary_; } double commission() const { return commission_; } unsigned sales() const { return sales_; } double calculatePay() const override { return baseSalary_ + commission_*sales_; } }; enum class hiking_experience {beginner,intermediate,advanced}; struct hiking_reputon { std::string rater; hiking_experience assertion; std::string rated; double rating; friend bool operator==(const hiking_reputon& lhs, const hiking_reputon& rhs) { return lhs.rater == rhs.rater && lhs.assertion == rhs.assertion && lhs.rated == rhs.rated && lhs.rating == rhs.rating; } }; class hiking_reputation { std::string application; std::vector reputons; // Make json_type_traits specializations friends to give accesses to private members JSONCONS_TYPE_TRAITS_FRIEND hiking_reputation() { } public: hiking_reputation(const std::string& application, const std::vector& reputons) : application(application), reputons(reputons) {} friend bool operator==(const hiking_reputation& lhs, const hiking_reputation& rhs) { return (lhs.application == rhs.application) && (lhs.reputons == rhs.reputons); } }; struct smart_pointer_and_optional_test1 { std::shared_ptr field1; std::unique_ptr field2; jsoncons::optional field3; std::shared_ptr field4; std::unique_ptr field5; jsoncons::optional field6; std::shared_ptr field7; std::unique_ptr field8; jsoncons::optional field9; std::shared_ptr field10; std::unique_ptr field11; jsoncons::optional field12; }; } // namespace ns } // namespace JSONCONS_ENUM_TRAITS(ns::float_format, scientific, fixed, hex, general) JSONCONS_ALL_MEMBER_TRAITS(ns::book1a,author,title,price) JSONCONS_N_MEMBER_TRAITS(ns::book1b,3,author,title,price,isbn) JSONCONS_N_MEMBER_TRAITS(ns::book1c,3,author,title,price,isbn) JSONCONS_ALL_CTOR_GETTER_TRAITS(ns::book2a, author, title, price) JSONCONS_N_CTOR_GETTER_TRAITS(ns::book2b, 2, author, title, price, isbn, publisher) JSONCONS_TPL_ALL_MEMBER_TRAITS(1,ns::MyStruct,typeContent,someString) JSONCONS_TPL_ALL_MEMBER_TRAITS(1,ns::MyStruct2,typeContent,someString) JSONCONS_TPL_ALL_CTOR_GETTER_TRAITS(1,ns::MyStruct3,typeContent,someString) JSONCONS_TPL_ALL_MEMBER_TRAITS(2,ns::TemplatedStruct,aT1,aT2) JSONCONS_ALL_CTOR_GETTER_TRAITS(ns::HourlyEmployee, firstName, lastName, wage, hours) JSONCONS_ALL_CTOR_GETTER_TRAITS(ns::CommissionedEmployee, firstName, lastName, baseSalary, commission, sales) JSONCONS_POLYMORPHIC_TRAITS(ns::Employee, ns::HourlyEmployee, ns::CommissionedEmployee) JSONCONS_ALL_GETTER_SETTER_TRAITS(ns::book3a, get, set, Author, Title, Price) JSONCONS_N_GETTER_SETTER_TRAITS(ns::book3b, get, set, 2, Author, Title, Price, Isbn) JSONCONS_N_GETTER_SETTER_TRAITS(ns::book3c, get, set, 2, Author, Title, Price, Isbn) JSONCONS_ENUM_TRAITS(ns::hiking_experience, beginner, intermediate, advanced) JSONCONS_ALL_MEMBER_TRAITS(ns::hiking_reputon, rater, assertion, rated, rating) JSONCONS_ALL_MEMBER_TRAITS(ns::hiking_reputation, application, reputons) // Declare the traits, first 6 members mandatory, last 6 non-mandatory JSONCONS_N_MEMBER_TRAITS(ns::smart_pointer_and_optional_test1,6, field1,field2,field3,field4,field5,field6, field7,field8,field9,field10,field11,field12) void test_is_json_type_traits_declared(std::true_type) { } namespace { template struct MyAlloc { using value_type = T; using size_type = std::size_t; using propagate_on_container_move_assignment = std::true_type; #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 MyAlloc() = default; #endif MyAlloc(int) {} template< typename U > MyAlloc(const MyAlloc&) noexcept {} T* allocate(size_type n) { return static_cast(::operator new(n * sizeof(T))); } void deallocate(T* ptr, size_type) noexcept { ::operator delete(ptr); } bool operator==(const MyAlloc&) const { return true; } bool operator!=(const MyAlloc&) const { return false; } template struct rebind { using other = MyAlloc; }; using pointer = T*; using const_pointer = const T*; using reference = T&; using const_reference = const T&; using difference_type = std::ptrdiff_t; }; } // namespace TEST_CASE("JSONCONS_ALL_MEMBER_TRAITS tests") { std::string an_author = "Haruki Murakami"; std::string a_title = "Kafka on the Shore"; double a_price = 25.17; ns::book1a book{an_author, a_title, a_price}; CHECK(is_json_type_traits_declared::value); test_is_json_type_traits_declared(is_json_type_traits_declared()); SECTION("book1a") { std::string s; encode_json(book, s); json j = decode_json(s); REQUIRE(j.is() == true); REQUIRE(j.is() == true); // isbn is optional CHECK(j["author"].as() == an_author); CHECK(j["title"].as() == a_title); CHECK(j["price"].as() == Approx(a_price).epsilon(0.001)); json j2(book); CHECK(j == j2); ns::book1a val = j.as(); CHECK(val.author == book.author); CHECK(val.title == book.title); CHECK(val.price == Approx(book.price).epsilon(0.001)); } } TEST_CASE("JSONCONS_N_MEMBER_TRAITS with optional tests") { std::string an_author = "Haruki Murakami"; std::string a_title = "Kafka on the Shore"; double a_price = 25.17; std::string an_isbn = "1400079276"; SECTION("book1c no isbn") { ns::book1c book{an_author, a_title, a_price, jsoncons::optional{}}; CHECK(is_json_type_traits_declared::value); std::string s; encode_json(book, s); json j = decode_json(s); REQUIRE(j.is() == true); REQUIRE(j.is() == true); // isbn is optional CHECK(j["author"].as() == an_author); CHECK(j["title"].as() == a_title); CHECK(j["price"].as() == Approx(a_price).epsilon(0.001)); CHECK_FALSE(j.contains("isbn")); json j2(book); CHECK(j == j2); auto val = j.as(); CHECK(val.author == book.author); CHECK(val.title == book.title); CHECK(val.price == Approx(book.price).epsilon(0.001)); CHECK_FALSE(val.isbn.has_value()); } SECTION("book1c has isbn") { ns::book1c book{an_author, a_title, a_price, an_isbn}; CHECK(is_json_type_traits_declared::value); std::string s; encode_json(book, s); json j = decode_json(s); REQUIRE(j.is() == true); REQUIRE(j.is() == true); CHECK(j["author"].as() == an_author); CHECK(j["title"].as() == a_title); CHECK(j["price"].as() == Approx(a_price).epsilon(0.001)); REQUIRE(j.contains("isbn")); CHECK(j["isbn"].as() == an_isbn); json j2(book); CHECK(j == j2); auto val = j.as(); CHECK(val.author == book.author); CHECK(val.title == book.title); CHECK(val.price == Approx(book.price).epsilon(0.00001)); CHECK(val.isbn.has_value()); CHECK(val.isbn == an_isbn); } } TEST_CASE("JSONCONS_ALL_CTOR_GETTER_TRAITS tests") { std::string an_author = "Haruki Murakami"; std::string a_title = "Kafka on the Shore"; double a_price = 25.17; SECTION("is") { json j; j["author"] = an_author; j["title"] = a_title; j["price"] = a_price; bool val = j.is(); CHECK(val == true); } SECTION("to_json") { ns::book2a book(an_author,a_title,a_price); json j(book); CHECK(j["author"].as() == an_author); CHECK(j["title"].as() == a_title); CHECK(j["price"].as() == Approx(a_price).epsilon(0.001)); } SECTION("as") { json j; j["author"] = an_author; j["title"] = a_title; j["price"] = a_price; ns::book2a book = j.as(); CHECK(book.author() == an_author); CHECK(book.title() == a_title); CHECK(book.price() == Approx(a_price).epsilon(0.001)); } } TEST_CASE("JSONCONS_N_CTOR_GETTER_TRAITS tests") { std::string an_author = "Haruki Murakami"; std::string a_title = "Kafka on the Shore"; double a_price = 25.17; std::string an_isbn = "1400079276"; SECTION("is") { json j; j["author"] = an_author; j["title"] = a_title; CHECK(j.is() == true); CHECK(j.is() == false); // has author, title, but not price j["price"] = a_price; CHECK(j.is() == true); // has author, title, price } SECTION("to_json") { ns::book2b book(an_author,a_title,a_price,an_isbn,jsoncons::optional()); json j(book); CHECK(j["author"].as() == an_author); CHECK(j["title"].as() == a_title); CHECK(j["price"].as() == Approx(a_price).epsilon(0.001)); CHECK(j["isbn"].as() == an_isbn); } SECTION("as") { json j; j["author"] = an_author; j["title"] = a_title; j["price"] = a_price; ns::book2b book = j.as(); CHECK(book.author() == an_author); CHECK(book.title() == a_title); CHECK(book.price() == Approx(a_price).epsilon(0.001)); } SECTION("decode") { json j; j["author"] = an_author; j["title"] = a_title; std::string buffer; j.dump(buffer); auto book = decode_json(buffer); CHECK(book.author() == an_author); CHECK(book.title() == a_title); CHECK(book.price() == double()); CHECK(book.isbn() == std::string()); } SECTION("encode_json") { ns::book2b book(an_author, a_title, a_price, an_isbn, jsoncons::optional()); std::string buffer; encode_json(book, buffer, indenting::indent); json j = json::parse(buffer); CHECK(j["author"].as() == an_author); CHECK(j["title"].as() == a_title); CHECK(j["price"].as() == Approx(a_price).epsilon(0.001)); CHECK(j["isbn"].as() == an_isbn); CHECK_FALSE(j.contains("publisher")); } } TEST_CASE("JSONCONS_TPL_ALL_MEMBER_TRAITS tests") { SECTION("MyStruct>") { typedef ns::MyStruct> value_type; value_type val; val.typeContent = std::make_pair(1,2); val.someString = "A string"; std::string s; encode_json(val, s, indenting::indent); auto val2 = decode_json(s); CHECK(val2.typeContent.first == val.typeContent.first); CHECK(val2.typeContent.second == val.typeContent.second); CHECK(val2.someString == val.someString); //std::cout << val.typeContent.first << ", " << val.typeContent.second << ", " << val.someString << "\n"; } SECTION("TemplatedStruct") { using value_type = ns::TemplatedStruct; value_type val; val.aT1 = 1; val.aT2 = 2; std::string s; encode_json(val, s, indenting::indent); auto val2 = decode_json(s); CHECK(val2.aT1 == val.aT1); CHECK(val2.aT2 == val.aT2); //std::cout << val.typeContent.first << ", " << val.typeContent.second << ", " << val.someString << "\n"; } SECTION("TemplatedStruct") { using value_type = ns::TemplatedStruct; value_type val; val.aT1 = 1; val.aT2 = L"sss"; std::wstring s; encode_json(val, s, indenting::indent); auto val2 = decode_json(s); CHECK(val2.aT1 == val.aT1); CHECK(val2.aT2 == val.aT2); //std::cout << val.typeContent.first << ", " << val.typeContent.second << ", " << val.someString << "\n"; } } TEST_CASE("JSONCONS_TPL_ALL_CTOR_GETTER_TRAITS tests") { SECTION("MyStruct>") { typedef ns::MyStruct3> value_type; value_type val(std::make_pair(1,2), "A string"); std::string s; encode_json(val, s, indenting::indent); auto val2 = decode_json(s); CHECK(val2.typeContent().first == val.typeContent().first); CHECK(val2.typeContent().second == val.typeContent().second); CHECK(val2.someString() == val.someString()); //std::cout << val.typeContent.first << ", " << val.typeContent.second << ", " << val.someString << "\n"; } } TEST_CASE("JSONCONS_ENUM_TRAITS tests") { SECTION("float_format default") { ns::float_format val{ns::float_format::hex}; std::string s; encode_json(val,s); auto val2 = decode_json(s); CHECK(val2 == val); } SECTION("float_format hex") { ns::float_format val{ns::float_format()}; std::string s; encode_json(val,s); auto val2 = decode_json(s); CHECK(val2 == val); } SECTION("float_format default L") { ns::float_format val{ns::float_format::hex}; std::wstring s; encode_json(val,s); auto val2 = decode_json(s); CHECK(val2 == val); } SECTION("float_format hex L") { ns::float_format val{ns::float_format::hex}; std::wstring s; encode_json(val,s); auto val2 = decode_json(s); CHECK(val2 == val); } } TEST_CASE("JSONCONS_POLYMORPHIC_TRAITS tests") { std::string input = R"( [ { "firstName": "John", "hours": 1000, "lastName": "Smith", "wage": 40.0 }, { "baseSalary": 30000.0, "commission": 0.25, "firstName": "Jane", "lastName": "Doe", "sales": 1000 } ] )"; const std::string firstName0 = "John"; const std::string lastName0 = "Smith"; const double pay0 = 40000; const std::string firstName1 = "Jane"; const std::string lastName1 = "Doe"; const double pay1 = 30250; SECTION("decode vector of shared_ptr test") { auto v = jsoncons::decode_json>>(input); REQUIRE(2 == v.size()); CHECK(v[0]->firstName() == firstName0); CHECK(v[0]->lastName() == lastName0); CHECK(v[0]->calculatePay() == pay0); CHECK(v[1]->firstName() == firstName1); CHECK(v[1]->lastName() == lastName1); CHECK(v[1]->calculatePay() == pay1); } SECTION("decode vector of unique_ptr test") { auto v = jsoncons::decode_json>>(input); REQUIRE(2 == v.size()); CHECK(v[0]->firstName() == firstName0); CHECK(v[0]->lastName() == lastName0); CHECK(v[0]->calculatePay() == pay0); CHECK(v[1]->firstName() == firstName1); CHECK(v[1]->lastName() == lastName1); CHECK(v[1]->calculatePay() == pay1); } SECTION("encode vector of shared_ptr test") { std::vector> v; v.push_back(std::make_shared("John", "Smith", 40.0, 1000)); v.push_back(std::make_shared("Jane", "Doe", 30000, 0.25, 1000)); jsoncons::json j(v); json expected = json::parse(input); CHECK(expected == j); } SECTION("encode vector of unique_ptr test") { std::vector> v; v.emplace_back(new ns::HourlyEmployee("John", "Smith", 40.0, 1000)); v.emplace_back(new ns::CommissionedEmployee("Jane", "Doe", 30000, 0.25, 1000)); jsoncons::json j(v); json expected = json::parse(input); CHECK(expected == j); } } TEST_CASE("JSONCONS_N_GETTER_SETTER_TRAITS tests") { std::string an_author = "Haruki Murakami"; std::string a_title = "Kafka on the Shore"; double a_price = 25.17; SECTION("is") { json j; j["Author"] = an_author; j["Title"] = a_title; j["Price"] = a_price; bool val = j.is(); CHECK(val == true); } SECTION("to_json") { ns::book3a book; book.setAuthor(an_author); book.setTitle(a_title); book.setPrice(a_price); json j(book); CHECK(j["Author"].as() == an_author); CHECK(j["Title"].as() == a_title); CHECK(j["Price"].as() == Approx(a_price).epsilon(0.001)); } SECTION("as") { json j; j["Author"] = an_author; j["Title"] = a_title; j["Price"] = a_price; ns::book3a book = j.as(); CHECK(book.getAuthor() == an_author); CHECK(book.getTitle() == a_title); CHECK(book.getPrice() == Approx(a_price).epsilon(0.001)); } SECTION("decode") { json j; j["author"] = an_author; j["title"] = a_title; j["price"] = a_price; std::string buffer; j.dump(buffer); auto book = decode_json(buffer); CHECK(book.author() == an_author); CHECK(book.title() == a_title); CHECK(book.price() == a_price); } } TEST_CASE("JSONCONS_ALL_GETTER_SETTER_TRAITS tests") { std::string an_author = "Haruki Murakami"; std::string a_title = "Kafka on the Shore"; double a_price = 25.17; std::string an_isbn = "1400079276"; SECTION("is") { json j; j["Author"] = an_author; j["Title"] = a_title; CHECK(j.is() == true); CHECK(j.is() == false); j["Price"] = a_price; CHECK(j.is() == true); CHECK(j.is() == true); } SECTION("to_json") { ns::book3b book; book.setAuthor(an_author); book.setTitle(a_title); book.setPrice(a_price); book.setIsbn(an_isbn); json j(book); CHECK(j["Author"].as() == an_author); CHECK(j["Title"].as() == a_title); CHECK(j["Price"].as() == Approx(a_price).epsilon(0.001)); CHECK(j["Isbn"].as() == an_isbn); } SECTION("as") { json j; j["Author"] = an_author; j["Title"] = a_title; j["Price"] = a_price; auto book = j.as(); CHECK(book.getAuthor() == an_author); CHECK(book.getTitle() == a_title); CHECK(book.getPrice() == Approx(a_price).epsilon(0.001)); } SECTION("decode") { json j; j["Author"] = an_author; j["Title"] = a_title; std::string buffer; j.dump(buffer); auto book = decode_json(buffer); CHECK(book.getAuthor() == an_author); CHECK(book.getTitle() == a_title); CHECK(book.getPrice() == double()); CHECK(book.getIsbn() == std::string()); } } TEST_CASE("JSONCONS_ALL_GETTER_SETTER_TRAITS optional tests") { std::string an_author = "Haruki Murakami"; std::string a_title = "Kafka on the Shore"; double a_price = 25.17; std::string an_isbn = "1400079276"; SECTION("book3c no isbn") { ns::book3c book; book.setAuthor(an_author); book.setTitle(a_title); book.setPrice(a_price); std::string input; encode_json(book,input); auto b1 = decode_json(input); CHECK(b1.getAuthor() == an_author); CHECK(b1.getTitle() == a_title); CHECK(b1.getPrice() == a_price); CHECK_FALSE(b1.getIsbn().has_value()); } SECTION("book3c has isbn") { ns::book3c book; book.setAuthor(an_author); book.setTitle(a_title); book.setPrice(a_price); book.setIsbn(an_isbn); std::string input; encode_json(book,input); auto b1 = decode_json(input); CHECK(b1.getAuthor() == an_author); CHECK(b1.getTitle() == a_title); CHECK(b1.getPrice() == Approx(a_price).epsilon(0.00001)); CHECK(b1.getIsbn() == an_isbn); } } TEST_CASE("hiking_reputation") { MyAlloc alloc1(1); ns::hiking_reputation val("hiking", { ns::hiking_reputon{"HikingAsylum",ns::hiking_experience::advanced,"Marilyn C",0.9} }); SECTION("1") { std::string s; encode_json(val, s); auto val2 = decode_json(s); CHECK(val2 == val); } SECTION("2") { std::string s; encode_json(val, s, indenting::indent); auto val2 = decode_json(s); CHECK(val2 == val); } SECTION("3") { std::string s; auto options = json_options{}; encode_json(val, s, options, indenting::indent); auto val2 = decode_json(s, options); CHECK(val2 == val); } SECTION("4") { std::string s; encode_json(val, s, indenting::indent); auto val2 = decode_json(temp_allocator_only(alloc1), s); CHECK(val2 == val); } SECTION("5") { std::string s; encode_json(val, s, indenting::indent); auto val2 = decode_json(temp_allocator_only(alloc1), s, json_options()); CHECK(val2 == val); } SECTION("6") { std::string s; auto options = json_options{}; encode_json(val, s, options, indenting::indent); auto val2 = decode_json(temp_allocator_only(alloc1), s, options); CHECK(val2 == val); } SECTION("os 1") { std::stringstream os; encode_json(val, os); auto val2 = decode_json(os); CHECK(val2 == val); } SECTION("os 2") { std::stringstream os; encode_json_pretty(val, os); auto val2 = decode_json(os); CHECK(val2 == val); } SECTION("os 3") { std::stringstream os; auto options = json_options{}; encode_json_pretty(val, os); auto val2 = decode_json(os, options); CHECK(val2 == val); } SECTION("os 4") { std::stringstream os; encode_json_pretty(val, os); auto val2 = decode_json(temp_allocator_only(alloc1), os, json_options()); CHECK(val2 == val); } SECTION("os 5") { std::stringstream os; encode_json_pretty(val, os); auto val2 = decode_json(temp_allocator_only(alloc1), os, json_options()); CHECK(val2 == val); } SECTION("os 6") { std::stringstream os; auto options = json_options{}; encode_json_pretty(val, os, options); auto val2 = decode_json(temp_allocator_only(alloc1), os, options); CHECK(val2 == val); } } TEST_CASE("JSONCONS_N_MEMBER_TRAITS pointer and optional test") { SECTION("test 1") { ns::smart_pointer_and_optional_test1 val; val.field1 = std::make_shared("Field 1"); val.field2 = jsoncons::make_unique("Field 2"); val.field3 = "Field 3"; val.field4 = std::shared_ptr(nullptr); val.field5 = std::unique_ptr(nullptr); val.field6 = jsoncons::optional(); val.field7 = std::make_shared("Field 7"); val.field8 = jsoncons::make_unique("Field 8"); val.field9 = "Field 9"; val.field10 = std::shared_ptr(nullptr); val.field11 = std::unique_ptr(nullptr); val.field12 = jsoncons::optional(); std::string buf; encode_json(val, buf, indenting::indent); //std::cout << buf << "\n"; json j = decode_json(buf); CHECK(j.contains("field1")); CHECK(j.contains("field2")); CHECK(j.contains("field3")); CHECK(j.contains("field4")); CHECK(j.contains("field5")); CHECK(j.contains("field6")); CHECK(j.contains("field7")); CHECK(j.contains("field8")); CHECK(j.contains("field9")); CHECK_FALSE(j.contains("field10")); CHECK_FALSE(j.contains("field11")); CHECK_FALSE(j.contains("field12")); CHECK(j["field1"].as() == std::string("Field 1")); CHECK(j["field2"].as() == std::string("Field 2")); CHECK(j["field3"].as() == std::string("Field 3")); CHECK(j["field4"].is_null()); CHECK(j["field5"].is_null()); CHECK(j["field6"].is_null()); CHECK(j["field7"].as() == std::string("Field 7")); CHECK(j["field8"].as() == std::string("Field 8")); CHECK(j["field9"].as() == std::string("Field 9")); auto other = decode_json(buf); CHECK(*other.field1 == *val.field1); CHECK(*other.field2 == *val.field2); CHECK(*other.field3 == *val.field3); CHECK_FALSE(other.field4); CHECK_FALSE(other.field5); CHECK_FALSE(other.field6); CHECK(*other.field7 == *val.field7); CHECK(*other.field8 == *val.field8); CHECK(*other.field9 == *val.field9); CHECK_FALSE(other.field10); CHECK_FALSE(other.field11); CHECK_FALSE(other.field12); } } jsoncons-1.3.2/test/corelib/src/json_traits_name_macro_tests.cpp000066400000000000000000000403631477700171100252170ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include using namespace jsoncons; namespace { namespace ns { struct book1a { std::string author; std::string title; double price; book1a() : author(""), title(""), price(0) { } book1a(const std::string& author, const std::string& title, double price) : author(author), title(title), price(price) { } }; struct book1b { std::string author; std::string title; double price; }; class book2a { std::string author_; std::string title_; double price_; public: book2a(const std::string& author, const std::string& title, double price) : author_(author), title_(title), price_(price) { } const std::string& author() const { return author_; } const std::string& title() const { return title_; } double price() const { return price_; } }; class book2b { std::string author_; std::string title_; double price_; std::string isbn_; jsoncons::optional publisher_; public: book2b(const std::string& author, const std::string& title, double price, const std::string& isbn, const jsoncons::optional& publisher) : author_(author), title_(title), price_(price), isbn_(isbn), publisher_(publisher) { } const std::string& author() const { return author_; } const std::string& title() const { return title_; } double price() const { return price_; } const std::string& isbn() const { return isbn_; } const jsoncons::optional& publisher() const { return publisher_; } }; class book3a { std::string author_; std::string title_; double price_; public: book3a() : price_(0) { } book3a(const std::string& author, const std::string& title, double price) : author_(author), title_(title), price_(price) { } const std::string& get_author() const { return author_; } const std::string& get_title() const { return title_; } double get_price() const { return price_; } void set_author(const std::string& author) { author_ = author; } void set_title(const std::string& title) { title_ = title; } void set_price(double price) { price_ = price; } }; class book3b { std::string author_; std::string title_; double price_; std::string isbn_; public: book3b() : author_(), title_(), price_(), isbn_() { } book3b(const std::string& author, const std::string& title, double price, const std::string& isbn) : author_(author), title_(title), price_(price), isbn_(isbn) { } const std::string& get_author() const { return author_; } void set_author(const std::string& value) { author_ = value; } const std::string& get_title() const { return title_; } void set_title(const std::string& value) { title_ = value; } double get_price() const { return price_; } void set_price(double value) { price_ = value; } const std::string& get_isbn() const { return isbn_; } void set_isbn(const std::string& value) { isbn_ = value; } }; class book5 { std::string author_; std::string title_; double price_; public: book5() : price_(0) { } book5(const std::string& author, const std::string& title, double price) : author_(author), title_(title), price_(price) { } const std::string& get_author() const { return author_; } const std::string& get_title() const { return title_; } double get_price() const { return price_; } void set_author(const std::string& author) { author_ = author; } void set_title(const std::string& title) { title_ = title; } void set_price(double price) { price_ = price; } }; template struct TemplatedStruct1 { T1 typeContent; std::string someString; }; template struct TemplatedStruct2 { T1 aT1; T2 aT2; }; enum class float_format {scientific = 1,fixed = 2,hex = 4,general = fixed | scientific}; struct Person1 { std::string name; std::string surname; }; } // ns } // namespace JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::book1a,(author,"Author"),(title,"Title"),(price,"Price")) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::book1b,(author,"Author"),(title,"Title"),(price,"Price")) JSONCONS_N_MEMBER_NAME_TRAITS(ns::Person1, 1, (name, "n"), (surname, "sn")) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::book2a, (author,"Author"),(title,"Title"),(price,"Price")) JSONCONS_N_CTOR_GETTER_NAME_TRAITS(ns::book2b, 2, (author,"Author"),(title,"Title"),(price,"Price"), (isbn, "Isbn"), (publisher, "Publisher")) JSONCONS_ALL_GETTER_SETTER_NAME_TRAITS(ns::book3a, (get_author,set_author,"Author"),(get_title,set_title,"Title"),(get_price,set_price,"Price")) JSONCONS_N_GETTER_SETTER_NAME_TRAITS(ns::book3b, 2, (get_author,set_author,"Author"),(get_title,set_title,"Title"),(get_price,set_price,"Price"),(get_isbn,set_isbn,"Isbn")) JSONCONS_TPL_ALL_MEMBER_NAME_TRAITS(1,ns::TemplatedStruct1,(typeContent,"type-content"),(someString,"some-string")) JSONCONS_TPL_ALL_MEMBER_NAME_TRAITS(2,ns::TemplatedStruct2,(aT1,"a-t1"),(aT2,"a-t2")) JSONCONS_ENUM_NAME_TRAITS(ns::float_format, (scientific,"Exponential"), (fixed,"Fixed"), (hex,"Hex"), (general,"General")) TEST_CASE("JSONCONS_ALL_MEMBER_NAME_TRAITS tests 1") { std::string an_author = "Haruki Murakami"; std::string a_title = "Kafka on the Shore"; double a_price = 25.17; ns::book1a book{an_author, a_title, a_price}; SECTION("book1a") { std::string s; encode_json(book, s); json j = decode_json(s); REQUIRE(j.is() == true); CHECK(j["Author"].as() == an_author); CHECK(j["Title"].as() == a_title); CHECK(j["Price"].as() == Approx(a_price).epsilon(0.001)); json j2(book); CHECK(j == j2); ns::book1a val = j.as(); CHECK(val.author == book.author); CHECK(val.title == book.title); CHECK(val.price == Approx(book.price).epsilon(0.001)); } } TEST_CASE("JSONCONS_ALL_MEMBER_NAME_TRAITS tests 2") { std::string an_author = "Haruki Murakami"; std::string a_title = "Kafka on the Shore"; double a_price = 25.17; ns::book1b book{an_author, a_title, a_price}; SECTION("book1b") { std::string s; encode_json(book, s); json j = decode_json(s); REQUIRE(j.is() == true); CHECK(j["Author"].as() == an_author); CHECK(j["Title"].as() == a_title); CHECK(j["Price"].as() == Approx(a_price).epsilon(0.001)); json j2(book); CHECK(j == j2); ns::book1b val = j.as(); CHECK(val.author == book.author); CHECK(val.title == book.title); CHECK(val.price == Approx(book.price).epsilon(0.001)); } } TEST_CASE("JSONCONS_N_MEMBER_NAME_TRAITS tests") { SECTION("decode") { std::string data = R"({"n":"Rod"})"; auto person = jsoncons::decode_json(data); CHECK(person.name == std::string("Rod")); CHECK(person.surname.empty()); std::string s; jsoncons::encode_json(person, s, indenting::indent); auto other = jsoncons::decode_json(s); CHECK(other.name == person.name); CHECK(other.surname == person.surname); } } TEST_CASE("JSONCONS_ALL_TPL_MEMBER_NAME_TRAITS tests 1") { SECTION("TemplatedStruct1>") { typedef ns::TemplatedStruct1> value_type; value_type val; val.typeContent = std::make_pair(1,2); val.someString = "A string"; std::string s; encode_json(val, s, indenting::indent); json j = decode_json(s); CHECK(j["some-string"].as() == val.someString); CHECK(1 == j["type-content"][0].as()); CHECK(2 == j["type-content"][1].as()); //std::cout << pretty_print(j) << "\n"; auto val2 = decode_json(s); CHECK(val2.typeContent.first == val.typeContent.first); CHECK(val2.typeContent.second == val.typeContent.second); CHECK(val2.someString == val.someString); //std::cout << val.typeContent.first << ", " << val.typeContent.second << ", " << val.someString << "\n"; } SECTION("TemplatedStruct2") { typedef ns::TemplatedStruct2 value_type; value_type val; val.aT1 = 1; val.aT2 = 2; std::string s; encode_json(val, s, indenting::indent); json j = decode_json(s); CHECK(1 == j["a-t1"].as()); CHECK(j["a-t2"].as() == 2.0); //std::cout << pretty_print(j) << "\n"; auto val2 = decode_json(s); CHECK(val2.aT1 == val.aT1); CHECK(val2.aT2 == val.aT2); //std::cout << val.typeContent.first << ", " << val.typeContent.second << ", " << val.someString << "\n"; } } TEST_CASE("JSONCONS_ENUM_NAME_TRAITS tests") { SECTION("float_format default") { ns::float_format val{ns::float_format::hex}; std::string s; encode_json(val,s); json j = decode_json(s); CHECK(j.as() == std::string("Hex")); auto val2 = decode_json(s); CHECK(val2 == val); } SECTION("float_format hex") { ns::float_format val{ns::float_format()}; std::string s; encode_json(val,s); json j = decode_json(s); CHECK(j.as().empty()); auto val2 = decode_json(s); CHECK(val2 == val); } } TEST_CASE("JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS tests") { std::string an_author = "Haruki Murakami"; std::string a_title = "Kafka on the Shore"; double a_price = 25.17; SECTION("is") { json j; j["Author"] = an_author; j["Title"] = a_title; j["Price"] = a_price; bool val = j.is(); CHECK(val); } SECTION("to_json") { ns::book2a book(an_author,a_title,a_price); json j(book); CHECK(j["Author"].as() == an_author); CHECK(j["Title"].as() == a_title); CHECK(j["Price"].as() == Approx(a_price).epsilon(0.001)); } SECTION("as") { json j; j["Author"] = an_author; j["Title"] = a_title; j["Price"] = a_price; ns::book2a book = j.as(); CHECK(book.author() == an_author); CHECK(book.title() == a_title); CHECK(book.price() == Approx(a_price).epsilon(0.001)); } } TEST_CASE("JSONCONS_N_CTOR_GETTER_NAME_TRAITS tests") { std::string an_author = "Haruki Murakami"; std::string a_title = "Kafka on the Shore"; double a_price = 25.17; std::string an_isbn = "1400079276"; SECTION("decode") { json j; j["Author"] = an_author; j["Title"] = a_title; CHECK(j.is()); CHECK_FALSE(j.is()); std::string buffer; j.dump(buffer); auto book = decode_json(buffer); CHECK(book.author() == an_author); CHECK(book.title() == a_title); CHECK(book.price() == double()); CHECK(book.isbn() == std::string()); } SECTION("encode_json") { ns::book2b book(an_author, a_title, a_price, an_isbn, jsoncons::optional()); std::string buffer; encode_json_pretty(book, buffer); //std::cout << buffer << "\n"; json j = json::parse(buffer); CHECK(j["Author"].as() == an_author); CHECK(j["Title"].as() == a_title); CHECK(j["Price"].as() == Approx(a_price).epsilon(0.001)); CHECK(j["Isbn"].as() == an_isbn); CHECK_FALSE(j.contains("Publisher")); } } TEST_CASE("JSONCONS_ALL_GETTER_SETTER_NAME_TRAITS tests") { std::string an_author = "Haruki Murakami"; std::string a_title = "Kafka on the Shore"; double a_price = 25.17; SECTION("is") { json j; j["Author"] = an_author; j["Title"] = a_title; j["Price"] = a_price; bool val = j.is(); CHECK(val); } SECTION("as") { json j; j["Author"] = an_author; j["Title"] = a_title; j["Price"] = a_price; ns::book3a book = j.as(); CHECK(book.get_author() == an_author); CHECK(book.get_title() == a_title); CHECK(book.get_price() == Approx(a_price).epsilon(0.001)); } SECTION("to_json") { ns::book3a book(an_author,a_title,a_price); json j(book); CHECK(j["Author"].as() == an_author); CHECK(j["Title"].as() == a_title); CHECK(j["Price"].as() == Approx(a_price).epsilon(0.001)); } } TEST_CASE("JSONCONS_ALL_GETTER_SETTER_NAME_TRAITS tests 2") { std::string an_author = "Haruki Murakami"; std::string a_title = "Kafka on the Shore"; double a_price = 25.17; std::string an_isbn = "1400079276"; SECTION("is") { json j; j["Author"] = an_author; j["Title"] = a_title; j["Price"] = a_price; bool val = j.is(); CHECK(val); } SECTION("as") { json j; j["Author"] = an_author; j["Title"] = a_title; j["Price"] = a_price; ns::book3b book = j.as(); CHECK(book.get_author() == an_author); CHECK(book.get_title() == a_title); CHECK(book.get_price() == Approx(a_price).epsilon(0.001)); } SECTION("to_json") { ns::book3b book(an_author,a_title,a_price, an_isbn); json j(book); CHECK(j["Author"].as() == an_author); CHECK(j["Title"].as() == a_title); CHECK(j["Price"].as() == Approx(a_price).epsilon(0.001)); CHECK(j["Isbn"].as() == an_isbn); } SECTION("decode") { json j; j["Author"] = an_author; j["Title"] = a_title; CHECK(j.is()); CHECK_FALSE(j.is()); std::string buffer; j.dump(buffer); auto book = decode_json(buffer); CHECK(book.get_author() == an_author); CHECK(book.get_title() == a_title); CHECK(book.get_price() == double()); CHECK(book.get_isbn() == std::string()); } } jsoncons-1.3.2/test/corelib/src/json_type_traits_chrono_tests.cpp000066400000000000000000000012071477700171100254410ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include using namespace jsoncons; TEST_CASE("json_type_traits chron tests") { SECTION("test 1") { uint64_t time = 1000; json j(time, semantic_tag::epoch_second); auto val = j.as(); CHECK(val.count() == std::chrono::seconds::rep(time)); } SECTION("test 2") { double time = 1000.100; json j(time, semantic_tag::epoch_second); auto val = j.as>(); CHECK(val.count() == time); } } jsoncons-1.3.2/test/corelib/src/json_type_traits_container_tests.cpp000066400000000000000000000510151477700171100261350ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("test_json_as_pair") { json j(json_array_arg, {false,1}); auto t = j.as>(); CHECK(std::get<0>(t) == false); CHECK(1 == std::get<1>(t)); } TEST_CASE("test_tuple_to_json") { auto t = std::make_tuple(false,1,"foo"); json j(t); REQUIRE(j.is_array()); REQUIRE(3 == j.size()); CHECK(false == j[0].as()); CHECK(1 == j[1].as()); CHECK(std::string("foo") == j[2].as()); } TEST_CASE("test_json_as_tuple") { json j(json_array_arg, {false,1,"foo"}); auto t = j.as>(); CHECK(std::get<0>(t) == false); CHECK(1 == std::get<1>(t)); CHECK(std::get<2>(t) == std::string("foo")); } TEST_CASE("test_characters") { const json a = "short"; const json b = "a long string"; CHECK(true == a.is()); CHECK(true == b.is()); std::string s2 = a.as(); std::string t2 = b.as(); json c(json_array_arg, { "short","a long string" }); auto u = c.as>(); } // vector TEST_CASE("test_is_json_vector") { json a(json_array_arg, {0,1,2,3,4}); CHECK(true == a.is>()); } TEST_CASE("test_as_vector") { json a(json_array_arg, {0,1,2,3,4}); std::vector v = a.as>(); CHECK(0 == v[0]); CHECK(1 == v[1]); CHECK(2 == v[2]); CHECK(3 == v[3]); CHECK(4 == v[4]); } TEST_CASE("test_assign_vector") { std::vector v {0,1,2,3,4}; json a = v; CHECK(json(0) == a[0]); CHECK(json(1) == a[1]); CHECK(json(2) == a[2]); CHECK(json(3) == a[3]); CHECK(json(4) == a[4]); } TEST_CASE("test_as_vector_of_bool") { json a = json::parse("[true,false,true]"); std::vector v = a.as>(); CHECK(v[0] == true); CHECK(v[1] == false); CHECK(v[2] == true); } TEST_CASE("test_assign_vector_of_bool") { std::vector v = {true,false,true}; json a = v; CHECK(a[0] == json(true)); CHECK(a[1] == json(false)); CHECK(a[2] == json(true)); json b; b = v; CHECK(b[0] == json(true)); CHECK(b[1] == json(false)); CHECK(b[2] == json(true)); } TEST_CASE("test_construct_vector_of_bool") { std::vector v = {true,false,true}; json a = v; CHECK(a[0] == json(true)); CHECK(a[1] == json(false)); CHECK(a[2] == json(true)); } TEST_CASE("test_construct_const_vector_of_bool") { const std::vector v = {true,false,true}; json a = v; CHECK(a[0] == json(true)); CHECK(a[1] == json(false)); CHECK(a[2] == json(true)); } // valarray TEST_CASE("test_is_json_valarray") { json a(json_array_arg, {0,1,2,3,4}); CHECK(true == a.is>()); } TEST_CASE("test_as_valarray") { json a(json_array_arg, {0,1,2,3,4}); std::valarray v = a.as>(); CHECK(0 == v[0]); CHECK(1 == v[1]); CHECK(2 == v[2]); CHECK(3 == v[3]); CHECK(4 == v[4]); } TEST_CASE("test_assign_valarray") { std::valarray v {0,1,2,3,4}; json a = v; CHECK(json(0) == a[0]); CHECK(json(1) == a[1]); CHECK(json(2) == a[2]); CHECK(json(3) == a[3]); CHECK(json(4) == a[4]); } TEST_CASE("test_is_json_map") { json a; a["a"] = 0; a["b"] = 1; a["c"] = 2; CHECK(true == (a.is >())); } TEST_CASE("test_is_json_map2") { json a; a["a"] = "0"; a["b"] = "1"; a["c"] = "2"; CHECK(true == (a["a"].is_string())); json b("0"); CHECK(true == (b.is())); CHECK(true == (a["a"].is())); CHECK(true == (a.is >())); } TEST_CASE("test_as_map") { json o; o["first"] = "first"; o["second"] = "second"; auto m = o.as>(); CHECK(std::string("first") == m.at("first")); CHECK(std::string("second") == m.at("second")); json o2(m); CHECK(o == o2); json o3; o3 = m; CHECK(o == o3); } TEST_CASE("test_as_map2") { json o; o["first"] = 1; o["second"] = true; o["third"] = jsoncons::null_type(); auto m = o.as>(); CHECK(std::string("1") == m.at("first")); CHECK(std::string("true") == m.at("second")); CHECK(std::string("null") == m.at("third")); json o2(m); CHECK(std::string("1") == o2["first"].as()); } TEST_CASE("byte string container") { SECTION("as") { std::vector bytes = {'H', 'e', 'l', 'l', 'o'}; json j(byte_string_arg, bytes); auto v = j.as>(); json other(byte_string_arg, v); } } TEST_CASE("test_from_stl_container") { std::vector a_vector{1, 2, 3, 4}; json j_vector(a_vector); CHECK((1 == j_vector[0].as())); CHECK(2 == j_vector[1].as()); CHECK(3 == j_vector[2].as()); CHECK(4 == j_vector[3].as()); std::vector a_vector2{1ul, 2ul, 3ul, 4ul}; json j_vec2(a_vector2); CHECK(1 == j_vec2[0].as()); CHECK(2 == j_vec2[1].as()); CHECK(3 == j_vec2[2].as()); CHECK(4 == j_vec2[3].as()); std::deque a_deque{1.123, 2.234, 3.456, 4.567}; json j_deque(a_deque); CHECK(1.123 == j_deque[0].as()); CHECK(2.234 == j_deque[1].as()); CHECK(3.456 == j_deque[2].as()); CHECK(4.567 == j_deque[3].as()); std::list a_list{true, true, false, true}; json j_list(a_list); CHECK(true == j_list[0].as()); CHECK(true == j_list[1].as()); CHECK(false == j_list[2].as()); CHECK(true == j_list[3].as()); std::forward_lista_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543}; json j_flist(a_flist); CHECK(static_cast(12345678909876) == j_flist[0].as()); CHECK(static_cast(23456789098765) == j_flist[1].as()); CHECK(static_cast(34567890987654) == j_flist[2].as()); CHECK(static_cast(45678909876543) == j_flist[3].as()); std::array a_array {{1, 2, 3, 4}}; json j_array(a_array); CHECK(1 == j_array[0].as()); CHECK(2 == j_array[1].as()); CHECK(3 == j_array[2].as()); CHECK(4 == j_array[3].as()); std::set a_set{"one", "two", "three", "four"}; json j_set(a_set); // ["four", "one", "three", "two"] std::unordered_set a_uset{"one", "two", "three", "four"}; json j_uset(a_uset); // maybe ["two", "three", "four", "one"] std::multiset a_mset{"one", "two", "one", "four"}; json j_mset(a_mset); // only one entry for "one" is used // maybe ["one", "two", "four"] std::unordered_multiset a_umset {"one", "two", "one", "four"}; json j_umset(a_umset); // both entries for "one" are used // maybe ["one", "two", "one", "four"] std::map a_map{ {"one", 1}, {"two", 2}, {"three", 3} }; json j_map(a_map); CHECK(1 == j_map["one"].as()); CHECK(2 == j_map["two"].as()); CHECK(3 == j_map["three"].as()); std::unordered_map a_umap{ {"one", 1.2}, {"two", 2.3}, {"three", 3.4} }; json j_umap(a_umap); CHECK(1.2 == j_umap["one"].as()); CHECK(2.3 == j_umap["two"].as()); CHECK(3.4 == j_umap["three"].as()); std::multimap a_mmap{ {"one", true}, {"two", true}, {"three", false}, {"three", true} }; json j_mmap(a_mmap); // one entry for key "three" CHECK(true == j_mmap.find("one")->value().as()); CHECK(true == j_mmap.find("two")->value().as()); CHECK(false == j_mmap.find("three")->value().as()); std::unordered_multimap a_ummap { {"one", true}, {"two", true}, /*{"three", false},*/ {"three", true} }; json j_ummap(a_ummap); // two entries for key "three" CHECK(true == j_ummap.find("one")->value().as()); CHECK(true == j_ummap.find("two")->value().as()); CHECK(true == j_ummap.find("three")->value().as()); } //own vector will always be of an even length struct own_vector : std::vector { using std::vector::vector; }; namespace jsoncons { template struct json_type_traits { static bool is(const Json& j) noexcept { return j.is_object() && j.size() % 2 == 0; } static own_vector as(const Json& j) { own_vector v; for (auto& item : j.object_range()) { std::string s(item.key()); v.push_back(std::strtol(s.c_str(),nullptr,10)); v.push_back(item.value().template as()); } return v; } static Json to_json(const own_vector& val){ Json j; for (std::size_t i=0;i struct is_json_type_traits_declared : public std::true_type {}; } // namespace jsoncons TEST_CASE("own_vector json_type_traits") { json j(json_object_arg,{ {"1",2},{"3",4} }); REQUIRE(j.is()); auto v = j.as(); REQUIRE(4 == v.size()); json j2 = v; CHECK(j2 == j); } TEST_CASE("map with integer key") { SECTION("test 1") { std::map val{ {1,1,},{2,2} }; json j{ val }; //CHECK(j.is>()); //CHECK(j.is>()); CHECK_FALSE(!j.is>()); REQUIRE(j.is_object()); REQUIRE(2 == j.size()); CHECK(1 == j["1"]); CHECK(2 == j["2"]); std::map other = j.as>(); REQUIRE(2 == other.size()); CHECK(1 == other[1]); CHECK(2 == other[2]); json other_j{ other }; REQUIRE(other_j.is_object()); REQUIRE(2 == other_j.size()); CHECK(1 == other_j["1"]); CHECK(2 == other_j["2"]); } } namespace { namespace ns { enum class MyCriterionType{ First, Presentation = First, MessageType, Version, Release, Last }; template class TCriterion { public: TCriterion() = default; TCriterion(E iType, std::string iVal) : _type(iType), _value(iVal) {} const std::string& getValue() const { return _value; } const E getType() const { return _type; } protected: JSONCONS_TYPE_TRAITS_FRIEND E _type; std::string _value; }; struct EnumClassHash { template std::size_t operator()(T t) const noexcept { return static_cast(t); } };//To be able to use the enum class as key template class TCriteria { public: TCriteria() = default; const std::unordered_map >& getCriteriaMap() const { return _criteriaMap; } //protected: JSONCONS_TYPE_TRAITS_FRIEND std::unordered_map, EnumClassHash> _criteriaMap; }; } // ns } // namespace JSONCONS_TPL_ALL_MEMBER_NAME_TRAITS(1,ns::TCriterion, (_type,"name"), (_value,"value")) JSONCONS_TPL_ALL_MEMBER_NAME_TRAITS(1, ns::TCriteria, (_criteriaMap, "criteriaList")) JSONCONS_ENUM_NAME_TRAITS(ns::MyCriterionType,(First,"first"),(MessageType,"message-type"),(Version,"version"),(Release,"release"),(Last,"last")) TEST_CASE("map with enum key") { SECTION("test 1") { ns::TCriterion criterion(ns::MyCriterionType::MessageType,"foo"); std::string buffer; encode_json(criterion, buffer, indenting::indent); //std::cout << buffer << "\n"; auto val = decode_json>(buffer); CHECK(val.getValue() == std::string("foo")); CHECK(val.getType() == ns::MyCriterionType::MessageType); } SECTION("test 2") { ns::TCriterion criterion(ns::MyCriterionType::MessageType, "foo"); ns::TCriteria criteria; criteria._criteriaMap.emplace(ns::MyCriterionType::MessageType, criterion); std::string buffer = R"( { "criteriaList" : { "message-type" : { "name": "message-type", "value": "foo" } } } )"; encode_json(criteria, buffer, indenting::indent); //std::cout << buffer << "\n"; auto val = decode_json>(buffer); auto x = val._criteriaMap.at(ns::MyCriterionType::MessageType); CHECK(x.getValue() == std::string("foo")); CHECK(x.getType() == ns::MyCriterionType::MessageType); } } namespace { namespace ns { struct Value { std::string name; std::int32_t value; friend bool operator==(const Value& lhs, const Value& rhs) { return lhs.name == rhs.name && lhs.value == rhs.value; } // Required for fedora24-x86_64 g++ 6.3.1 friend bool operator!=(const Value& lhs, const Value& rhs) { return !(lhs == rhs); } }; struct ValueHash { std::size_t operator()(const Value& val) const noexcept { std::size_t h1 = std::hash{}(val.name); std::size_t h2 = std::hash{}(val.value); return h1 ^ (h2 << 1); } }; inline bool operator<(const Value &l, const Value &r) noexcept { return l.name < r.name; } template struct Project { std::int32_t version = 1; std::string name; std::string author; std::string notes; bool showNotes; Container values; friend bool operator==(const Project& lhs, const Project& rhs) { return (lhs.version == rhs.version && lhs.name == rhs.name && lhs.author == rhs.author && lhs.notes == rhs.notes && lhs.showNotes == rhs.showNotes && lhs.values == rhs.values); } friend bool operator!=(const Project& lhs, const Project& rhs) { return !(lhs == rhs); } }; } // namespace ns } // namespace JSONCONS_N_MEMBER_TRAITS(ns::Value, 0, name, value ) JSONCONS_TPL_N_MEMBER_TRAITS(1, ns::Project, 0, version, name, author, notes, showNotes, values ) TEST_CASE("encode/decode set traits") { using project_type = ns::Project>; project_type project; project.name = "xyz"; project.author = "Jane Doe"; project.showNotes = true; project.values.insert({ "foo",1 }); project.values.insert({ "bar",2 }); project.values.insert({ "foo",1 }); project.values.insert({ "baz",1 }); SECTION("Value comparator tests") { ns::Value a{"foo", 1}; ns::Value b{ "foo",2 }; CHECK(a == a); CHECK(a != b); } SECTION("encode/decode") { std::string s; encode_json(project, s, indenting::indent); auto project2 = decode_json(s); CHECK(project2 == project); CHECK_FALSE(project2 != project); CHECK_FALSE(project2.values != project.values); } SECTION("json_type_traits") { json j{project}; auto project2 = j.as(); CHECK(project2 == project); } } TEST_CASE("encode/decode multiset traits") { using project_type = ns::Project>; project_type project; project.name = "xyz"; project.author = "Jane Doe"; project.showNotes = true; project.values.insert({ "foo",1 }); project.values.insert({ "bar",2 }); project.values.insert({ "foo",1 }); project.values.insert({ "baz",1 }); SECTION("encode/decode") { std::string s; encode_json(project, s, indenting::indent); auto project2 = decode_json(s); CHECK(project2 == project); } SECTION("json_type_traits") { json j{project}; auto project2 = j.as(); CHECK(project2 == project); } } TEST_CASE("encode/decode unordered_set traits") { using project_type = ns::Project>; project_type project; project.name = "xyz"; project.author = "Jane Doe"; project.showNotes = true; project.values.insert({ "foo",1 }); project.values.insert({ "bar",2 }); project.values.insert({ "foo",1 }); project.values.insert({ "baz",1 }); SECTION("encode/decode") { std::string s; encode_json(project, s, indenting::indent); auto project2 = decode_json(s); CHECK(project2 == project); } SECTION("json_type_traits") { json j{project}; auto project2 = j.as(); CHECK(project2 == project); } } TEST_CASE("encode/decode unordered_multiset traits") { using project_type = ns::Project>; project_type project; project.name = "xyz"; project.author = "Jane Doe"; project.showNotes = true; project.values.insert({ "foo",1 }); project.values.insert({ "bar",2 }); project.values.insert({ "foo",1 }); project.values.insert({ "baz",1 }); SECTION("encode/decode") { std::string s; encode_json(project, s, indenting::indent); auto project2 = decode_json(s); CHECK(project2 == project); } SECTION("json_type_traits") { json j{project}; auto project2 = j.as(); CHECK(project2 == project); } } TEST_CASE("encode/decode std::forward_list traits") { using project_type = ns::Project>; project_type project; project.name = "xyz"; project.author = "Jane Doe"; project.showNotes = true; project.values.push_front({ "foo",1 }); project.values.push_front({ "bar",2 }); project.values.push_front({ "foo",1 }); project.values.push_front({ "baz",1 }); SECTION("encode/decode") { std::string s; encode_json(project, s, indenting::indent); auto project2 = decode_json(s); CHECK(project2 == project); } SECTION("json_type_traits") { json j{project}; auto project2 = j.as(); CHECK(project2 == project); } } TEST_CASE("encode/decode std::deque traits") { using project_type = ns::Project>; project_type project; project.name = "xyz"; project.author = "Jane Doe"; project.showNotes = true; project.values.push_back({ "foo",1 }); project.values.push_back({ "bar",2 }); project.values.push_back({ "foo",1 }); project.values.push_back({ "baz",1 }); SECTION("encode/decode") { std::string s; encode_json(project, s, indenting::indent); auto project2 = decode_json(s); CHECK(project2 == project); } SECTION("json_type_traits") { json j{project}; auto project2 = j.as(); CHECK(project2 == project); } } TEST_CASE("encode/decode std::vector traits") { using project_type = ns::Project>; project_type project; project.name = "xyz"; project.author = "Jane Doe"; project.showNotes = true; project.values.push_back({ "foo",1 }); project.values.push_back({ "bar",2 }); project.values.push_back({ "foo",1 }); project.values.push_back({ "baz",1 }); SECTION("encode/decode") { std::string s; encode_json(project, s, indenting::indent); auto project2 = decode_json(s); CHECK(project2 == project); } SECTION("json_type_traits") { json j{project}; auto project2 = j.as(); CHECK(project2 == project); } } jsoncons-1.3.2/test/corelib/src/json_type_traits_string_tests.cpp000066400000000000000000000025041477700171100254600ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include using jsoncons::json_type_traits; using jsoncons::json; using jsoncons::wjson; using jsoncons::decode_json; using jsoncons::encode_json; TEST_CASE("json_type_traits string tests") { SECTION("test 1") { std::string s = "foo"; std::wstring buf; encode_json(s,buf); auto s2 = decode_json(buf); CHECK(s2 == s); } SECTION("test 2") { std::wstring s = L"foo"; std::string buf; encode_json(s,buf); auto s2 = decode_json(buf); CHECK(s2 == s); } } TEST_CASE("json_type_traits vector of string tests") { SECTION("test 1") { std::vector v = {"foo","bar","baz"}; std::wstring buf; encode_json(v,buf); auto v2 = decode_json>(buf); CHECK(v2 == v); } SECTION("test 2") { std::vector v = {L"foo",L"bar",L"baz"}; std::string buf; encode_json(v,buf); auto v2 = decode_json>(buf); CHECK(v2 == v); } } jsoncons-1.3.2/test/corelib/src/json_type_traits_tests.cpp000066400000000000000000000233161477700171100240760ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include using namespace jsoncons; // own vector will always be of an even length struct own_vector : std::vector { using std::vector::vector; }; namespace jsoncons { template struct json_type_traits { static bool is(const Json&) noexcept { return true; } static own_vector as(const Json&) { return own_vector(); } static Json to_json(const own_vector& val) { Json j; for (uint64_t i = 0; i(p); root["Test"] = q; } TEST_CASE("test_uint8_t") { uint8_t x = 10; json o; o["u"] = x; CHECK(o["u"].is_number()); uint8_t y = o["u"].as(); CHECK(y == 10); } TEST_CASE("test_float_assignment") { float x = 10.5; json o; o["float"] = x; CHECK(o["float"].is_number()); float y = o["float"].as(); CHECK(10.5 == Approx(y).epsilon(0.00001)); } TEST_CASE("test_float") { float x = 10.5; json o(x); CHECK(o.is()); float y = o.as(); CHECK(10.5 == Approx(y).epsilon(0.00001)); } TEST_CASE("test_unsupported_type") { json o; //o["u"] = Info; // compile error } TEST_CASE("test_as_json_value") { json a; a["first"] = "first"; a["second"] = "second"; CHECK(true == a.is()); json b = a.as(); CHECK("first" == b["first"].as()); CHECK("second" == b["second"].as()); } TEST_CASE("test_byte_string_as_vector") { json a(byte_string{'H','e','l','l','o'}); REQUIRE(a.is_byte_string()); auto bytes = a.as(); REQUIRE(5 == bytes.size()); CHECK('H' == bytes[0]); CHECK('e' == bytes[1]); CHECK('l' == bytes[2]); CHECK('l' == bytes[3]); CHECK('o' == bytes[4]); } TEST_CASE("jsoncons::json_type_traits") { std::vector> v = { 0,1,jsoncons::optional{} }; json j = v; REQUIRE(3 == j.size()); CHECK(0 == j[0].as()); CHECK(1 == j[1].as()); CHECK(j[2].is_null()); CHECK(j[0].is>()); CHECK_FALSE(j[0].is>()); CHECK(j[1].is>()); CHECK_FALSE(j[1].is>()); CHECK(j[2].is>()); // null can be any optinal } TEST_CASE("jsoncons::json_type_traits") { std::vector> v = {std::make_shared("Hello"), std::make_shared("World"), std::shared_ptr()}; json j{v}; REQUIRE(3 == j.size()); CHECK(j[0].as() == std::string("Hello")); CHECK(j[1].as() == std::string("World")); CHECK(j[2].is_null()); CHECK(j[0].is>()); CHECK_FALSE(j[0].is>()); CHECK(j[1].is>()); CHECK_FALSE(j[1].is>()); CHECK(j[2].is>()); } TEST_CASE("jsoncons::json_type_traits") { std::vector> v; v.emplace_back(jsoncons::make_unique("Hello")); v.emplace_back(jsoncons::make_unique("World")); v.emplace_back(std::unique_ptr()); json j{ v }; REQUIRE(3 == j.size()); CHECK(j[0].as() == std::string("Hello")); CHECK(j[1].as() == std::string("World")); CHECK(j[2].is_null()); CHECK(j[0].is>()); CHECK_FALSE(j[0].is>()); CHECK(j[1].is>()); CHECK_FALSE(j[1].is>()); CHECK(j[2].is>()); } /* TEST_CASE("test_own_vector") { jsoncons::json j = own_vector({0,9,8,7}); std::cout << j; } */ #if defined(JSONCONS_HAS_STD_VARIANT) namespace { namespace ns { enum class Color {yellow, red, green, blue}; inline std::ostream& operator<<(std::ostream& os, Color val) { switch (val) { case Color::yellow: os << "yellow"; break; case Color::red: os << "red"; break; case Color::green: os << "green"; break; case Color::blue: os << "blue"; break; } return os; } class Fruit { private: JSONCONS_TYPE_TRAITS_FRIEND std::string name_; Color color_; public: }; class Fabric { private: JSONCONS_TYPE_TRAITS_FRIEND int size_; std::string material_; public: }; class Basket { private: JSONCONS_TYPE_TRAITS_FRIEND std::string owner_; std::vector> items_; public: std::string owner() const { return owner_; } std::vector> items() const { return items_; } }; } // ns } // namespace JSONCONS_ENUM_NAME_TRAITS(ns::Color, (yellow, "YELLOW"), (red, "RED"), (green, "GREEN"), (blue, "BLUE")) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::Fruit, (name_, "name"), (color_, "color")) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::Fabric, (size_, "size"), (material_, "material")) JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::Basket, (owner_, "owner"), (items_, "items")) TEST_CASE("json_type_traits for std::variant") { std::string input = R"( { "owner": "Rodrigo", "items": [ { "name": "banana", "color": "YELLOW" }, { "size": 40, "material": "wool" }, { "name": "apple", "color": "RED" }, { "size": 40, "material": "cotton" } ] } )"; SECTION("test decode and encode") { ns::Basket basket = decode_json(input); std::string output; encode_json(basket, output, indenting::indent); json j1 = json::parse(input); json j2 = json::parse(output); CHECK(j1 == j2); } SECTION("std::variant test") { using variant_type = std::variant; variant_type var1(100); variant_type var2(10.1); variant_type var3(false); variant_type var4(std::string("Hello World")); variant_type var5(ns::Color::yellow); std::string buffer1; jsoncons::encode_json(var1,buffer1); std::string buffer2; jsoncons::encode_json(var2,buffer2); std::string buffer3; jsoncons::encode_json(var3,buffer3); std::string buffer4; jsoncons::encode_json(var4,buffer4); std::string buffer5; jsoncons::encode_json(var5,buffer5); auto v1 = jsoncons::decode_json(buffer1); auto v2 = jsoncons::decode_json(buffer2); auto v3 = jsoncons::decode_json(buffer3); auto v4 = jsoncons::decode_json(buffer4); auto v5 = jsoncons::decode_json(buffer5); CHECK(0 == v1.index()); CHECK(1 == v2.index()); CHECK(2 == v3.index()); CHECK(3 == v4.index()); CHECK(3 == v5.index()); CHECK(std::get<0>(v1) == 100); CHECK(std::get<1>(v2) == 10.1); CHECK(std::get<2>(v3) == false); CHECK(std::get<3>(v4) == std::string("Hello World")); CHECK(std::get<3>(v5) == std::string("YELLOW")); } SECTION("std::variant test") { using variant_type = std::variant; variant_type var1(100); variant_type var2(10.1); variant_type var3(false); variant_type var4(std::string("Hello World")); variant_type var5(ns::Color::yellow); std::string buffer1; jsoncons::encode_json(var1,buffer1); std::string buffer2; jsoncons::encode_json(var2,buffer2); std::string buffer3; jsoncons::encode_json(var3,buffer3); std::string buffer4; jsoncons::encode_json(var4,buffer4); std::string buffer5; jsoncons::encode_json(var5,buffer5); auto v1 = jsoncons::decode_json(buffer1); auto v2 = jsoncons::decode_json(buffer2); auto v3 = jsoncons::decode_json(buffer3); auto v4 = jsoncons::decode_json(buffer4); auto v5 = jsoncons::decode_json(buffer5); CHECK(0 == v1.index()); CHECK(1 == v2.index()); CHECK(2 == v3.index()); CHECK(4 == v4.index()); CHECK(3 == v5.index()); CHECK(std::get<0>(v1) == 100); CHECK(std::get<1>(v2) == 10.1); CHECK(std::get<2>(v3) == false); CHECK(std::get<4>(v4) == std::string("Hello World")); CHECK(std::get<3>(v5) == ns::Color::yellow); } } #endif jsoncons-1.3.2/test/corelib/src/json_validation_tests.cpp000066400000000000000000000147641477700171100236700ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include namespace ns { struct employee_AMN { std::string name; uint64_t id; int age; }; struct employee_NMN { std::string name; uint64_t id; int age; }; class employee_ACGN { std::string name_; uint64_t id_; int age_; public: employee_ACGN(std::string name, uint64_t id, int age) : name_(name), id_(id), age_(age) { } const std::string& name() const {return name_;} uint64_t id() const {return id_;} int age() const {return age_;} }; class employee_NCGN { std::string name_; uint64_t id_; int age_; public: employee_NCGN(std::string name, uint64_t id, int age) : name_(name), id_(id), age_(age) { } const std::string& name() const {return name_;} uint64_t id() const {return id_;} int age() const {return age_;} }; class employee_AGSN { std::string name_; uint64_t id_; int age_; public: const std::string& name() const {return name_;} uint64_t id() const {return id_;} int age() const {return age_;} void name(const std::string& value) {name_ = value;} void id(uint64_t value) {id_ = value;} void age(int value) {age_ = value;} }; class employee_NGSN { std::string name_; uint64_t id_; int age_; public: const std::string& name() const {return name_;} uint64_t id() const {return id_;} int age() const {return age_;} void name(const std::string& value) {name_ = value;} void id(uint64_t value) {id_ = value;} void age(int value) {age_ = value;} }; } // namespace jsoncons JSONCONS_ALL_MEMBER_NAME_TRAITS(ns::employee_AMN, (name,"Name"), (id,"Id"), (age,"Age",JSONCONS_RDWR, [](int age) noexcept { return age >= 16 && age <= 68; } ) ) JSONCONS_N_MEMBER_NAME_TRAITS(ns::employee_NMN,3, (name,"Name"), (id,"Id"), (age,"Age",JSONCONS_RDWR, [](int age) noexcept { return age >= 16 && age <= 68; } ) ) JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(ns::employee_ACGN, (name,"Name"), (id,"Id"), (age,"Age",JSONCONS_RDWR, [](int age) noexcept { return age >= 16 && age <= 68; } ) ) JSONCONS_N_CTOR_GETTER_NAME_TRAITS(ns::employee_NCGN, 3, (name,"Name"), (id,"Id"), (age,"Age",JSONCONS_RDWR, [](int age) noexcept { return age >= 16 && age <= 68; } ) ) JSONCONS_ALL_GETTER_SETTER_NAME_TRAITS(ns::employee_AGSN, (name,name,"Name"), (id,id,"Id"), (age,age,"Age",JSONCONS_RDWR, [](int age) noexcept { return age >= 16 && age <= 68; } ) ) JSONCONS_N_GETTER_SETTER_NAME_TRAITS(ns::employee_NGSN, 3, (name,name,"Name"), (id,id,"Id"), (age,age,"Age",JSONCONS_RDWR, [](int age) noexcept { return age >= 16 && age <= 68; } ) ) TEST_CASE("json validator tests") { const std::string input = R"( [ { "Name" : "John Smith", "Id" : 22, "Age" : 345 }, { "Name" : "", "Id" : 23, "Age" : 36 }, { "Name" : "Jane Doe", "Id" : 24, "Age" : 34 } ] )"; SECTION("employee_AMN test") { jsoncons::json_string_cursor cursor(input); auto view = jsoncons::staj_array(cursor); for (auto it = view.begin(); it != view.end(); ++it) { if (it.has_value()) { auto val = *it; } else { REQUIRE_THROWS_WITH(*it, "Not a ns::employee_AMN: Unable to convert into the provided type"); } } } SECTION("employee_NMN test") { jsoncons::json_string_cursor cursor(input); auto view = jsoncons::staj_array(cursor); for (auto it = view.begin(); it != view.end(); ++it) { if (it.has_value()) { auto val = *it; } else { REQUIRE_THROWS_WITH(*it, "Not a ns::employee_NMN: Unable to convert into the provided type"); } } } SECTION("employee_ACGN test") { jsoncons::json_string_cursor cursor(input); auto view = jsoncons::staj_array(cursor); for (auto it = view.begin(); it != view.end(); ++it) { if (it.has_value()) { auto val = *it; } else { REQUIRE_THROWS_WITH(*it, "Not a ns::employee_ACGN: Unable to convert into the provided type"); } } } SECTION("employee_NCGN test") { jsoncons::json_string_cursor cursor(input); auto view = jsoncons::staj_array(cursor); for (auto it = view.begin(); it != view.end(); ++it) { if (it.has_value()) { auto val = *it; } else { REQUIRE_THROWS_WITH(*it, "Not a ns::employee_NCGN: Unable to convert into the provided type"); } } } SECTION("employee_AGSN test") { jsoncons::json_string_cursor cursor(input); auto view = jsoncons::staj_array(cursor); for (auto it = view.begin(); it != view.end(); ++it) { if (it.has_value()) { auto val = *it; } else { REQUIRE_THROWS_WITH(*it, "Not a ns::employee_AGSN: Unable to convert into the provided type"); } } } SECTION("employee_NGSN test") { jsoncons::json_string_cursor cursor(input); auto view = jsoncons::staj_array(cursor); for (auto it = view.begin(); it != view.end(); ++it) { if (it.has_value()) { auto val = *it; } else { REQUIRE_THROWS_WITH(*it, "Not a ns::employee_NGSN: Unable to convert into the provided type"); } } } } jsoncons-1.3.2/test/corelib/src/jsoncons_tests.cpp000066400000000000000000000141021477700171100223230ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("test_assignment") { json root; root["double_1"] = 10.0; json double_1 = root["double_1"]; root["myobject"] = json(); root["myobject"]["double_2"] = 7.0; root["myobject"]["bool_2"] = true; root["myobject"]["int_2"] = 0LL; root["myobject"]["string_2"] = "my string"; root["myarray"] = json(json_array_arg); json double_2 = root["myobject"]["double_2"]; CHECK(double_1.as() == Approx(10.0).epsilon(0.000001)); CHECK(double_2.as() == Approx(7.0).epsilon(0.000001)); CHECK(7 == double_2.as()); CHECK(root["myobject"]["bool_2"].as()); CHECK(0 == root["myobject"]["int_2"].as()); CHECK(root["myobject"]["string_2"].as() == std::string("my string")); CHECK(root["myobject"]["bool_2"].as()); CHECK(0 == root["myobject"]["int_2"].as()); CHECK(root["myobject"]["string_2"].as() == std::string("my string")); } TEST_CASE("test_1") { basic_json j; std::basic_ostringstream os; std::cout << sizeof(json) << '\n'; //os << j << U"\n"; } TEST_CASE("test_shrink_to_fit") { json val = json::make_array(3); val.reserve(100); val[0].reserve(100); val[0]["key"] = "value"; val.shrink_to_fit(); CHECK(3 == val.size()); CHECK(1 == val[0].size()); } TEST_CASE("test_for_each_value") { std::string input = "{\"A\":\"Jane\", \"B\":\"Roe\",\"C\":10}"; json val = json::parse(input); auto it = val.object_range().begin(); CHECK(it->value().is_string()); ++it; CHECK(it->value().is_string()); ++it; CHECK(it->value().type() == jsoncons::json_type::uint64_value); ++it; CHECK((it == val.object_range().end())); } TEST_CASE("test_array") { json root; root["addresses"]; std::vector addresses; json address1; address1["city"] = "San Francisco"; address1["state"] = "CA"; address1["zip"] = "94107"; address1["country"] = "USA"; addresses.push_back(address1); json address2; address2["city"] = "Sunnyvale"; address2["state"] = "CA"; address2["zip"] = "94085"; address2["country"] = "USA"; addresses.push_back(address2); root["addresses"] = addresses; CHECK(2 == root["addresses"].size()); } TEST_CASE("test_null") { json nullval = json::null(); CHECK(nullval.is_null()); CHECK(nullval.is()); json obj; obj["field"] = json::null(); CHECK(obj["field"] == json::null()); } TEST_CASE("test_to_string") { std::ostringstream os; os << "{" << "\"string\":\"value\"" << ",\"null\":null" << ",\"bool1\":false" << ",\"bool2\":true" << ",\"integer\":12345678" << ",\"neg-integer\":-87654321" << ",\"double\":123456.01" << ",\"neg-double\":-654321.01" << ",\"exp\":2.00600e+03" << ",\"minus-exp\":1.00600e-010" << ",\"escaped-string\":\"\\\\\\n\"" << "}"; json root = json::parse(os.str()); CHECK(root["null"].is_null()); CHECK(root["null"].is()); CHECK_FALSE(root["bool1"].as()); CHECK(root["bool2"].as()); CHECK(root["integer"].as() == 12345678); CHECK(root["integer"].as() == 12345678); CHECK(root["neg-integer"].as() == -87654321); CHECK(root["double"].as() == Approx(123456.01).epsilon(0.0000001)); CHECK(root["escaped-string"].as() == std::string("\\\n")); CHECK_FALSE(root["bool1"].as()); CHECK(root["bool2"].as()); CHECK(root["integer"].as() == 12345678); CHECK(root["integer"].as() == 12345678); CHECK(root["neg-integer"].as() == -87654321); CHECK(root["double"].as() == Approx(123456.01).epsilon(0.0000001)); CHECK(root["escaped-string"].as() == std::string("\\\n")); } TEST_CASE("test_u0000") { std::string inputStr("[\"\\u0040\\u0040\\u0000\\u0011\"]"); //std::cout << "Input: " << inputStr << '\n'; json arr = json::parse(inputStr); std::string s = arr[0].as(); REQUIRE(4 == s.length()); CHECK(static_cast(s[0]) == 0x40); CHECK(static_cast(s[1]) == 0x40); CHECK(static_cast(s[2]) == 0x00); CHECK(static_cast(s[3]) == 0x11); std::ostringstream os; os << arr; std::string s2 = os.str(); //std::cout << std::hex << "Output: " << os.str() << '\n'; } TEST_CASE("test_uHHHH") { std::string inputStr("[\"\\u007F\\u07FF\\u0800\"]"); json arr = json::parse(inputStr); std::string s = arr[0].as(); REQUIRE(6 == s.length()); CHECK(static_cast(s[0]) == 0x7f); CHECK(static_cast(s[1]) == 0xdf); CHECK(static_cast(s[2]) == 0xbf); CHECK(static_cast(s[3]) == 0xe0); CHECK(static_cast(s[4]) == 0xa0); CHECK(static_cast(s[5]) == 0x80); std::ostringstream os; auto options = json_options{} .escape_all_non_ascii(true); arr.dump(os, options); std::string outputStr = os.str(); json arr2 = json::parse(outputStr); std::string s2 = arr2[0].as(); REQUIRE(6 == s2.length()); CHECK(static_cast(s2[0]) == 0x7f); CHECK(static_cast(s2[1]) == 0xdf); CHECK(static_cast(s2[2]) == 0xbf); CHECK(static_cast(s2[3]) == 0xe0); CHECK(static_cast(s2[4]) == 0xa0); CHECK(static_cast(s2[5]) == 0x80); } TEST_CASE("test_multiline_comments") { std::string path = "./corelib/input/json-multiline-comment.json"; std::fstream is(path); if (!is) { std::cout << "Cannot open " << path << '\n'; return; } json j = json::parse(is); CHECK(j.is_array()); CHECK(0 == j.size()); } jsoncons-1.3.2/test/corelib/src/ojson_object_tests.cpp000066400000000000000000000265151477700171100231600ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("ojson insert(first,last) test") { SECTION("copy map into ojson") { std::map m1 = {{"f",4},{"e",5},{"d",6}}; std::map m2 = {{"c",1},{"b",2},{"a",3}}; ojson doc; doc.insert(m1.begin(),m1.end()); doc.insert(m2.begin(),m2.end()); //std::cout << doc << "\n"; REQUIRE(6 == doc.size()); auto it = doc.object_range().begin(); CHECK(it++->key() == "d"); CHECK(it++->key() == "e"); CHECK(it++->key() == "f"); CHECK(it++->key() == "a"); CHECK(it++->key() == "b"); CHECK(it++->key() == "c"); } } TEST_CASE("ojson parse_duplicate_names") { SECTION("duplicates at front") { ojson doc = ojson::parse(R"({"first":1,"first":2,"second":2,"third":3})"); REQUIRE(3 == doc.size()); CHECK(1 == doc["first"].as()); CHECK(2 == doc["second"].as()); CHECK(3 == doc["third"].as()); } SECTION("duplicates at back") { ojson doc = ojson::parse(R"({"first":1,"second":2,"third":3,"third":4})"); REQUIRE(3 == doc.size()); CHECK(1 == doc["first"].as()); CHECK(2 == doc["second"].as()); CHECK(3 == doc["third"].as()); } SECTION("duplicates at endpoints") { ojson doc = ojson::parse(R"({"first":1,"second":2,"third":3,"first":4})"); REQUIRE(3 == doc.size()); CHECK(1 == doc["first"].as()); CHECK(2 == doc["second"].as()); CHECK(3 == doc["third"].as()); } } TEST_CASE("ojson object erase with iterator") { SECTION("ojson erase with iterator") { ojson doc(jsoncons::json_object_arg); doc.try_emplace("a", 1); doc.try_emplace("b", 2); doc.try_emplace("c", 3); auto it = doc.object_range().begin(); while (it != doc.object_range().end()) { if (it->key() == "a" || it->key() == "c") { it = doc.erase(it); } else { it++; } } CHECK(1 == doc.size()); CHECK(2 == doc.at("b")); CHECK(doc.at("b") == 2.0); CHECK(doc.at("b") == 2.0f); CHECK(2 == doc["b"]); } SECTION("ojson erase with iterator 2") { ojson doc(jsoncons::json_object_arg); doc.try_emplace("a", 1); doc.try_emplace("b", 2); doc.try_emplace("c", 3); auto it = doc.object_range().begin(); while (it != doc.object_range().end()) { if (it->key() == "a") { it = doc.erase(it, it+2); } else { it++; } } CHECK(1 == doc.size()); CHECK(3 == doc.at("c")); CHECK(3 == doc["c"]); } SECTION("ojson erase with iterator 3") { ojson doc(jsoncons::json_object_arg); doc.try_emplace("c", 1); doc.try_emplace("b", 2); doc.try_emplace("a", 3); auto it = doc.object_range().begin(); while (it != doc.object_range().end()) { if (it->key() == "c") { it = doc.erase(it, it+2); } else { it++; } } CHECK(1 == doc.size()); CHECK(3 == doc.at("a")); CHECK(3 == doc["a"]); } } TEST_CASE("test_ojson_merge") { ojson doc = ojson::parse(R"( { "a" : 1, "b" : 2 } )"); const ojson source = ojson::parse(R"( { "a" : 2, "c" : 3, "d" : 4, "b" : 5, "e" : 6 } )"); SECTION("merge doc with source") { const ojson expected = ojson::parse(R"( { "a" : 1, "b" : 2, "c" : 3, "d" : 4, "e" : 6 } )"); doc.merge(source); CHECK(expected == doc); } SECTION("merge doc") { const ojson expected = ojson::parse(R"( {"a":1,"b":2,"c":3,"d":4,"e":6} )"); doc.merge(doc.object_range().begin()+1,source); CHECK(expected == doc); } //std::cout << doc << '\n'; } TEST_CASE("test_ojson_merge_move") { ojson doc = ojson::parse(R"( { "a" : "1", "d" : [1,2,3] } )"); ojson source = ojson::parse(R"( { "a" : "2", "c" : [4,5,6] } )"); SECTION("merge source into doc") { ojson expected = ojson::parse(R"( { "a" : "1", "d" : [1,2,3], "c" : [4,5,6] } )"); doc.merge(std::move(source)); CHECK(expected == doc); } SECTION("merge source into doc at begin") { ojson expected = ojson::parse(R"( { "a" : "1", "d" : [1,2,3], "c" : [4,5,6] } )"); doc.merge(doc.object_range().begin(),std::move(source)); CHECK(expected == doc); } //std::cout << "(1)\n" << doc << '\n'; //std::cout << "(2)\n" << source << '\n'; } TEST_CASE("ojson merge_or_update test") { ojson doc = ojson::parse(R"( { "a" : 1, "b" : 2 } )"); const ojson source = ojson::parse(R"( { "a" : 2, "c" : 3 } )"); SECTION("merge_or_update source into doc") { const ojson expected = ojson::parse(R"( { "a" : 2, "b" : 2, "c" : 3 } )"); doc.merge_or_update(source); CHECK(expected == doc); } SECTION("merge_or_update source into doc at pos 1") { const ojson expected = ojson::parse(R"( { "a" : 2, "b" : 2, "c" : 3 } )"); doc.merge_or_update(doc.object_range().begin()+1,source); CHECK(expected == doc); } //std::cout << doc << '\n'; } TEST_CASE("test_ojson_merge_or_update_move") { ojson doc = ojson::parse(R"( { "a" : "1", "d" : [1,2,3] } )"); ojson source = ojson::parse(R"( { "a" : "2", "c" : [4,5,6] } )"); SECTION("merge or update doc from source") { ojson expected = ojson::parse(R"( { "a" : "2", "d" : [1,2,3], "c" : [4,5,6] } )"); doc.merge_or_update(std::move(source)); //CHECK(expected == doc); } SECTION("merge or update doc from source at pos") { ojson expected = ojson::parse(R"( { "a" : "2", "d" : [1,2,3], "c" : [4,5,6] } )"); doc.merge_or_update(doc.object_range().begin(),std::move(source)); CHECK(expected == doc); } } #if defined(JSONCONS_HAS_STATEFUL_ALLOCATOR) && JSONCONS_HAS_STATEFUL_ALLOCATOR == 1 #include #include template using MyScopedAllocator = std::scoped_allocator_adaptor>; using cust_json = jsoncons::basic_json>; TEST_CASE("cust_json.merge test with order_preserving_policy and statefule allocator") { MyScopedAllocator alloc(1); cust_json doc = cust_json::parse(combine_allocators(alloc), R"( { "a" : 1, "b" : 2 } )"); const cust_json source = cust_json::parse(combine_allocators(alloc), R"( { "a" : 2, "c" : 3, "d" : 4, "b" : 5, "e" : 6 } )"); SECTION("merge doc with source") { const cust_json expected = cust_json::parse(combine_allocators(alloc), R"( { "a" : 1, "b" : 2, "c" : 3, "d" : 4, "e" : 6 } )"); doc.merge(source); CHECK(expected == doc); } SECTION("merge doc") { const cust_json expected = cust_json::parse(combine_allocators(alloc), R"( {"a":1,"b":2,"c":3,"d":4,"e":6} )"); doc.merge(doc.object_range().begin()+1,source); CHECK(expected == doc); } } TEST_CASE("cust_json object erase with iterator") { MyScopedAllocator alloc(1); SECTION("cust_json erase with iterator") { cust_json doc(jsoncons::json_object_arg, alloc); doc.try_emplace("a", 1); doc.try_emplace("b", 2); doc.try_emplace("c", 3); auto it = doc.object_range().begin(); while (it != doc.object_range().end()) { if (it->key() == jsoncons::string_view("a") || it->key() == jsoncons::string_view("c")) { it = doc.erase(it); } else { it++; } } CHECK(1 == doc.size()); CHECK(2 == doc.at("b")); CHECK(2 == doc["b"]); } SECTION("cust_json erase with iterator 2") { cust_json doc(jsoncons::json_object_arg, alloc); doc.try_emplace("a", 1); doc.try_emplace("b", 2); doc.try_emplace("c", 3); auto it = doc.object_range().begin(); while (it != doc.object_range().end()) { if (it->key() == jsoncons::string_view("a")) { it = doc.erase(it, it+2); } else { it++; } } CHECK(1 == doc.size()); CHECK(3 == doc.at("c")); CHECK(3 == doc["c"]); } SECTION("cust_json erase with iterator 3") { cust_json doc(jsoncons::json_object_arg, alloc); doc.try_emplace("c", 1); doc.try_emplace("b", 2); doc.try_emplace("a", 3); auto it = doc.object_range().begin(); while (it != doc.object_range().end()) { if (it->key() == jsoncons::string_view("c")) { it = doc.erase(it, it+2); } else { it++; } } CHECK(1 == doc.size()); CHECK(3 == doc.at("a")); CHECK(3 == doc["a"]); } } TEST_CASE("cust_json merge_or_update test") { MyScopedAllocator alloc(1); cust_json doc = cust_json::parse(combine_allocators(alloc), R"( { "a" : 1, "b" : 2 } )"); const cust_json source = cust_json::parse(combine_allocators(alloc), R"( { "a" : 2, "c" : 3 } )"); SECTION("merge_or_update source into doc") { const cust_json expected = cust_json::parse(combine_allocators(alloc), R"( { "a" : 2, "b" : 2, "c" : 3 } )"); doc.merge_or_update(source); CHECK(expected == doc); } SECTION("merge_or_update source into doc at pos 1") { const cust_json expected = cust_json::parse(combine_allocators(alloc), R"( { "a" : 2, "b" : 2, "c" : 3 } )"); doc.merge_or_update(doc.object_range().begin()+1,source); CHECK(expected == doc); } } #endif jsoncons-1.3.2/test/corelib/src/ojson_tests.cpp000066400000000000000000000044661477700171100216330ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("test_index") { ojson o = ojson::parse(R"( { "street_number" : "100", "street_name" : "Queen St W", "city" : "Toronto", "country" : "Canada" } )"); CHECK("100" == o[0].as()); CHECK("Queen St W" == o[1].as()); CHECK("Toronto" ==o[2].as()); CHECK("Canada" ==o[3].as()); CHECK("100" == o.at(0).as()); CHECK("Queen St W" == o.at(1).as()); CHECK("Toronto" ==o.at(2).as()); CHECK("Canada" ==o.at(3).as()); } TEST_CASE("test_object") { ojson o = ojson::parse(R"( { "street_number" : "100", "street_name" : "Queen St W", "city" : "Toronto", "country" : "Canada" } )"); o.insert_or_assign("postal_code", "M5H 2N2"); ojson o2 = o; CHECK(o == o2); ojson o3 = o; o3["street_name"] = "Queen St W"; //CHECK(o == o3); //BOOST_CHECK_EQUAL("Queen St W",o["street_name"].as()); //CHECK(2 == o["city"].as()); //CHECK(4 == o["street_number"].as()); auto it = o.find("country"); CHECK_FALSE((it == o.object_range().end())); o.insert_or_assign(it,"province","Ontario"); o.insert_or_assign("unit_type","O"); o.erase("unit_type"); } TEST_CASE("test_object_emplace") { ojson o = ojson::parse(R"( { "street_number" : "100", "street_name" : "Queen St W", "city" : "Toronto", "country" : "Canada" } )"); o.try_emplace("postal_code", "M5H 2N2"); ojson o2 = o; CHECK(o == o2); ojson o3 = o; o3["street_name"] = "Queen St W"; //CHECK(o == o3); //BOOST_CHECK_EQUAL("Queen St W",o["street_name"].as()); //CHECK(2 == o["city"].as()); //CHECK(4 == o["street_number"].as()); auto it = o.find("country"); CHECK_FALSE((it == o.object_range().end())); o.try_emplace(it,"province","Ontario"); o.try_emplace("unit_type","O"); o.erase("unit_type"); } jsoncons-1.3.2/test/corelib/src/parse_string_tests.cpp000066400000000000000000000055631477700171100232020ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include using namespace jsoncons; struct jsonpath_filter_fixture { }; class lenient_error_handler { std::error_code value_; public: lenient_error_handler(std::error_code value) : value_(value) { } bool operator()(const std::error_code& ec, const ser_context&) noexcept { return ec == value_; // if returns true, use default processing } }; TEST_CASE("test_parse_small_string1") { std::string input = "\"String\""; json_decoder decoder; JSONCONS_TRY { json_string_reader reader(input,decoder); reader.read_next(); } JSONCONS_CATCH (const std::exception&) { } CHECK(decoder.is_valid()); } TEST_CASE("test_parse_small_string2") { std::string input = "\"Str\\\"ing\""; json_decoder decoder; JSONCONS_TRY { json_string_reader reader(input, decoder); reader.read_next(); } JSONCONS_CATCH (const std::exception&) { } CHECK(decoder.is_valid()); } TEST_CASE("test_parse_small_string4") { std::string input = "\"Str\\\"ing\""; for (std::size_t i = 4; i < input.length(); ++i) { std::istringstream is(input); json_decoder decoder; JSONCONS_TRY { json_stream_reader reader(stream_source(is,i), decoder); reader.read_next(); } JSONCONS_CATCH (const std::exception&) { } CHECK(decoder.is_valid()); CHECK(std::string("Str\"ing") == decoder.get_result().as()); } } TEST_CASE("test_parse_big_string1") { std::string input = "\"Big Str\\\"ing\""; for (std::size_t i = 4; i < input.length(); ++i) { std::istringstream is(input); json_decoder decoder; JSONCONS_TRY { json_stream_reader reader(stream_source(is,i), decoder); reader.read_next(); } JSONCONS_CATCH (const std::exception&) { } CHECK(decoder.is_valid()); CHECK(std::string("Big Str\"ing") == decoder.get_result().as()); } } #if 0 TEST_CASE("test_parse_big_string2") { std::string input = "\"Big\t Str\\\"ing\""; std::istringstream is(input); json_decoder decoder; lenient_error_handler err_handler(json_errc::illegal_character_in_string); JSONCONS_TRY { json_stream_reader reader(is, decoder, err_handler); reader.read_next(); } JSONCONS_CATCH (const std::exception&) { } CHECK(decoder.is_valid()); CHECK(std::string("Big\t Str\"ing") == decoder.get_result().as()); } #endif jsoncons-1.3.2/test/corelib/src/polymorphic_allocator_tests.cpp000066400000000000000000000141501477700171100250770ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #if defined(JSONCONS_HAS_POLYMORPHIC_ALLOCATOR) && JSONCONS_HAS_POLYMORPHIC_ALLOCATOR == 1 #include using namespace jsoncons; using pmr_json = jsoncons::pmr::json; using pmr_ojson = jsoncons::pmr::ojson; TEST_CASE("string polymorhic allocator tests") { char buffer1[1024] = {}; // a small buffer on the stack memset(buffer1, 0, sizeof(buffer1)); std::pmr::monotonic_buffer_resource pool1{ std::data(buffer1), std::size(buffer1) }; std::pmr::polymorphic_allocator alloc1(&pool1); char buffer2[1024] = {}; // a small buffer on the stack std::pmr::monotonic_buffer_resource pool2{ std::data(buffer2), std::size(buffer2) }; std::pmr::polymorphic_allocator alloc2(&pool2); const char* long_string1 = "String too long for short string"; CHECK_FALSE(std::allocator_traits>::is_always_equal::value); CHECK_FALSE(alloc1 == alloc2); CHECK(alloc1 == alloc1); SECTION("construct string") { std::cout << "Polymorphic Allocator\n\n"; std::cout << "propagate_on_container_copy_assignment: " << std::allocator_traits>::propagate_on_container_copy_assignment::value << "\n"; std::cout << "propagate_on_container_move_assignment: " << std::allocator_traits>::propagate_on_container_move_assignment::value << "\n"; std::cout << "propagate_on_container_swap: " << std::allocator_traits>::propagate_on_container_swap::value << "\n"; pmr_json j1(long_string1, alloc1); pmr_json j2(j1, alloc2); CHECK(j1.as() == long_string1); CHECK(j2.as() == long_string1); CHECK(j1.cast().get_allocator() == alloc1); CHECK(j2.cast().get_allocator() == alloc2); CHECK_FALSE(j1.cast().get_allocator() == j2.cast().get_allocator()); } } TEST_CASE("Test polymorhic allocator") { char buffer1[1024] = {}; // a small buffer1 on the stack std::pmr::monotonic_buffer_resource pool1{ std::data(buffer1), std::size(buffer1) }; std::pmr::polymorphic_allocator alloc1(&pool1); char buffer2[1024] = {}; // a small buffer on the stack std::pmr::monotonic_buffer_resource pool2{ std::data(buffer2), std::size(buffer2) }; std::pmr::polymorphic_allocator alloc2(&pool2); const char* a_long_string = "String too long for short string"; CHECK_FALSE(std::allocator_traits>::is_always_equal::value); pmr_json an_object1(json_object_arg, alloc1); an_object1.try_emplace("true", true); an_object1.try_emplace("false", false); an_object1.try_emplace("null", null_type()); an_object1.try_emplace("Key to long for short string", a_long_string); std::pmr::string key1{"foo", alloc1}; std::pmr::string key2{"bar", alloc1}; SECTION("construct string") { pmr_json j(a_long_string, alloc1); CHECK(j.as() == a_long_string); } SECTION("try_emplace json") { pmr_json j(json_object_arg, alloc1); pmr_json an_object1_copy(an_object1); j.try_emplace(key1, pmr_json{}); j.try_emplace(std::move(key2), a_long_string); j.try_emplace("baz", an_object1); j.try_emplace("qux", std::move(an_object1_copy)); CHECK(4 == j.size()); CHECK(j.at("foo") == pmr_json{}); CHECK(j.at("bar").as_string_view() == a_long_string); CHECK(j.at("baz") == an_object1); CHECK(j.at("qux") == an_object1); } SECTION("try_emplace ojson") { pmr_ojson j(json_object_arg, alloc1); j.try_emplace(key1, pmr_ojson{}); j.try_emplace(std::move(key2), a_long_string); CHECK(2 == j.size()); CHECK(j.at("foo") == pmr_ojson{}); CHECK(j.at("bar").as_string_view() == a_long_string); } SECTION("insert_or_assign json") { pmr_json j(json_object_arg, alloc1); j.insert_or_assign("foo", pmr_json{}); j.insert_or_assign("bar", a_long_string); CHECK(2 == j.size()); CHECK(j.at("foo") == pmr_json{}); CHECK(j.at("bar").as_string_view() == a_long_string); } SECTION("insert_or_assign ojson") { pmr_ojson j(json_object_arg, alloc1); j.insert_or_assign("foo", pmr_ojson{}); j.insert_or_assign("bar", a_long_string); CHECK(2 == j.size()); CHECK(j.at("foo") == pmr_ojson{}); CHECK(j.at("bar").as_string_view() == a_long_string); } SECTION("emplace_back") { pmr_json j(json_array_arg, alloc1); j.emplace_back(1); j.emplace_back(a_long_string); CHECK(2 == j.size()); CHECK(1 == j.at(0)); CHECK(j.at(1).as() == a_long_string); } SECTION("push_back") { pmr_json j(json_array_arg, alloc1); j.push_back(1); j.push_back(a_long_string); CHECK(2 == j.size()); CHECK(1 == j.at(0)); CHECK(j.at(1).as() == a_long_string); } SECTION("insert") { pmr_json j(json_array_arg, alloc1); j.insert(j.array_range().end(), pmr_json{}); j.insert(j.array_range().end(), a_long_string); CHECK(2 == j.size()); CHECK(j[0] == pmr_json{}); CHECK(j[1].as_string_view() == a_long_string); } SECTION("parse") { std::string s = a_long_string; std::string input = "\"" + s + "\""; json_decoder decoder(alloc1); JSONCONS_TRY { json_string_reader reader(input,decoder); reader.read_next(); } JSONCONS_CATCH (const std::exception&) { } CHECK(decoder.is_valid()); auto j = decoder.get_result(); CHECK(j.as() == s); } } #endif // namespace JSONCONS_HAS_2017 jsoncons-1.3.2/test/corelib/src/read_encoded_data_tests.cpp000066400000000000000000000031111477700171100240520ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include using namespace jsoncons; template typename std::enable_if::value,std::size_t>::type read_json(Source& source, char* buffer, std::size_t capacity, unicode_traits::encoding_kind& encoding) { using value_type = typename Source::value_type; std::size_t count = 0; char* ptr = buffer; if (encoding != unicode_traits::encoding_kind::undetected) { count = source.read(buffer, capacity); auto r = unicode_traits::detect_json_encoding(buffer,capacity); encoding = r.encoding; count -= (r.ptr - buffer); ptr = r.ptr; } switch (encoding) { case unicode_traits::encoding_kind::utf8: break; case unicode_traits::encoding_kind::utf16le: break; case unicode_traits::encoding_kind::utf16be: break; case unicode_traits::encoding_kind::utf32le: break; case unicode_traits::encoding_kind::utf32be: break; } } TEST_CASE("Read utf8 encoded data") { SECTION("utf8, no bom") { std::string input = "[1,2,3]"; auto r = jsoncons::unicode_traits::detect_json_encoding(input.data(),input.size()); CHECK(r.encoding == jsoncons::unicode_traits::encoding_kind::utf8); CHECK(r.ptr == input.data()); } } jsoncons-1.3.2/test/corelib/src/scoped_allocator_adaptor_tests.cpp000066400000000000000000000106641477700171100255270ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #if defined(JSONCONS_HAS_STATEFUL_ALLOCATOR) && JSONCONS_HAS_STATEFUL_ALLOCATOR == 1 #include #include using namespace jsoncons; template using MyScopedAllocator = std::scoped_allocator_adaptor>; using cust_json = jsoncons::basic_json>; using cust_string = std::basic_string, MyScopedAllocator>; TEST_CASE("scoped allocator adaptor basic_json tests") { MyScopedAllocator alloc1(1); using cust_json = basic_json>; using cust_string = std::basic_string,MyScopedAllocator>; const char* long_string = "String too long for short string"; CHECK_FALSE(std::allocator_traits>::is_always_equal::value); SECTION("construct from string") { cust_json j(long_string, alloc1); CHECK(j.as() == long_string); } SECTION("try_emplace") { cust_json j(json_object_arg, alloc1); cust_string key1{"foo", alloc1}; cust_string key2{"bar", alloc1}; j.try_emplace(key1, cust_json{}); j.try_emplace(std::move(key2), long_string); CHECK(2 == j.size()); CHECK(j.at("foo") == cust_json{}); CHECK(j.at("bar").as_string_view() == long_string); } SECTION("insert_or_assign") { cust_json j(json_object_arg, alloc1); j.insert_or_assign("foo", cust_json{}); j.insert_or_assign("bar", long_string); CHECK(2 == j.size()); CHECK(j.at("foo") == cust_json{}); CHECK(j.at("bar").as_string_view() == long_string); } SECTION("emplace_back") { cust_json j(json_array_arg, alloc1); j.emplace_back(1); j.emplace_back(long_string); CHECK(2 == j.size()); CHECK(1 == j.at(0)); CHECK(j.at(1).as() == long_string); } SECTION("push_back") { cust_json j(json_array_arg, alloc1); j.push_back(1); j.push_back(long_string); CHECK(2 == j.size()); CHECK(1 == j.at(0)); CHECK(j.at(1).as() == long_string); } SECTION("insert") { cust_json j(json_array_arg, alloc1); j.insert(j.array_range().end(), cust_json{}); j.insert(j.array_range().end(), long_string); CHECK(2 == j.size()); CHECK(j[0] == cust_json{}); CHECK(j[1].as_string_view() == long_string); } } TEST_CASE("scoped allocator adaptor parse tests") { using cust_json = basic_json>; using cust_string = std::basic_string,MyScopedAllocator>; CHECK_FALSE(std::allocator_traits>::is_always_equal::value); MyScopedAllocator alloc1(1); MyScopedAllocator alloc2(2); cust_string data = cust_string(R"( {"foo" : [{"short" : "bar", "long" : "string to long for short string", "false" : false, "true" : true, "null" : null, "integer" : 10, "double" : 1000.1}] } )", alloc2); SECTION("parse") { json_decoder> decoder(alloc1, alloc2); JSONCONS_TRY { json_string_reader reader(data,decoder); reader.read_next(); } JSONCONS_CATCH (const std::exception& ex) { std::cout << ex.what() << "\n\n"; } CHECK(decoder.is_valid()); auto j = decoder.get_result(); CHECK(j.contains("foo")); cust_json& a = j.at("foo"); CHECK(1 == a.size()); cust_json& b = a[0]; CHECK(b.at("double").as() == Approx(1000.1).epsilon(0.001)); CHECK(b.at("integer").as() == 10); CHECK(b.at("null") == cust_json::null()); CHECK(b.at("false") == cust_json(false)); CHECK(b.at("true") == cust_json(true)); CHECK(b.at("short") == cust_json("bar", alloc1)); CHECK(b.at("long") == cust_json("string to long for short string", alloc1)); } } #endif jsoncons-1.3.2/test/corelib/src/short_string_tests.cpp000066400000000000000000000014311477700171100232150ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("test_small_string") { json s("ABCD"); CHECK(s.storage_kind() == jsoncons::json_storage_kind::short_str); CHECK(s.as() == std::string("ABCD")); json t(s); CHECK(t.storage_kind() == jsoncons::json_storage_kind::short_str); CHECK(t.as() == std::string("ABCD")); json q; q = s; CHECK(q.storage_kind() == jsoncons::json_storage_kind::short_str); CHECK(q.as() == std::string("ABCD")); } jsoncons-1.3.2/test/corelib/src/source_adaptor_tests.cpp000066400000000000000000000011501477700171100235000ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("buffer reader tests") { SECTION("test 1") { json_source_adaptor> reader{}; } } TEST_CASE("json_source_adaptor constructor tests") { SECTION("test 1") { json_source_adaptor> source{string_source()}; CHECK(source.eof()); } } jsoncons-1.3.2/test/corelib/src/source_tests.cpp000066400000000000000000000371551477700171100220040ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include TEST_CASE("basic_null_istream tests") { SECTION("test1") { jsoncons::basic_null_istream is{ jsoncons::basic_null_istream() }; } } TEST_CASE("string_source tests") { std::string data = "012345678"; jsoncons::string_source source(data); SECTION("test get and peek") { char b; auto p0 = source.peek(); CHECK_FALSE(source.eof()); CHECK(p0.value == '0'); CHECK(0 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '0'); CHECK(1 == source.position()); auto p1 = source.peek(); CHECK_FALSE(source.eof()); CHECK(p1.value == '1'); CHECK(1 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '1'); CHECK(2 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '2'); CHECK(3 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '3'); CHECK(4 == source.position()); auto p4 = source.peek(); CHECK_FALSE(source.eof()); CHECK(p4.value == '4'); CHECK(4 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '4'); CHECK(5 == source.position()); auto p5 = source.peek(); CHECK_FALSE(source.eof()); CHECK(p5.value == '5'); CHECK(5 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '5'); CHECK(6 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '6'); CHECK(7 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '7'); CHECK(8 == source.position()); CHECK(1 == source.read(&b,1)); CHECK(source.eof()); CHECK(b == '8'); CHECK(9 == source.position()); CHECK(0 == source.read(&b,1)); CHECK(source.eof()); } SECTION("read_buffer") { auto s = source.read_buffer(); CHECK(source.eof()); CHECK(9 == s.size()); CHECK(std::equal(s.begin(), s.end(), data.begin())); CHECK(9 == source.position()); } } TEST_CASE("byte_source tests") { std::string data = "012345678"; jsoncons::bytes_source source(data); SECTION("test get and peek") { uint8_t b; auto p0 = source.peek(); CHECK_FALSE(source.eof()); CHECK(p0.value == '0'); CHECK(0 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '0'); CHECK(1 == source.position()); auto p1 = source.peek(); CHECK_FALSE(source.eof()); CHECK(p1.value == '1'); CHECK(1 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '1'); CHECK(2 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '2'); CHECK(3 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '3'); CHECK(4 == source.position()); auto p4 = source.peek(); CHECK_FALSE(source.eof()); CHECK(p4.value == '4'); CHECK(4 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '4'); CHECK(5 == source.position()); auto p5 = source.peek(); CHECK_FALSE(source.eof()); CHECK(p5.value == '5'); CHECK(5 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '5'); CHECK(6 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '6'); CHECK(7 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '7'); CHECK(8 == source.position()); CHECK(1 == source.read(&b,1)); CHECK(source.eof()); CHECK(b == '8'); CHECK(9 == source.position()); CHECK(0 == source.read(&b,1)); CHECK(source.eof()); } SECTION("read_buffer") { auto s = source.read_buffer(); CHECK(source.eof()); CHECK(9 == s.size()); CHECK(std::equal(s.begin(), s.end(), data.begin())); CHECK(9 == source.position()); } } TEST_CASE("stream_source tests") { std::string data = "012345678"; std::istringstream is(data); jsoncons::stream_source source(is); SECTION("test get and peek") { char b; auto p0 = source.peek(); CHECK_FALSE(source.eof()); CHECK(p0.value == '0'); CHECK(0 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '0'); CHECK(1 == source.position()); auto p1 = source.peek(); CHECK_FALSE(source.eof()); CHECK(p1.value == '1'); CHECK(1 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '1'); CHECK(2 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '2'); CHECK(3 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '3'); CHECK(4 == source.position()); auto p4 = source.peek(); CHECK_FALSE(source.eof()); CHECK(p4.value == '4'); CHECK(4 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '4'); CHECK(5 == source.position()); auto p5 = source.peek(); CHECK_FALSE(source.eof()); CHECK(p5.value == '5'); CHECK(5 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '5'); CHECK(6 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '6'); CHECK(7 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '7'); CHECK(8 == source.position()); CHECK(1 == source.read(&b,1)); CHECK(source.eof()); CHECK(b == '8'); CHECK(9 == source.position()); CHECK(0 == source.read(&b,1)); CHECK(source.eof()); } } TEST_CASE("wide stream source tests") { std::wstring data = L"012345678"; std::wistringstream is(data); jsoncons::stream_source source(is); } TEST_CASE("binary_stream_source tests") { std::string data = "012345678"; std::istringstream is(data); jsoncons::binary_stream_source source(is,4); SECTION("get and peek") { uint8_t b; auto p0 = source.peek(); CHECK_FALSE(source.eof()); CHECK(p0.value == '0'); CHECK(0 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '0'); CHECK(1 == source.position()); auto p1 = source.peek(); CHECK_FALSE(source.eof()); CHECK(p1.value == '1'); CHECK(1 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '1'); CHECK(2 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '2'); CHECK(3 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '3'); CHECK(4 == source.position()); auto p4 = source.peek(); CHECK_FALSE(source.eof()); CHECK(p4.value == '4'); CHECK(4 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '4'); CHECK(5 == source.position()); auto p5 = source.peek(); CHECK_FALSE(source.eof()); CHECK(p5.value == '5'); CHECK(5 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '5'); CHECK(6 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '6'); CHECK(7 == source.position()); CHECK(1 == source.read(&b,1)); CHECK_FALSE(source.eof()); CHECK(b == '7'); CHECK(8 == source.position()); jsoncons::binary_stream_source source2(std::move(source)); CHECK(1 == source2.read(&b,1)); CHECK(source2.eof()); CHECK(b == '8'); CHECK(9 == source2.position()); CHECK(0 == source2.read(&b,1)); CHECK(source2.eof()); } SECTION("ignore") { source.ignore(1); CHECK_FALSE(source.eof()); CHECK(1 == source.position()); auto p1 = source.peek(); CHECK_FALSE(source.eof()); CHECK(p1.value == '1'); CHECK(1 == source.position()); source.ignore(7); CHECK_FALSE(source.eof()); CHECK(8 == source.position()); source.ignore(2); CHECK(source.eof()); CHECK(9 == source.position()); } SECTION("read 1, read1") { std::vector v(10); std::vector expected = {'0','1','2','3','4','5','6','7','8'}; std::size_t len = source.read(v.data(),1); CHECK_FALSE(source.eof()); CHECK(1 == len); CHECK(std::equal(expected.begin(),expected.begin()+1,v.begin())); CHECK(1 == source.position()); len = source.read(v.data(),1); CHECK_FALSE(source.eof()); CHECK(1 == len); CHECK(std::equal(expected.begin()+1,expected.begin()+2,v.begin())); CHECK(2 == source.position()); } SECTION("read 3, read 4, read 3") { std::vector v(10); std::vector expected = {'0','1','2','3','4','5','6','7','8'}; std::size_t len = source.read(v.data(),3); CHECK_FALSE(source.eof()); CHECK(3 == len); CHECK(std::equal(expected.begin(),expected.begin()+3,v.begin())); CHECK(3 == source.position()); len = source.read(v.data(),4); CHECK_FALSE(source.eof()); CHECK(4 == len); CHECK(std::equal(expected.begin()+3,expected.begin()+7,v.begin())); CHECK(7 == source.position()); len = source.read(v.data(),3); CHECK(source.eof()); CHECK(2 == len); CHECK(std::equal(expected.begin()+7,expected.begin()+9,v.begin())); CHECK(9 == source.position()); } SECTION("read 9") { std::vector v(10); std::vector expected = {'0','1','2','3','4','5','6','7','8'}; std::size_t len = source.read(v.data(),9); CHECK_FALSE(source.eof()); CHECK(9 == len); CHECK(std::equal(expected.begin(),expected.end(),v.begin())); CHECK(9 == source.position()); } SECTION("read 10") { std::vector v(10); std::vector expected = { '0','1','2','3','4','5','6','7','8'}; std::size_t len = source.read(v.data(), 10); CHECK(source.eof()); CHECK(9 == len); CHECK(std::equal(expected.begin(), expected.end(), v.begin())); CHECK(9 == source.position()); } SECTION("read_buffer") { auto s = source.read_buffer(); CHECK_FALSE(source.eof()); CHECK(4 == s.size()); CHECK(std::equal(s.begin(), s.end(), data.begin())); CHECK(4 == source.position()); s = source.read_buffer(); CHECK_FALSE(source.eof()); CHECK(4 == s.size()); CHECK(std::equal(s.begin(), s.end(), data.begin()+4)); CHECK(8 == source.position()); s = source.read_buffer(); CHECK(source.eof()); CHECK(1 == s.size()); CHECK(std::equal(s.begin(), s.end(), data.begin()+8)); CHECK(9 == source.position()); } } TEST_CASE("random access iterator iterator_stream source tests") { std::string data = "012345678"; jsoncons::iterator_source source(data.begin(), data.end(), 4); SECTION("read 3") { std::vector v(3); source.read(v.data(), 3); CHECK_FALSE(source.eof()); CHECK(std::equal(v.begin(), v.begin()+3, data.begin())); CHECK(3 == source.position()); } SECTION("read_buffer") { auto s = source.read_buffer(); CHECK_FALSE(source.eof()); CHECK(4 == s.size()); CHECK(std::equal(s.begin(), s.end(), data.begin())); CHECK(4 == source.position()); s = source.read_buffer(); CHECK_FALSE(source.eof()); CHECK(4 == s.size()); CHECK(std::equal(s.begin(), s.end(), data.begin()+4)); CHECK(8 == source.position()); s = source.read_buffer(); CHECK(source.eof()); CHECK(1 == s.size()); CHECK(std::equal(s.begin(), s.end(), data.begin()+8)); CHECK(9 == source.position()); } } TEST_CASE("forward iterator iterator_stream source tests") { std::string data = "012345678"; std::istringstream is(data); std::istream_iterator iter(is); jsoncons::iterator_source> source(iter, std::istream_iterator(), 4); SECTION("read 3") { std::vector v(3); source.read(v.data(), 3); CHECK_FALSE(source.eof()); CHECK(std::equal(v.begin(), v.begin()+3, data.begin())); CHECK(3 == source.position()); } SECTION("read_buffer") { auto s = source.read_buffer(); CHECK_FALSE(source.eof()); CHECK(4 == s.size()); CHECK(std::equal(s.begin(), s.end(), data.begin())); CHECK(4 == source.position()); s = source.read_buffer(); CHECK_FALSE(source.eof()); CHECK(4 == s.size()); CHECK(std::equal(s.begin(), s.end(), data.begin()+4)); CHECK(8 == source.position()); s = source.read_buffer(); CHECK(source.eof()); CHECK(1 == s.size()); CHECK(std::equal(s.begin(), s.end(), data.begin()+8)); CHECK(9 == source.position()); } } TEST_CASE("binary_iterator_stream source tests") { std::vector data = { 0,1,2,3,4,5,6,7,8 }; jsoncons::binary_iterator_source::iterator> source(data.begin(), data.end(), 4); SECTION("read 3") { std::vector v(3); source.read(v.data(), 3); CHECK_FALSE(source.eof()); CHECK(std::equal(v.begin(), v.begin()+3, data.begin())); CHECK(3 == source.position()); } SECTION("read_buffer") { auto s = source.read_buffer(); CHECK_FALSE(source.eof()); CHECK(4 == s.size()); CHECK(std::equal(s.begin(), s.end(), data.begin())); CHECK(4 == source.position()); s = source.read_buffer(); CHECK_FALSE(source.eof()); CHECK(4 == s.size()); CHECK(std::equal(s.begin(), s.end(), data.begin()+4)); CHECK(8 == source.position()); s = source.read_buffer(); CHECK(source.eof()); CHECK(1 == s.size()); CHECK(std::equal(s.begin(), s.end(), data.begin()+8)); CHECK(9 == source.position()); } } jsoncons-1.3.2/test/corelib/src/staj_iterator_tests.cpp000066400000000000000000000111451477700171100233450ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("jtaj_array_view tests") { std::string s = R"( [ { "enrollmentNo" : 100, "firstName" : "Tom", "lastName" : "Cochrane", "mark" : 55 }, { "enrollmentNo" : 101, "firstName" : "Catherine", "lastName" : "Smith", "mark" : 95 }, { "enrollmentNo" : 102, "firstName" : "William", "lastName" : "Skeleton", "mark" : 60 } ] )"; SECTION("test 1") { json_string_cursor cursor(s); auto view = staj_array(cursor); auto it = view.begin(); auto end = view.end(); CHECK_FALSE((it == end)); const auto& j1 = *it; REQUIRE(j1.is_object()); CHECK(j1["firstName"].as() == std::string("Tom")); ++it; CHECK_FALSE((it == end)); const auto& j2 = *it; CHECK(j2["firstName"].as() == std::string("Catherine")); ++it; CHECK_FALSE((it == end)); const auto& j3 = *it; CHECK(j3["firstName"].as() == std::string("William")); ++it; CHECK((it == end)); CHECK_NOTHROW(cursor.check_done()); } SECTION("filter test") { json_string_cursor cursor(s); bool author_next = false; auto filtered_c = cursor | [&](const staj_event& event, const ser_context&) -> bool { if (event.event_type() == staj_event_type::key && event.get() == "firstName") { author_next = true; return false; } if (author_next) { author_next = false; return true; } return false; }; REQUIRE(!filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::string_value); CHECK(filtered_c.current().get() == std::string("Tom")); filtered_c.next(); REQUIRE(!filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::string_value); CHECK(filtered_c.current().get() == std::string("Catherine")); filtered_c.next(); REQUIRE(!filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::string_value); CHECK(filtered_c.current().get() == std::string("William")); filtered_c.next(); REQUIRE(filtered_c.done()); } } TEST_CASE("object_iterator test") { std::string s = R"( { "enrollmentNo" : 100, "firstName" : "Tom", "lastName" : "Cochrane", "mark" : 55 } )"; SECTION("test 1") { std::istringstream is(s); json_stream_cursor cursor(is); auto view = staj_object(cursor); auto it = view.begin(); auto end = view.end(); CHECK_FALSE((it == end)); const auto& p1 = *it; CHECK(p1.second.as() == 100); ++it; CHECK_FALSE((it == end)); const auto& p2 = *it; CHECK(p2.second.as() == std::string("Tom")); ++it; CHECK_FALSE((it == end)); const auto& p3 = *it; CHECK(p3.second.as() == std::string("Cochrane")); ++it; CHECK_FALSE((it == end)); const auto& p4 = *it; CHECK(p4.second.as() == 55); ++it; CHECK((it == end)); CHECK_NOTHROW(cursor.check_done()); } SECTION("nested") { std::string str = R"({ "prop": { "nested": 123} })"; std::istringstream is(str); json_stream_cursor cursor(is); auto view = staj_object(cursor); auto it = view.begin(); auto end = view.end(); CHECK_FALSE((it == end)); //const auto& p1 = *it; //std::cout << p1.first << ": " << p1.second << "\n"; //CHECK(p1.second.as() == 100); ++it; CHECK((it == end)); CHECK_NOTHROW(cursor.check_done()); } } jsoncons-1.3.2/test/corelib/src/string_to_double_tests.cpp000066400000000000000000000025461477700171100240420ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("test_string_to_double") { std::cout << "sizeof(json): " << sizeof(json) << '\n'; const char* s1 = "0.0"; json j1 = json::parse(s1); double expected1 = 0.0; CHECK( j1.as() == expected1); const char* s2 = "0.123456789"; json j2 = json::parse(s2); double expected2 = 0.123456789; CHECK( j2.as() == expected2); const char* s3 = "123456789.123456789"; json j3 = json::parse(s3); char* end3 = nullptr; double expected3 = strtod(s3,&end3); CHECK( j3.as() == expected3); } TEST_CASE("test_exponent") { jsoncons::detail::chars_to reader; const char* begin = "1.15507e-173"; char* endptr = nullptr; const double value1 = 1.15507e-173; const double value2 = strtod(begin, &endptr ); const double value3 = reader(begin,endptr-begin); CHECK(value1 == value2); CHECK(value2 == value3); const char* s1 = "1.15507e+173"; json j1 = json::parse(s1); double expected1 = 1.15507e+173; CHECK( j1.as() == expected1); } jsoncons-1.3.2/test/corelib/src/testmain.cpp000066400000000000000000000010011477700171100210630ustar00rootroot00000000000000#define CATCH_CONFIG_MAIN #include #include TEST_CASE("configuration") { #if defined(__clang__) std::cout << "clang" << "\n"; #elif defined(__GNUC__) std::cout << "__GNUC__: " << __GNUC__ << "\n"; #if defined(__GNUC_MINOR__) std::cout << "__GNUC_MINOR__" << __GNUC_MINOR__ << "\n"; #endif #endif #if defined(JSONCONS_HAS_STD_REGEX) std::cout << "JSONCONS_HAS_STD_REGEX\n"; #endif } jsoncons-1.3.2/test/corelib/src/utility/000077500000000000000000000000001477700171100202465ustar00rootroot00000000000000jsoncons-1.3.2/test/corelib/src/utility/bigint_tests.cpp000066400000000000000000000255701477700171100234610ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" #endif #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("test_positive_bignum") { std::string expected = "18446744073709551616"; std::vector v = {1,0,0,0,0,0,0,0,0}; bigint x = bigint::from_bytes_be(1, v.data(),v.size()); std::string sx = x.to_string(); CHECK(expected == sx); bigint y(x); std::string sy = y.to_string(); CHECK(expected == sy); bigint z; z = x; std::string sz = y.to_string(); CHECK(expected == sz); SECTION("write_string_hex") { std::string exp = "10000000000000000"; std::string s; x.write_string_hex(s); CHECK(s == exp); } } TEST_CASE("bignums are equal") { std::string s = "18446744073709551616"; bigint x = bigint::from_string(s); bigint y = bigint::from_string(s); bool test = x == y; CHECK(test); } TEST_CASE("test_negative_bignum") { std::string expected = "-18446744073709551617"; std::vector b = {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; bigint x = bigint::from_bytes_be(1, b.data(),b.size()); bigint x2 = -1 - x; std::string sx = x2.to_string(); CHECK(expected == sx); bigint y(x2); std::string sy = y.to_string(); CHECK(expected == sy); bigint z; z = x2; std::string sz = z.to_string(); CHECK(expected == sz); int signum; std::vector v; x.write_bytes_be(signum, v); REQUIRE(v.size() == b.size()); for (std::size_t i = 0; i < v.size(); ++i) { REQUIRE(v[i] == b[i]); } SECTION("write_string_hex") { std::string exp = "-10000000000000001"; std::string s; x2.write_string_hex(s); //std::cout << "bigint: " << expected << ", s: " << s << "\n"; CHECK(s == exp); } } TEST_CASE("test_longlong") { long long n = (std::numeric_limits::max)(); bigint val(n); //std::cout << "long long " << n << " == " << val << '\n'; //std::cout << val.to_string(16) << '\n'; } TEST_CASE("test_bignum2") { std::string v = "10000000000000000"; bigint val = bigint::from_string(v.data()); //std::cout << val << '\n'; } TEST_CASE("test_logical_operations") { bigint x = bigint::from_string( "888888888888888888" ); bigint y = bigint::from_string( "888888888888888888" ); bigint z = x & y; bool test = z == x; CHECK(test); } TEST_CASE("test_addition") { bigint x = bigint::from_string( "4444444444444444444444444444444" ); bigint y = bigint::from_string( "4444444444444444444444444444444" ); bigint a = bigint::from_string( "8888888888888888888888888888888" ); bigint z = x + y; bool test = z == a; CHECK(test); } TEST_CASE("test_multiplication") { bigint x = bigint::from_string( "4444444444444444444444444444444" ); bigint a = bigint::from_string( "8888888888888888888888888888888" ); bigint z = 2*x; bool test = z == a; CHECK(test); z = x*2; test = z == a; CHECK(test); } TEST_CASE("test_conversion_0") { bigint x; json j(x); bigint y = j.as(); CHECK(bool(x == y)); std::string s = y.to_string(); CHECK(s == "0"); } TEST_CASE("test_traits1") { std::vector data = {0x01,0x00}; bigint x = bigint::from_bytes_be(1, data.data(), data.size()); json j(x); bigint y = j.as(); CHECK(bool(x == y)); std::string s = y.to_string(); CHECK(s == "256"); } TEST_CASE("test_traits2") { std::vector data = {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; bigint x = bigint::from_bytes_be(1, data.data(), data.size()); json j(x); bigint y = j.as(); CHECK(bool(x == y)); std::string s = y.to_string(); CHECK(s == "18446744073709551616"); } TEST_CASE("test_traits3") { std::vector data = {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; bigint x = bigint::from_bytes_be(1, data.data(), data.size()); x = -1 - x; int signum; std::vector v; x.write_bytes_be(signum,v); REQUIRE(signum == -1); //for (auto c : v) //{ // //std::cout << std::hex << (int)c; //} //std::cout << '\n'; json j(x); bigint y = j.as(); CHECK(bool(x == y)); std::string s = y.to_string(); CHECK(s == "-18446744073709551617"); } TEST_CASE("test shift left") { SECTION("n << 1") { bigint n = bigint::from_string("1"); bigint x = n << 1; std::string s = x.to_string(); CHECK(s == "2"); } SECTION("n << 100") { bigint n(1); bigint x = n << 100; std::string s = x.to_string(); CHECK(s == "1267650600228229401496703205376"); } SECTION("n << 100, += 1") { bigint n(1); bigint x = n << 100; x += 1; std::string s = x.to_string(); CHECK(s == "1267650600228229401496703205377"); } } TEST_CASE("times 10") { SECTION("1") { bigint n = bigint::from_string("1234"); bigint m = n * 10; std::string s = m.to_string(); CHECK(s == "12340"); } SECTION("31") { std::string expected("1234"); bigint n = bigint::from_string(expected); for (std::size_t i = 0; i < 31; ++i) { n *= (uint64_t)10; expected.push_back('0'); } std::string s = n.to_string(); CHECK(expected == s); //std::cout << "x31: " << s << "\n"; } SECTION("32") { std::string expected("1234"); bigint n = bigint::from_string(expected); for (std::size_t i = 0; i < 32; ++i) { n *= (uint64_t)10; expected.push_back('0'); } std::string s = n.to_string(); CHECK(expected == s); //std::cout << "x31: " << s << "\n"; } } TEST_CASE("bigint div") { #if defined(_MSC_VER) && _MSC_VER >= 1910 SECTION("bigint") { bigint big_pos = bigint::from_string("18364494661702398480"); bigint small_pos = bigint::from_string("65535"); bigint res_pos = bigint::from_string("280224226164681"); bigint big_neg = -big_pos; bigint small_neg = -small_pos; bigint res_neg = -res_pos; CHECK((big_neg / big_neg) == bigint(1)); CHECK((big_neg / small_neg) == res_pos); CHECK((big_neg / small_pos) == res_neg); CHECK((big_neg / big_pos) == bigint(-1)); CHECK((small_neg / big_neg) == bigint(0)); CHECK((small_neg / small_neg) == bigint(1)); CHECK((small_neg / small_pos) == bigint(-1)); CHECK((small_neg / big_pos) == bigint(0)); CHECK((small_pos / big_neg) == bigint(0)); CHECK((small_pos / small_neg) == bigint(-1)); CHECK((small_pos / small_pos) == bigint(1)); CHECK((small_pos / big_pos) == bigint(0)); CHECK((big_pos / big_neg) == bigint(-1)); CHECK((big_pos / small_neg) == res_neg); CHECK((big_pos / small_pos) == res_pos); CHECK((big_pos / big_pos) == bigint(1)); } #endif } // Source: https://github.com/justmoon/node-bignum/blob/master/test/big.js TEST_CASE("bigint operations") { SECTION("plus") { bigint a = bigint::from_string("20178175244496647895629245678926563358862835685868092718528786189298896755892724096350318132354654969715294305656279188466948605121492948268400884893722767401972695174353441"); bigint b = bigint::from_string("93976986297275963857794534313022836860642008364607162222395304627737845003599751108876721426146679370149373711095582235633733294240624814097369771481147215472578762824607080"); bigint c = a + b; bigint expected = bigint::from_string("114155161541772611753423779991949400219504844050475254940924090817036741759492475205227039558501334339864668016751861424100681899362117762365770656374869982874551457998960521"); CHECK(expected == (c)); } SECTION("minus") { bigint a = bigint::from_string("63584976221895260406245934266037944699776129516216688813405106853198139417759498415735161100030933326522675347686646219695144553808051168706779408804756208386011014197185296"); bigint b = bigint::from_string("75761734353628069683913529566109295493116360791340046058510920764479664838827482335858563500856417188227416490721063436557647698896399869016678013515043471880323279258685478"); bigint c = a - b; bigint expected = bigint::from_string("-12176758131732809277667595300071350793340231275123357245105813911281525421067983920123402400825483861704741143034417216862503145088348700309898604710287263494312265061500182"); CHECK(expected == (c)); } SECTION("mult") { bigint a = bigint::from_string("43359329001059048967113581928625959342654930666632400867978208429224464941890190751598229305718587280094852374898291386268967561418738958337632249177044975686477011571044266"); bigint b = bigint::from_string("1277902648419017187919156692641295109476255233737630537760832794503886212911067061184379695097643279217271150419129022856601771338794256383410400076210073482253089544155377"); bigint c = a * b; bigint expected = bigint::from_string("55409001364124857587521411422210474638575227552776047085010157327559891765943209923363557763419730972781537530948429788352886919273214132899346769031695550850320602049507618052164677667378189154076988316301237199538599598044906690917691500474146296751848053320011822980888915807952984822080201739642211593661864443811046346990267512628848918282"); CHECK(expected == (c)); } SECTION("div") { bigint a = bigint::from_string("43359329001059048967113581928625959342654930666632400867978208429224464941890190751598229305718587280094852374898291386268967561418738958337632249177044975686477011571044266"); bigint b = bigint::from_string("1277902648419017187919156692641295109476255233737630537760832794503886212911067061184379695097643279217271150419129022856601771338794256383410400076210073482253089544155377"); bigint c = a / b; bigint expected = bigint::from_string("33"); CHECK(expected == (c)); } SECTION("&=") { bigint a{0}; bigint b = bigint::from_string("1277902648419017187919156692641295109476255233737630537760832794503886212911067061184379695097643279217271150419129022856601771338794256383410400076210073482253089544155377"); b &= a; CHECK(a == b); } SECTION("|=") { bigint a{0}; bigint b = bigint::from_string("1277902648419017187919156692641295109476255233737630537760832794503886212911067061184379695097643279217271150419129022856601771338794256383410400076210073482253089544155377"); bigint expected = b; b |= a; CHECK(expected == b); } } jsoncons-1.3.2/test/corelib/src/utility/byte_string_tests.cpp000066400000000000000000000161511477700171100245310ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #include using namespace jsoncons; // https://tools.ietf.org/html/rfc4648#section-4 test vectors template void check_encode_base64(const std::vector& input, const std::basic_string& expected) { std::basic_string result; encode_base64(input.begin(),input.end(),result); REQUIRE(result.size() == expected.size()); for (std::size_t i = 0; i < result.size(); ++i) { CHECK(result[i] == expected[i]); } std::vector output; decode_base64(result.begin(), result.end(), output); REQUIRE(output.size() == input.size()); for (std::size_t i = 0; i < output.size(); ++i) { CHECK(output[i] == input[i]); } } template void check_encode_base64url(const std::vector& input, const std::basic_string& expected) { std::basic_string result; encode_base64url(input.begin(),input.end(),result); REQUIRE(result.size() == expected.size()); for (std::size_t i = 0; i < result.size(); ++i) { CHECK(result[i] == expected[i]); } std::vector output; decode_base64url(result.begin(), result.end(), output); REQUIRE(output.size() == input.size()); for (std::size_t i = 0; i < output.size(); ++i) { CHECK(output[i] == input[i]); } } template void check_encode_base16(const std::vector& input, const std::basic_string& expected) { std::basic_string result; encode_base16(input.begin(),input.end(), result); REQUIRE(result.size() == expected.size()); for (std::size_t i = 0; i < result.size(); ++i) { CHECK(result[i] == expected[i]); } std::vector output; auto res = decode_base16(result.begin(), result.end(), output); REQUIRE(res.ec == conv_errc::success); REQUIRE(output.size() == input.size()); for (std::size_t i = 0; i < output.size(); ++i) { CHECK(output[i] == input[i]); } } TEST_CASE("test_base64_conversion") { SECTION("char") { check_encode_base64({}, ""); check_encode_base64({'f'}, "Zg=="); check_encode_base64({'f','o'}, "Zm8="); check_encode_base64({'f','o','o'}, "Zm9v"); check_encode_base64({'f','o','o','b'}, "Zm9vYg=="); check_encode_base64({'f','o','o','b','a'}, "Zm9vYmE="); check_encode_base64({'f','o','o','b','a','r'}, "Zm9vYmFy"); } SECTION("wchar_t") { check_encode_base64({}, L""); check_encode_base64({'f'}, L"Zg=="); check_encode_base64({'f','o'}, L"Zm8="); check_encode_base64({'f','o','o'}, L"Zm9v"); check_encode_base64({'f','o','o','b'}, L"Zm9vYg=="); check_encode_base64({'f','o','o','b','a'}, L"Zm9vYmE="); check_encode_base64({'f','o','o','b','a','r'}, L"Zm9vYmFy"); } } TEST_CASE("test_base64url_conversion") { SECTION("char") { check_encode_base64url({}, ""); check_encode_base64url({'f'}, "Zg"); check_encode_base64url({'f','o'}, "Zm8"); check_encode_base64url({'f','o','o'}, "Zm9v"); check_encode_base64url({'f','o','o','b'}, "Zm9vYg"); check_encode_base64url({'f','o','o','b','a'}, "Zm9vYmE"); check_encode_base64url({'f','o','o','b','a','r'}, "Zm9vYmFy"); } SECTION("wchar_t") { check_encode_base64url({}, L""); check_encode_base64url({'f'}, L"Zg"); check_encode_base64url({'f','o'}, L"Zm8"); check_encode_base64url({'f','o','o'}, L"Zm9v"); check_encode_base64url({'f','o','o','b'}, L"Zm9vYg"); check_encode_base64url({'f','o','o','b','a'}, L"Zm9vYmE"); check_encode_base64url({'f','o','o','b','a','r'}, L"Zm9vYmFy"); } } TEST_CASE("test_base16_conversion") { SECTION ("string") { check_encode_base16({}, ""); check_encode_base16({'f'}, "66"); check_encode_base16({'f','o'}, "666F"); check_encode_base16({'f','o','o'}, "666F6F"); check_encode_base16({'f','o','o','b'}, "666F6F62"); check_encode_base16({'f','o','o','b','a'}, "666F6F6261"); check_encode_base16({'f','o','o','b','a','r'}, "666F6F626172"); } SECTION ("wstring") { check_encode_base16({}, L""); check_encode_base16({'f'}, L"66"); check_encode_base16({'f','o'}, L"666F"); check_encode_base16({'f','o','o'}, L"666F6F"); check_encode_base16({'f','o','o','b'}, L"666F6F62"); check_encode_base16({'f','o','o','b','a'}, L"666F6F6261"); check_encode_base16({'f','o','o','b','a','r'}, L"666F6F626172"); } } TEST_CASE("byte_string_view constructors") { SECTION("test 1") { std::vector v = {'f','o','o','b','a','r'}; byte_string_view bstr(v); CHECK(bstr[0] == 'f'); CHECK(bstr[1] == 'o'); CHECK(bstr[2] == 'o'); CHECK(bstr[3] == 'b'); CHECK(bstr[4] == 'a'); CHECK(bstr[5] == 'r'); byte_string_view copied(bstr); CHECK(copied == bstr); byte_string_view moved(std::move(bstr)); CHECK(bstr.data() == nullptr); CHECK(0 == bstr.size()); REQUIRE(6 == moved.size()); CHECK(moved[0] == 'f'); CHECK(moved[1] == 'o'); CHECK(moved[2] == 'o'); CHECK(moved[3] == 'b'); CHECK(moved[4] == 'a'); CHECK(moved[5] == 'r'); } } TEST_CASE("byte_string mutators") { SECTION("append") { std::vector u = {'b','a','z'}; std::vector v = {'f','o','o','b','a','r'}; byte_string bstr(u.data(),3); bstr.append(v.data(), 6); CHECK(bstr[0] == 'b'); CHECK(bstr[1] == 'a'); CHECK(bstr[2] == 'z'); CHECK(bstr[3] == 'f'); CHECK(bstr[4] == 'o'); CHECK(bstr[5] == 'o'); CHECK(bstr[6] == 'b'); CHECK(bstr[7] == 'a'); CHECK(bstr[8] == 'r'); } SECTION("assign") { std::vector v = {'f','o','o','b','a','r'}; byte_string bstr; bstr.assign(v.data(), 6); CHECK(bstr[0] == 'f'); CHECK(bstr[1] == 'o'); CHECK(bstr[2] == 'o'); CHECK(bstr[3] == 'b'); CHECK(bstr[4] == 'a'); CHECK(bstr[5] == 'r'); } } TEST_CASE("byte_string_view iterators") { SECTION("begin/end") { std::vector v = {'f','o','o'}; byte_string_view bstr(v); auto it = bstr.begin(); REQUIRE(it != bstr.end()); CHECK(*it++ == 'f'); REQUIRE(it != bstr.end()); CHECK(*it++ == 'o'); REQUIRE(it != bstr.end()); CHECK(*it++ == 'o'); CHECK(it == bstr.end()); } } jsoncons-1.3.2/test/corelib/src/utility/extension_traits_tests.cpp000066400000000000000000000041111477700171100255730ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #if defined(JSONCONS_HAS_POLYMORPHIC_ALLOCATOR) && JSONCONS_HAS_POLYMORPHIC_ALLOCATOR == 1 #include #endif namespace extension_traits = jsoncons::extension_traits; TEST_CASE("extension_traits tests") { SECTION("is_propagating_allocator") { CHECK_FALSE(jsoncons::extension_traits::is_propagating_allocator>::value); #if defined(JSONCONS_HAS_POLYMORPHIC_ALLOCATOR) && JSONCONS_HAS_POLYMORPHIC_ALLOCATOR == 1 CHECK(jsoncons::extension_traits::is_propagating_allocator>::value); #endif } } #if defined(JSONCONS_HAS_STATEFUL_ALLOCATOR) && JSONCONS_HAS_STATEFUL_ALLOCATOR == 1 #include #include template using MyScopedAllocator = std::scoped_allocator_adaptor>; TEST_CASE("extension_traits tests is_propagating_allocator") { SECTION("is_propagating_allocator") { CHECK_FALSE(jsoncons::extension_traits::is_propagating_allocator>::value); CHECK(jsoncons::extension_traits::is_propagating_allocator>::value); } } #endif TEST_CASE("extension_traits function object tests") { SECTION("is_unary_function_object") { CHECK_FALSE(extension_traits::is_unary_function_object::value); } SECTION("is_unary_function_object_exact") { CHECK_FALSE(extension_traits::is_unary_function_object_exact::value); } SECTION("is_binary_function_object") { CHECK_FALSE(extension_traits::is_binary_function_object::value); } SECTION("is_unary_function_object_exact") { CHECK_FALSE(extension_traits::is_binary_function_object_exact::value); } } jsoncons-1.3.2/test/corelib/src/utility/heap_string_tests.cpp000066400000000000000000000034671477700171100245110ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("heap_string test") { using heap_string_factory_type = jsoncons::utility::heap_string_factory>; using pointer = typename heap_string_factory_type::pointer; std::string s("Hello World"); pointer ptr = heap_string_factory_type::create(s.data(), s.length(), null_type(), std::allocator()); CHECK(s == ptr->c_str()); CHECK(s.length() == ptr->length_); heap_string_factory_type::destroy(ptr); } #if defined(JSONCONS_HAS_POLYMORPHIC_ALLOCATOR) && JSONCONS_HAS_POLYMORPHIC_ALLOCATOR == 1 #include TEST_CASE("heap_string with polymorphic allocator test") { using heap_string_factory_type = jsoncons::utility::heap_string_factory>; using pointer = typename heap_string_factory_type::pointer; char buffer[1024] = {}; // a small buffer on the stack std::pmr::monotonic_buffer_resource pool1{ std::data(buffer), std::size(buffer) }; std::pmr::polymorphic_allocator alloc(&pool1); std::string s1("Hello World 1"); pointer ptr1 = heap_string_factory_type::create(s1.data(), s1.length(), null_type(), alloc); CHECK(s1 == ptr1->c_str()); CHECK(s1.length() == ptr1->length_); std::string s2("Hello 2"); pointer ptr2 = heap_string_factory_type::create(s2.data(), s2.length(), null_type(), alloc); CHECK(s2 == ptr2->c_str()); CHECK(s2.length() == ptr2->length_); heap_string_factory_type::destroy(ptr1); heap_string_factory_type::destroy(ptr2); } #endif jsoncons-1.3.2/test/corelib/src/utility/unicode_conv_tests.cpp000066400000000000000000000024601477700171100246510ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include using namespace jsoncons; #if 0 BOOST_AUTO_TEST_CASE( test_surrogate_pair ) { std::string input = "[\"\\u8A73\\u7D30\\u95B2\\u89A7\\uD800\\uDC01\\u4E00\"]"; json value = json::parse(input); auto options = json_options{} .escape_all_non_ascii(true); std::string output; value.dump(output,options); CHECK(input == output); } TEST_CASE("test_wide_surrogate_pair") { std::wstring input = L"[\"\\u8A73\\u7D30\\u95B2\\u89A7\\uD800\\uDC01\\u4E00\"]"; wjson value = wjson::parse(input); auto options = wjson_options{} .escape_all_non_ascii(true); std::wstring output; value.dump(output,options); CHECK(input == output); } BOOST_AUTO_TEST_CASE( test1 ) { std::istringstream is("{\"unicode_string_1\":\"\\uD800\\uDC00\"}"); json root = json::parse(is); CHECK(root.is_object()); CHECK(root.is_object()); root["double_1"] = 10.0; json double_1 = root["double_1"]; BOOST_CHECK_CLOSE(double_1.as(), 10.0, 0.000001); BOOST_CHECK_CLOSE(double_1.as(), 10.0, 0.000001); json copy(root); } #endif jsoncons-1.3.2/test/corelib/src/utility/uri_tests.cpp000066400000000000000000000611201477700171100227730ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include TEST_CASE("uri constructor tests") { SECTION("from parts") { std::string scheme = "https"; std::string userinfo = "!#$&'()*+,/:;=?@[]"; std::string host = "www.example.com"; std::string port = "10"; std::string path = "!#$&'()*+,/:;=?@[]"; std::string query = "!#$&'()*+,/:;=?@[]"; std::string fragment = "!#$&'()*+,/:;=?@[]"; jsoncons::uri uri{scheme, userinfo, host, port, path, query, fragment }; CHECK("!%23$&'()*+,%2F:;=%3F%40%5B%5D" == uri.encoded_userinfo()); CHECK("www.example.com" == uri.host()); CHECK("10" == uri.port()); CHECK("/!%23$&'()*+,/:;=%3F@%5B%5D" == uri.encoded_path()); CHECK("!%23$&'()*+,/:;=?@[]" == uri.encoded_query()); CHECK("!%23$&'()*+,/:;=?@[]" == uri.encoded_fragment()); //std::cout << uri << "\n"; } } TEST_CASE("uri tests (https://en.wikipedia.org/wiki/Uniform_Resource_Identifier)") { SECTION("https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top") { std::string s = "https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top"; jsoncons::uri uri(s); //std::cout << uri.string() << "\n"; CHECK(uri.scheme() == jsoncons::string_view("https")); CHECK(uri.encoded_authority() == jsoncons::string_view("john.doe@www.example.com:123")); CHECK(uri.userinfo() == jsoncons::string_view("john.doe")); CHECK(uri.host() == jsoncons::string_view("www.example.com")); CHECK(uri.port() == jsoncons::string_view("123")); CHECK(uri.path() == jsoncons::string_view("/forum/questions/")); CHECK(uri.encoded_query() == jsoncons::string_view("tag=networking&order=newest")); CHECK(uri.encoded_fragment() == jsoncons::string_view("top")); CHECK(uri.base().string() == "https://john.doe@www.example.com:123/forum/questions/"); CHECK(uri.is_absolute()); } SECTION("ldap://[2001:db8::7]/c=GB?objectClass?one") { std::string s = "ldap://[2001:db8::7]/c=GB?objectClass?one"; jsoncons::uri uri(s); CHECK(uri.scheme() == jsoncons::string_view("ldap")); CHECK(uri.encoded_authority() == jsoncons::string_view("2001:db8::7")); CHECK(uri.userinfo() == jsoncons::string_view("")); CHECK(uri.host() == jsoncons::string_view("2001:db8::7")); CHECK(uri.port() == jsoncons::string_view("")); CHECK(uri.encoded_path() == jsoncons::string_view("/c=GB")); CHECK(uri.encoded_query() == jsoncons::string_view("objectClass?one")); CHECK(uri.encoded_fragment() == jsoncons::string_view("")); CHECK(uri.is_absolute()); } SECTION("mailto:John.Doe@example.com") { std::string s = "mailto:John.Doe@example.com"; jsoncons::uri uri(s); CHECK(uri.scheme() == jsoncons::string_view("mailto")); CHECK(uri.encoded_authority() == jsoncons::string_view("")); CHECK(uri.userinfo() == jsoncons::string_view("")); CHECK(uri.host() == jsoncons::string_view("")); CHECK(uri.port() == jsoncons::string_view("")); CHECK(uri.encoded_path() == jsoncons::string_view("John.Doe@example.com")); CHECK(uri.encoded_query() == jsoncons::string_view("")); CHECK(uri.encoded_fragment() == jsoncons::string_view("")); CHECK(uri.is_absolute()); } SECTION("news:comp.infosystems.www.servers.unix") { std::string s = "news:comp.infosystems.www.servers.unix"; jsoncons::uri uri(s); CHECK(uri.scheme() == jsoncons::string_view("news")); CHECK(uri.encoded_authority() == jsoncons::string_view("")); CHECK(uri.userinfo() == jsoncons::string_view("")); CHECK(uri.host() == jsoncons::string_view("")); CHECK(uri.port() == jsoncons::string_view("")); CHECK(uri.encoded_path() == jsoncons::string_view("comp.infosystems.www.servers.unix")); CHECK(uri.encoded_query() == jsoncons::string_view("")); CHECK(uri.encoded_fragment() == jsoncons::string_view("")); CHECK(uri.is_absolute()); } SECTION("tel:+1-816-555-1212") { std::string s = "tel:+1-816-555-1212"; jsoncons::uri uri(s); CHECK(uri.scheme() == jsoncons::string_view("tel")); CHECK(uri.encoded_authority() == jsoncons::string_view("")); CHECK(uri.userinfo() == jsoncons::string_view("")); CHECK(uri.host() == jsoncons::string_view("")); CHECK(uri.port() == jsoncons::string_view("")); CHECK(uri.encoded_path() == jsoncons::string_view("+1-816-555-1212")); CHECK(uri.encoded_query() == jsoncons::string_view("")); CHECK(uri.encoded_fragment() == jsoncons::string_view("")); CHECK(uri.is_absolute()); } SECTION("telnet://192.0.2.16:80/") { std::string s = "telnet://192.0.2.16:80/"; jsoncons::uri uri(s); CHECK(uri.scheme() == jsoncons::string_view("telnet")); CHECK(uri.encoded_authority() == jsoncons::string_view("192.0.2.16:80")); CHECK(uri.userinfo() == jsoncons::string_view("")); CHECK(uri.host() == jsoncons::string_view("192.0.2.16")); CHECK(uri.port() == jsoncons::string_view("80")); CHECK(uri.encoded_path() == jsoncons::string_view("/")); CHECK(uri.encoded_query() == jsoncons::string_view("")); CHECK(uri.encoded_fragment() == jsoncons::string_view("")); CHECK(uri.is_absolute()); } SECTION("urn:oasis:names:specification:docbook:dtd:xml:4.1.2") { std::string s = "urn:oasis:names:specification:docbook:dtd:xml:4.1.2"; jsoncons::uri uri(s); CHECK(uri.scheme() == jsoncons::string_view("urn")); CHECK(uri.encoded_authority() == jsoncons::string_view("")); CHECK(uri.userinfo() == jsoncons::string_view("")); CHECK(uri.host() == jsoncons::string_view("")); CHECK(uri.port() == jsoncons::string_view("")); CHECK(uri.encoded_path() == jsoncons::string_view("oasis:names:specification:docbook:dtd:xml:4.1.2")); CHECK(uri.encoded_query() == jsoncons::string_view("")); CHECK(uri.encoded_fragment() == jsoncons::string_view("")); CHECK(uri.is_absolute()); } SECTION("urn:example:foo-bar-baz-qux?+CCResolve:cc=uk") { std::string s = "urn:example:foo-bar-baz-qux?+CCResolve:cc=uk"; jsoncons::uri uri(s); CHECK(uri.scheme() == jsoncons::string_view("urn")); CHECK(uri.encoded_authority() == jsoncons::string_view("")); CHECK(uri.userinfo() == jsoncons::string_view("")); CHECK(uri.host() == jsoncons::string_view("")); CHECK(uri.port() == jsoncons::string_view("")); CHECK(uri.encoded_path() == jsoncons::string_view("example:foo-bar-baz-qux")); CHECK(uri.encoded_query() == jsoncons::string_view("+CCResolve:cc=uk")); CHECK(uri.encoded_fragment() == jsoncons::string_view("")); CHECK(uri.is_absolute()); } } TEST_CASE("uri fragment tests") { SECTION("#/definitions/nonNegativeInteger") { std::string s = "#/definitions/nonNegativeInteger"; jsoncons::uri uri(s); CHECK(uri.scheme().empty()); CHECK(uri.encoded_authority().empty()); CHECK(uri.userinfo().empty()); CHECK(uri.host().empty()); CHECK(uri.port().empty()); CHECK(uri.encoded_path().empty()); CHECK(uri.encoded_query().empty()); CHECK(uri.encoded_fragment() == jsoncons::string_view("/definitions/nonNegativeInteger")); CHECK(!uri.is_absolute()); } } TEST_CASE("uri base tests") { SECTION("http://json-schema.org/draft-07/schema#") { std::string s = "http://json-schema.org/draft-07/schema#"; jsoncons::uri uri(s); CHECK(uri.scheme() == jsoncons::string_view("http")); CHECK(uri.encoded_authority() == jsoncons::string_view("json-schema.org")); CHECK(uri.userinfo().empty()); CHECK(uri.host() == jsoncons::string_view("json-schema.org")); CHECK(uri.port().empty()); CHECK(uri.encoded_path() == jsoncons::string_view("/draft-07/schema")); CHECK(uri.encoded_query().empty()); CHECK(uri.encoded_fragment().empty()); CHECK(uri.is_absolute()); } SECTION("folder/") { std::string s = "folder/"; jsoncons::uri uri(s); CHECK(uri.scheme().empty()); CHECK(uri.encoded_authority().empty()); CHECK(uri.userinfo().empty()); CHECK(uri.host().empty()); CHECK(uri.port().empty()); CHECK(uri.encoded_path() == jsoncons::string_view("folder/")); CHECK(uri.encoded_query().empty()); CHECK(uri.encoded_fragment().empty()); CHECK(!uri.is_absolute()); } SECTION("name.json#/definitions/orNull") { std::string s = "name.json#/definitions/orNull"; jsoncons::uri uri(s); CHECK(uri.scheme().empty()); CHECK(uri.encoded_authority().empty()); CHECK(uri.userinfo().empty()); CHECK(uri.host().empty()); CHECK(uri.port().empty()); CHECK(uri.encoded_path() == jsoncons::string_view("name.json")); CHECK(uri.encoded_query().empty()); CHECK(uri.encoded_fragment() == jsoncons::string_view("/definitions/orNull")); CHECK(!uri.is_absolute()); } } TEST_CASE("uri resolve tests") { /*SECTION("empty base") { jsoncons::uri base{ "" }; jsoncons::uri rel{"dir1/other.schema.json"}; jsoncons::uri uri = rel.resolve(base); CHECK(uri.base().string() == "dir1/other.schema.json"); CHECK(uri.path() == "dir1/other.schema.json"); }*/ SECTION("base has no authority and no path") { jsoncons::uri base{ "https" }; jsoncons::uri rel{ "dir1/other.schema.json" }; jsoncons::uri uri = base.resolve(rel); CHECK(uri.base().string() == "dir1/other.schema.json"); CHECK(uri.path() == "dir1/other.schema.json"); } SECTION("base has authority and path") { jsoncons::uri base{ "https://root" }; jsoncons::uri rel{"dir1/other.schema.json"}; jsoncons::uri uri = base.resolve(rel); CHECK(uri.base().string() == "https://root/dir1/other.schema.json"); CHECK(uri.path() == "/dir1/other.schema.json"); } SECTION("folder/") { jsoncons::uri base_uri("http://localhost:1234/scope_change_defs2.json"); jsoncons::uri relative_uri("folder/"); jsoncons::uri uri = base_uri.resolve(relative_uri); CHECK(uri.scheme() == jsoncons::string_view("http")); CHECK(uri.encoded_authority() == jsoncons::string_view("localhost:1234")); CHECK(uri.userinfo().empty()); CHECK(uri.host() == jsoncons::string_view("localhost")); CHECK(uri.port() == jsoncons::string_view("1234")); CHECK(uri.encoded_path() == jsoncons::string_view("/folder/")); CHECK(uri.encoded_query().empty()); CHECK(uri.encoded_fragment().empty()); CHECK(uri.is_absolute()); } SECTION("folderInteger.json") { jsoncons::uri base_uri("http://localhost:1234/folder/"); jsoncons::uri relative_uri("folderInteger.json"); jsoncons::uri uri = base_uri.resolve(relative_uri); CHECK(uri.scheme() == jsoncons::string_view("http")); CHECK(uri.encoded_authority() == jsoncons::string_view("localhost:1234")); CHECK(uri.userinfo().empty()); CHECK(uri.host() == jsoncons::string_view("localhost")); CHECK(uri.port() == jsoncons::string_view("1234")); CHECK(uri.encoded_path() == jsoncons::string_view("/folder/folderInteger.json")); CHECK(uri.encoded_query().empty()); CHECK(uri.encoded_fragment().empty()); CHECK(uri.is_absolute()); } } TEST_CASE("uri part decode tests") { SECTION("test 1") { std::string raw = "%7e"; std::string expected = "~"; std::string decoded = jsoncons::uri::decode_part(raw); CHECK(expected == decoded); } SECTION("test 2") { std::string raw = "%25"; std::string expected = "%"; std::string decoded = jsoncons::uri::decode_part(raw); CHECK(expected == decoded); } SECTION("test 3") { std::string raw = "foo%25bar%7ebaz"; std::string expected = "foo%bar~baz"; std::string decoded = jsoncons::uri::decode_part(raw); CHECK(expected == decoded); } } TEST_CASE("uri part encode tests") { SECTION("test 1") { std::string part = "/@_-!.~'()*azAZ09,;:$&+=%3F%ae"; std::string expected = part; std::string encoded; jsoncons::uri::encode_path(part, encoded); CHECK(expected == encoded); } SECTION("test 2") { std::string part = "%?/[]@,;:$&+="; std::string expected = "%25%3F/%5B%5D@,;:$&+="; std::string encoded; jsoncons::uri::encode_path(part, encoded); CHECK(expected == encoded); } } TEST_CASE("uri part encode illegal characters tests") { SECTION("test 1") { std::string part = "_-!.~'()*azAZ09?/[]@,;:$&+=%3F%ae"; std::string expected = part; std::string encoded; jsoncons::uri::encode_illegal_characters(part, encoded); CHECK(expected == encoded); } } TEST_CASE("uri constructors") { SECTION("test 1") { jsoncons::uri x{"http://localhost:4242/draft2019-09/recursiveRef6/base.json"}; jsoncons::uri y{ x, jsoncons::uri_fragment_part, "/anyOf" }; jsoncons::uri expected{"http://localhost:4242/draft2019-09/recursiveRef6/base.json#/anyOf"}; CHECK(expected == y); } } TEST_CASE("uri parsing tests") { SECTION("an invalid URI with spaces") { std::string str = "http://shouldfail.com"; std::error_code ec; jsoncons::uri id = jsoncons::uri::parse(str, ec); /*std::cout << "authority: [" << id.encoded_authority() << "]\n"; std::cout << "host: [" << id.host() << "]\n"; std::cout << "port: [" << id.port() << "]\n"; std::cout << "path: [" << id.encoded_path() << "]\n"; */ //CHECK(ec); } } TEST_CASE("cpp-netlib uri tests") { SECTION("test_empty_path") { std::error_code ec; jsoncons::uri uri = jsoncons::uri::parse("http://123.34.23.56", ec); REQUIRE_FALSE(ec); CHECK(uri.encoded_path().empty()); } SECTION("test_empty_path_with_query") { std::error_code ec; jsoncons::uri uri = jsoncons::uri::parse("http://123.34.23.56?query", ec); REQUIRE_FALSE(ec); CHECK(uri.encoded_path().empty()); } SECTION("test_empty_path_with_fragment") { std::error_code ec; jsoncons::uri uri = jsoncons::uri::parse("http://123.34.23.56#fragment", ec); REQUIRE_FALSE(ec); CHECK(uri.encoded_path().empty()); } SECTION("test_single_slash") { std::error_code ec; jsoncons::uri uri = jsoncons::uri::parse("http://123.34.23.56/", ec); REQUIRE_FALSE(ec); CHECK("/" == uri.encoded_path()); } SECTION("test_single_slash_with_query") { std::error_code ec; jsoncons::uri uri = jsoncons::uri::parse("http://123.34.23.56/?query", ec); REQUIRE_FALSE(ec); CHECK("/" == uri.encoded_path()); } SECTION("test_single_slash_with_fragment") { std::error_code ec; jsoncons::uri uri = jsoncons::uri::parse("http://123.34.23.56/#fragment", ec); REQUIRE_FALSE(ec); CHECK("/" == uri.encoded_path()); } SECTION("test_double_slash_empty_path_empty_everything") { std::error_code ec; jsoncons::uri uri = jsoncons::uri::parse("file://", ec); REQUIRE(ec == jsoncons::uri_errc::invalid_uri); CHECK(uri.encoded_path().empty()); } SECTION("test_triple_slash_empty_everything") { std::error_code ec; jsoncons::uri uri = jsoncons::uri::parse("file:///", ec); REQUIRE_FALSE(ec); CHECK("/" == uri.encoded_path()); } SECTION("test_triple_slash_with_path_name") { std::error_code ec; jsoncons::uri uri = jsoncons::uri::parse("file:///path", ec); REQUIRE_FALSE(ec); CHECK("/path" == uri.encoded_path()); } SECTION("test_rootless_1") { std::error_code ec; jsoncons::uri uri = jsoncons::uri::parse("mailto:john.doe@example.com", ec); REQUIRE_FALSE(ec); CHECK("john.doe@example.com" == uri.encoded_path()); } SECTION("test_invalid_characters_in_path") { std::error_code ec; jsoncons::uri uri = jsoncons::uri::parse("mailto:jo%hn.doe@example.com", ec); REQUIRE(ec); REQUIRE(jsoncons::uri_errc::invalid_character_in_path == ec); //std::cout << ec.message() << "\n"; } SECTION("test_invalid_percent_encoded_characters_in_path_1") { std::error_code ec; jsoncons::uri uri = jsoncons::uri::parse("mailto:john.doe@example%G0.com", ec); REQUIRE(ec); REQUIRE(jsoncons::uri_errc::invalid_character_in_path == ec); //std::cout << ec.message() << "\n"; } SECTION("test_invalid_percent_encoded_characters_in_path_2") { std::error_code ec; jsoncons::uri uri = jsoncons::uri::parse("mailto:john.doe@example%0G.com", ec); REQUIRE(ec); REQUIRE(jsoncons::uri_errc::invalid_character_in_path == ec); //std::cout << ec.message() << "\n"; } } TEST_CASE("cpp-netib uri resolve tests") { jsoncons::uri base_uri{"http://a/b/c/d;p?q"}; SECTION("is_absolute_uri__returns_other") { jsoncons::uri reference{"https://www.example.com/"}; auto uri = base_uri.resolve(reference); CHECK("https://www.example.com/" == uri.string()); } SECTION("base_has_empty_path__path_is_ref_path_1") { jsoncons::uri reference{"g"}; jsoncons::uri base{"http://a/"}; auto uri = base.resolve(reference); CHECK("http://a/g" == uri.string()); } SECTION("base_has_empty_path__path_is_ref_path_2") { jsoncons::uri reference{"g/x/y?q=1#s"}; jsoncons::uri base{"http://a/"}; auto uri = base.resolve(reference); CHECK(uri.encoded_query() == jsoncons::string_view("q=1")); CHECK("http://a/g/x/y?q=1#s" == uri.string()); } SECTION("remove_dot_segments1") { jsoncons::uri reference{"./g"}; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g" == uri.string()); } SECTION("base_has_path__path_is_merged_1") { jsoncons::uri reference{"g/"}; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g/" == uri.string()); } SECTION("base_has_path__path_is_merged_2") { jsoncons::uri reference{"g"}; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g" == uri.string()); } SECTION("path_starts_with_slash__path_is_ref_path") { jsoncons::uri reference{"/g"}; auto uri = base_uri.resolve(reference); CHECK("http://a/g" == uri.string()); } SECTION("path_starts_with_slash_with_query_fragment__path_is_ref_path") { jsoncons::uri reference{ "/g/x?y=z#s" }; auto uri = base_uri.resolve(reference); CHECK("http://a/g/x?y=z#s" == uri.string()); } SECTION("path_is_empty_but_has_query__returns_base_with_ref_query") { jsoncons::uri reference{ "?y=z" }; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/d;p?y=z" == uri.string()); } SECTION("path_is_empty_but_has_query_base_no_query__returns_base_with_ref_query") { jsoncons::uri reference{ "?y=z" }; jsoncons::uri base{"http://a/b/c/d"}; auto uri = base.resolve(reference); CHECK("http://a/b/c/d?y=z" == uri.string()); } SECTION("merge_path_with_query") { jsoncons::uri reference{ "g?y=z" }; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g?y=z" == uri.string()); } SECTION("append_fragment") { jsoncons::uri reference{ "#s" }; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/d;p?q#s" == uri.string()); } SECTION("merge_paths_with_fragment") { jsoncons::uri reference{ "g#s" }; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g#s" == uri.string()); } SECTION("merge_paths_with_query_and_fragment") { jsoncons::uri reference{ "g?y=z#s" }; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g?y=z#s" == uri.string()); } SECTION("merge_paths_with_semicolon_1") { jsoncons::uri reference{ ";x" }; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/;x" == uri.string()); } SECTION("merge_paths_with_semicolon_2") { jsoncons::uri reference{ "g;x" }; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g;x" == uri.string()); } SECTION("merge_paths_with_semicolon_3") { jsoncons::uri reference{ "g;x?y=z#s" }; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g;x?y=z#s" == uri.string()); } SECTION("abnormal_example_1") { jsoncons::uri reference{"../../../g"}; auto uri = base_uri.resolve(reference); CHECK("http://a/g" == uri.string()); } SECTION("abnormal_example_2") { jsoncons::uri reference{"../../../../g"}; auto uri = base_uri.resolve(reference); CHECK("http://a/g" == uri.string()); } SECTION("abnormal_example_3") { jsoncons::uri reference{"/./g"}; auto uri = base_uri.resolve(reference); CHECK("http://a/g" == uri.string()); } SECTION("abnormal_example_4") { jsoncons::uri reference{"/../g"}; auto uri = base_uri.resolve(reference); CHECK("http://a/g" == uri.string()); } SECTION("abnormal_example_5") { jsoncons::uri reference{"g."}; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g." == uri.string()); } SECTION("abnormal_example_6") { jsoncons::uri reference{".g"}; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/.g" == uri.string()); } SECTION("abnormal_example_7") { jsoncons::uri reference{"g.."}; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g.." == uri.string()); } SECTION("abnormal_example_8") { jsoncons::uri reference{"..g"}; auto uri = base_uri.resolve(reference); CHECK("http://a/b/g" == uri.string()); } SECTION("abnormal_example_9") { jsoncons::uri reference{"./../g"}; auto uri = base_uri.resolve(reference); CHECK("http://a/b/g" == uri.string()); } SECTION("abnormal_example_10") { jsoncons::uri reference{"./g/."}; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g/" == uri.string()); } SECTION("abnormal_example_11") { jsoncons::uri reference{"g/./h"}; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g/h" == uri.string()); } SECTION("abnormal_example_12") { jsoncons::uri reference{"g/../h"}; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/h" == uri.string()); } SECTION("abnormal_example_13") { jsoncons::uri reference{"g;x=1/./y"}; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g;x=1/y" == uri.string()); } SECTION("abnormal_example_14") { jsoncons::uri reference{"g;x=1/../y"}; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/y" == uri.string()); } SECTION("abnormal_example_15") { jsoncons::uri reference{"g?y/./x"}; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g?y/./x" == uri.string()); } SECTION("abnormal_example_16") { jsoncons::uri reference{"g?y/../x"}; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g?y/../x" == uri.string()); } SECTION("abnormal_example_17") { jsoncons::uri reference{"g#s/./x"}; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g#s/./x" == uri.string()); } SECTION("abnormal_example_18") { jsoncons::uri reference{"g#s/../x"}; auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g#s/../x" == uri.string()); } } jsoncons-1.3.2/test/corelib/src/value_converter_tests.cpp000066400000000000000000000026771477700171100237100ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include using namespace jsoncons; TEST_CASE("convert into string") { std::vector bytes = {'f','o','o','b','a','r'}; SECTION("from byte_string into string") { value_converter converter; std::string expected = "Zm9vYmFy"; std::error_code ec; std::string s = converter.convert(byte_string_view(bytes), semantic_tag::base64url, ec); REQUIRE(!ec); CHECK(expected == s); } SECTION("from byte string into wstring") { value_converter converter; std::wstring expected = L"Zm9vYmFy"; std::error_code ec; std::wstring s = converter.convert(byte_string_view(bytes), semantic_tag::base64url, ec); REQUIRE(!ec); CHECK(expected == s); } } TEST_CASE("convert into list-like") { SECTION("from string") { value_converter> converter; std::vector expected = {'f','o','o','b','a','r'}; std::error_code ec; std::vector v = converter.convert(jsoncons::string_view("Zm9vYmFy"), semantic_tag::base64url, ec); REQUIRE(!ec); CHECK(expected == v); } } jsoncons-1.3.2/test/corelib/src/wjson_tests.cpp000066400000000000000000000065771477700171100216500ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("test_wjson") { wjson root; root[L"field1"] = L"test"; root[L"field2"] = 3.9; root[L"field3"] = true; CHECK(root[L"field1"].as() == L"test"); CHECK(root[L"field2"].as() == 3.9); CHECK(root[L"field3"].as() == true); std::wstring s1 = root[L"field1"].as(); CHECK(s1 == L"test"); } TEST_CASE("test_wjson_escape_u") { std::wstring input = L"[\"\\uABCD\"]"; std::wistringstream is(input); wjson root = wjson::parse(is); std::wstring s = root[0].as(); CHECK( s.length() == 1 ); CHECK( s[0] == 0xABCD ); } TEST_CASE("wjson serialization tests") { jsoncons::wjson testBlock; testBlock[L"foo"] = true; testBlock[L"bar"] = false; testBlock[L"baz"] = true; std::wstring testStr; testBlock.dump(testStr); CHECK(testStr == L"{\"bar\":false,\"baz\":true,\"foo\":true}"); } TEST_CASE("wjson pretty print tests") { jsoncons::wjson testBlock; testBlock[L"foo"] = true; testBlock[L"bar"] = false; testBlock[L"baz"] = true; std::wostringstream actualStr; actualStr << jsoncons::pretty_print(testBlock); std::wostringstream expectedStr; expectedStr << L"{" << '\n'; expectedStr << L" \"bar\": false, " << '\n'; expectedStr << L" \"baz\": true, " << '\n'; expectedStr << L" \"foo\": true" << '\n'; expectedStr << L"}"; CHECK(actualStr.str().size() == expectedStr.str().size()); CHECK(actualStr.str() == expectedStr.str()); } TEST_CASE("wjson test case") { std::wstring data = LR"( {"call":"script","cwd":"C:\\Users\\Robert\\Documents\\Visual Studio 2015\\Projects\\EscPosPrinter\\Release\\","file":"scripts\\pos-submitorder.js","filename":"pos-submitorder.js","lib":"function", "params":{"data":{"cash":0,"coupons":0,"creditcard":0,"debit":0,"discounts":0,"name":null,"neworder":true,"operator":"","orders":[{"active":"1","addtoitem":"0","bar":"1","cat":"Beer","cooking":"","id":"7","kitchen":"0","modifier":"0","name":"Budwiser","noqty":"1","oneof":"[]","operator":"robert","options":"[]","price":"5","print":"","qty":1,"server":"robert","sideprice":"0","subtotal":5,"type":"Bar","uid":"0242.7559"}],"outstanding":5.25,"payments":[],"server":"robert","status":"0","subtotal":5,"tableid":"quickserv","taxes":0.25,"tip":0,"total":5.25,"uid":"2822.7128","voiditems":[]},"posstation":{"printers":{"kitchen":[{"arguments":{"baud":"9600","bits":"8","nparity":"0","port":"3","stopbit":"0","xonxoff":"5"},"model":"epson","path":"localhost","type":"com"},{"arguments":{"baud":"","bits":"","nparity":"","port":"","stopbit":"","xonxoff":""},"model":"screen","path":"temp-pc","type":"screen"}],"receipt":[{"arguments":{"baud":"9600","bits":"8","nparity":"0","port":"3","stopbit":"0","xonxoff":"5"},"model":"epson","path":"Temp-PC","type":"com"},{"arguments":{"baud":"","bits":"","nparity":"","port":"","stopbit":"","xonxoff":""},"model":"screen","path":"localhost","type":"screen"}]}}},"plugin":"clib"} )"; wjson j = wjson::parse(data); std::wstring s = j[L"params"].to_string(); std::wcout << s << "\n"; } jsoncons-1.3.2/test/csv/000077500000000000000000000000001477700171100151305ustar00rootroot00000000000000jsoncons-1.3.2/test/csv/input/000077500000000000000000000000001477700171100162675ustar00rootroot00000000000000jsoncons-1.3.2/test/csv/input/countries.csv000066400000000000000000000001571477700171100210220ustar00rootroot00000000000000country_code,name ABW,ARUBA ATF,"FRENCH SOUTHERN TERRITORIES, D.R. OF" VUT,VANUATU WLF,WALLIS & FUTUNA ISLANDS jsoncons-1.3.2/test/csv/input/countries.json000066400000000000000000000002471477700171100212000ustar00rootroot00000000000000[ ["country_code","name"], ["ABW","ARUBA"], ["ATF","FRENCH SOUTHERN TERRITORIES, D.R. OF"], ["VUT","VANUATU"], ["WLF","WALLIS & FUTUNA ISLANDS"] ] jsoncons-1.3.2/test/csv/input/desktop.ini000066400000000000000000000000641477700171100204410ustar00rootroot00000000000000[LocalizedFileNames] countries.csv=@countries.csv,0 jsoncons-1.3.2/test/csv/input/employees.json000066400000000000000000000013031477700171100211610ustar00rootroot00000000000000[ { "dept":"sales", "employee-name":"Smith, Matthew", "employee-no":"00000001", "note":"", "salary":"150,000.00" }, { "dept":"sales", "employee-name":"Brown, Sarah", "employee-no":"00000002", "note":"", "salary":"89,000.00" }, { "dept":"finance", "employee-name":"Oberc, Scott", "employee-no":"00000003", "salary":"110,000.00" }, { "dept":"sales", "employee-name":"Scott, Colette", "employee-no":"00000004", "note":"\"Exemplary\" employee Dependable, trustworthy", "comment":"Team player", "salary":"75,000.00" } ] jsoncons-1.3.2/test/csv/input/employees.txt000066400000000000000000000003771477700171100210410ustar00rootroot00000000000000employee-no employee-name dept salary note 00000001 Smith, Matthew sales 150,000.00 00000002 Brown, Sarah sales 89,000.00 00000003 Oberc, Scott finance 110,000.00 00000004 Scott, Colette sales 75,000.00 """Exemplary"" employee Dependable, trustworthy" jsoncons-1.3.2/test/csv/src/000077500000000000000000000000001477700171100157175ustar00rootroot00000000000000jsoncons-1.3.2/test/csv/src/csv_cursor_tests.cpp000066400000000000000000001255221477700171100220440ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("csv_cursor eof test") { const std::string data = ""; SECTION("csv::csv_mapping_kind::n_rows eof test") { auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_rows); std::error_code ec; csv::csv_string_cursor cursor(data, options, ec); CHECK(ec == csv::csv_errc::source_error); } } TEST_CASE("csv_cursor n_rows test") { const std::string data = R"(index_id,observation_date,rate EUR_LIBOR_06M,2015-10-23,0.0000214 EUR_LIBOR_06M,2015-10-26,0.0000143 EUR_LIBOR_06M,2015-10-27,0.0000001 )"; SECTION("n_rows test") { auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_rows); csv::csv_string_cursor cursor(data, options); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("index_id")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("observation_date")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("rate")); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("EUR_LIBOR_06M")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("2015-10-23")); cursor.next(); REQUIRE(staj_event_type::double_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("EUR_LIBOR_06M")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::double_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("EUR_LIBOR_06M")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::double_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); CHECK(cursor.done()); } SECTION("n_objects test") { auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_objects); csv::csv_string_cursor cursor(data, options); jsoncons::json_decoder decoder; REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("index_id")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("EUR_LIBOR_06M")); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("observation_date")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("2015-10-23")); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("rate")); cursor.next(); REQUIRE(staj_event_type::double_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_object == cursor.current().event_type()); cursor.read_to(decoder); REQUIRE(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("index_id")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("EUR_LIBOR_06M")); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("observation_date")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("rate")); cursor.next(); REQUIRE(staj_event_type::double_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); CHECK(cursor.done()); } SECTION("m_columns test") { auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::m_columns); json_decoder decoder; csv::csv_string_cursor cursor(data, options); REQUIRE(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("index_id")); cursor.next(); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("observation_date")); cursor.next(); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("rate")); cursor.next(); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::double_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::double_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::double_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); CHECK(cursor.done()); } } TEST_CASE("csv_cursor n_rows with quotes test") { const std::string data = R"("index_id","observation_date","rate" EUR_LIBOR_06M,2015-10-23,0.0000214 EUR_LIBOR_06M,2015-10-26,0.0000143 EUR_LIBOR_06M,2015-10-27,0.0000001 )"; SECTION("test 1") { auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_rows); csv::csv_string_cursor cursor(data, options); /* for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::end_array: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::begin_object: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::end_object: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::key: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::string_value: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::null_value: std::cout << event.event_type() << "\n"; break; case staj_event_type::bool_value: std::cout << event.event_type() << ": " << std::boolalpha << event.get() << "\n"; break; case staj_event_type::int64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::double_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; default: std::cout << "Unhandled event type: " << event.event_type() << " " << "\n"; break; } }*/ REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("index_id")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("observation_date")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("rate")); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::double_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::double_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::double_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); CHECK(cursor.done()); } } TEST_CASE("csv_cursor n_objects test") { const std::string data = R"(index_id,observation_date,rate EUR_LIBOR_06M,2015-10-23,0.0000214 EUR_LIBOR_06M,2015-10-26,0.0000143 EUR_LIBOR_06M,2015-10-27,0.0000001 )"; SECTION("test 2") { auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_objects); csv::csv_string_cursor cursor(data, options); /* for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::end_array: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::begin_object: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::end_object: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::key: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::string_value: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::null_value: std::cout << event.event_type() << "\n"; break; case staj_event_type::bool_value: std::cout << event.event_type() << ": " << std::boolalpha << event.get() << "\n"; break; case staj_event_type::int64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::double_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; default: std::cout << "Unhandled event type: " << event.event_type() << " " << "\n"; break; } } */ REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("index_id")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("observation_date")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("rate")); cursor.next(); REQUIRE(staj_event_type::double_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("index_id")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("observation_date")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("rate")); cursor.next(); REQUIRE(staj_event_type::double_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("index_id")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("observation_date")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("rate")); cursor.next(); REQUIRE(staj_event_type::double_value == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); CHECK(cursor.done()); } } TEST_CASE("csv_cursor n_objects subfields test") { const std::string data = R"(calculationPeriodCenters,paymentCenters,resetCenters NY;LON,TOR,LON NY,LON,TOR;LON "NY";"LON","TOR","LON" "NY","LON","TOR";"LON" )"; SECTION("test 1") { auto options = csv::csv_options{} .assume_header(true) .subfield_delimiter(';'); csv::csv_string_cursor cursor(data, options); /* for (; !cursor.done(); cursor.next()) { const auto& event = cursor.current(); switch (event.event_type()) { case staj_event_type::begin_array: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::end_array: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::begin_object: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::end_object: std::cout << event.event_type() << " " << "\n"; break; case staj_event_type::key: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::string_value: // Or std::string_view, if supported std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::null_value: std::cout << event.event_type() << "\n"; break; case staj_event_type::bool_value: std::cout << event.event_type() << ": " << std::boolalpha << event.get() << "\n"; break; case staj_event_type::int64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::uint64_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; case staj_event_type::double_value: std::cout << event.event_type() << ": " << event.get() << "\n"; break; default: std::cout << "Unhandled event type: " << event.event_type() << " " << "\n"; break; } } */ REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("calculationPeriodCenters")); cursor.next(); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("NY")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("LON")); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("paymentCenters")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("TOR")); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("resetCenters")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("LON")); cursor.next(); REQUIRE(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("calculationPeriodCenters")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("NY")); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("paymentCenters")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("LON")); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("resetCenters")); cursor.next(); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("TOR")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("LON")); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("calculationPeriodCenters")); cursor.next(); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("NY")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("LON")); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("paymentCenters")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("TOR")); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("resetCenters")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("LON")); cursor.next(); REQUIRE(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("calculationPeriodCenters")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("NY")); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("paymentCenters")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("LON")); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("resetCenters")); cursor.next(); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("TOR")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("LON")); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); CHECK(cursor.done()); } } TEST_CASE("csv_cursor n_rows, no header test") { std::string data = "\"b\""; SECTION("test 1") { auto options = csv::csv_options{} .mapping_kind(csv::csv_mapping_kind::n_rows) .assume_header(false); csv::csv_string_cursor cursor(data, options); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("b")); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); CHECK(cursor.done()); } } TEST_CASE("csv_cursor n_objects, header test") { std::string data = "a\n\"4\""; SECTION("test 2") { auto options = csv::csv_options{} .assume_header(true); csv::csv_string_cursor cursor(data, options); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("a")); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("4")); cursor.next(); REQUIRE(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); CHECK(cursor.done()); } } TEST_CASE("csv_cursor header, subfield no terminating new line test") { std::string data = "a\n4;-5"; SECTION("test 1") { auto options = csv::csv_options{} .assume_header(true) .subfield_delimiter(';') .mapping_kind(csv::csv_mapping_kind::n_rows); csv::csv_string_cursor cursor(data, options); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::string_value == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("a")); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::uint64_value == cursor.current().event_type()); CHECK(4 == cursor.current().get()); cursor.next(); REQUIRE(staj_event_type::int64_value == cursor.current().event_type()); CHECK(cursor.current().get() == -5); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); CHECK(cursor.done()); } SECTION("test 2") { auto options = csv::csv_options{} .assume_header(true) .subfield_delimiter(';'); csv::csv_string_cursor cursor(data, options); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().get() == std::string("a")); cursor.next(); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::uint64_value == cursor.current().event_type()); CHECK(4 == cursor.current().get()); cursor.next(); REQUIRE(staj_event_type::int64_value == cursor.current().event_type()); CHECK(cursor.current().get() == -5); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); CHECK(cursor.done()); } } struct remove_mark_csv_filter { bool reject_next_ = false; bool operator()(const staj_event& event, const ser_context&) { if (event.event_type() == staj_event_type::key && event.get() == "mark") { reject_next_ = true; return false; } else if (reject_next_) { reject_next_ = false; return false; } else { return true; } } }; TEST_CASE("csv_cursor with filter tests") { auto j = ojson::parse(R"( [ { "enrollmentNo" : 100, "firstName" : "Tom", "lastName" : "Cochrane", "mark" : 55 }, { "enrollmentNo" : 101, "firstName" : "Catherine", "lastName" : "Smith", "mark" : 95 }, { "enrollmentNo" : 102, "firstName" : "William", "lastName" : "Skeleton", "mark" : 60 } ] )"); std::string data; csv::encode_csv(j, data); auto options = csv::csv_options{} .assume_header(true); csv::csv_string_cursor cursor(data, options); auto filtered_c = cursor | remove_mark_csv_filter(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::begin_array); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::begin_object); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::uint64_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::string_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::string_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::end_object); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::begin_object); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::uint64_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::string_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::string_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::end_object); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::begin_object); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::uint64_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::string_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::string_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::end_object); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::end_array); filtered_c.next(); CHECK(filtered_c.done()); } TEST_CASE("test_csv_parser_reinitialization") { json_decoder decoder; auto options = csv::csv_options() .assume_header(true) .max_lines(2); csv::csv_parser parser(options); parser.reinitialize(); std::string input = "h1,h2\n" "3,4\n" "5,6\n"; parser.update(input.data(), input.size()); int count = 0; while (!parser.stopped() && count < 20) { parser.parse_some(decoder); ++count; } REQUIRE(parser.stopped()); decoder.end_array(); REQUIRE(decoder.is_valid()); json j = decoder.get_result(); json expected = json::parse(R"([{"h1":3,"h2":4}])"); CHECK(expected == j); parser.reinitialize(); input = "h7,h8\n" "9,10\n"; parser.update(input.data(), input.size()); count = 0; while (!parser.stopped() && count < 20) { parser.parse_some(decoder); ++count; } REQUIRE(parser.stopped()); decoder.end_array(); REQUIRE(decoder.is_valid()); j = decoder.get_result(); expected = json::parse(R"([{"h7":9,"h8":10}])"); CHECK(expected == j); } template void check_csv_cursor_table(std::string info, CursorType& cursor, std::string expected_key, unsigned expected_value) { INFO(info); REQUIRE_FALSE(cursor.done()); REQUIRE(staj_event_type::begin_array == cursor.current().event_type()); CHECK_FALSE(cursor.done()); cursor.next(); REQUIRE(staj_event_type::begin_object == cursor.current().event_type()); CHECK_FALSE(cursor.done()); cursor.next(); REQUIRE(staj_event_type::key == cursor.current().event_type()); CHECK(cursor.current().template get() == expected_key); CHECK_FALSE(cursor.done()); cursor.next(); REQUIRE(staj_event_type::uint64_value == cursor.current().event_type()); CHECK(cursor.current().template get() == expected_value); CHECK_FALSE(cursor.done()); cursor.next(); REQUIRE(staj_event_type::end_object == cursor.current().event_type()); CHECK_FALSE(cursor.done()); cursor.next(); REQUIRE(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); CHECK(cursor.done()); } TEMPLATE_TEST_CASE("csv_cursor reset test", "", (std::pair), (std::pair)) { using cursor_type = typename TestType::first_type; using input_type = typename TestType::second_type; SECTION("with another source") { input_type input1("h1\n1\n"); input_type input2(""); input_type input3("h3\n3\n"); auto options = csv::csv_options().assume_header(true); std::error_code ec; cursor_type cursor(input1, options, ec); check_csv_cursor_table("with input1", cursor, "h1", 1); cursor.reset(input2, ec); CHECK(ec == csv::csv_errc::source_error); CHECK_FALSE(cursor.done()); // Check that cursor can reused be upon reset following an error. ec = csv::csv_errc::success; cursor.reset(input3); check_csv_cursor_table("with input3", cursor, "h3", 3); } } jsoncons-1.3.2/test/csv/src/csv_encoder_tests.cpp000066400000000000000000000457731477700171100221570ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include namespace csv = jsoncons::csv; TEST_CASE("test json to flat csv with column mappings") { //#if 0 SECTION("array of objects to csv") { std::string expected = R"(Number,Date Time 1.0,1971-01-01T04:14:00 1.27,1948-01-01T14:57:13 )"; std::string jtext = R"( [ { "text": "Chicago Reader", "float": 1.0, "datetime": "1971-01-01T04:14:00", "boolean": true, "nested": { "time": "04:14:00", "nested": { "date": "1971-01-01", "integer": 40 } } }, { "text": "Chicago Sun-Times", "float": 1.27, "datetime": "1948-01-01T14:57:13", "boolean": true, "nested": { "time": "14:57:13", "nested": { "date": "1948-01-01", "integer": 63 } } } ] )"; auto j = jsoncons::json::parse(jtext); //std::cout << pretty_print(j) << "\n"; auto options = csv::csv_options{} .flat(true) .column_mapping({ {"/float","Number"}, {"/datetime","Date Time"} }); std::string buf; csv::csv_string_encoder encoder(buf, options); j.dump(encoder); //std::cout << buf << "\n"; CHECK(expected == buf); } SECTION("array of arrays to csv") { std::string expected = R"(Date Time,Newspaper 1971-01-01T04:14:00,Chicago Reader 1948-01-01T14:57:13,Chicago Sun-Times )"; std::string jtext = R"( [ [ "Chicago Reader", 1.0, "1971-01-01T04:14:00", true, [ "04:14:00", [ "1971-01-01", 40 ] ] ], [ "Chicago Sun-Times", 1.27, "1948-01-01T14:57:13", true, [ "14:57:13", [ "1948-01-01", 63 ] ] ] ] )"; auto j = jsoncons::json::parse(jtext); //std::cout << pretty_print(j) << "\n"; auto options = csv::csv_options{} .flat(true) .column_mapping({ {"/2","Date Time"}, {"/0","Newspaper"} }); std::string buf; csv::csv_string_encoder encoder(buf, options); j.dump(encoder); CHECK(expected == buf); } //#endif } TEST_CASE("test json to flat csv") { //#if 0 SECTION("array of objects to csv") { std::string expected = R"(boolean,datetime,float,text true,1971-01-01T04:14:00,1.0,Chicago Reader true,1948-01-01T14:57:13,1.27,Chicago Sun-Times )"; std::string jtext = R"( [ { "text": "Chicago Reader", "float": 1.0, "datetime": "1971-01-01T04:14:00", "boolean": true, "nested": { "time": "04:14:00", "nested": { "date": "1971-01-01", "integer": 40 } } }, { "text": "Chicago Sun-Times", "float": 1.27, "datetime": "1948-01-01T14:57:13", "boolean": true, "nested": { "time": "14:57:13", "nested": { "date": "1948-01-01", "integer": 63 } } } ] )"; auto j = jsoncons::json::parse(jtext); //std::cout << pretty_print(j) << "\n"; std::string buf; csv::csv_string_encoder encoder(buf); j.dump(encoder); //std::cout << buf << "\n"; CHECK(expected == buf); } SECTION("array of objects with some missing members to csv") { std::string expected = R"(boolean,datetime,float,text true,1971-01-01T04:14:00,1.0,Chicago Reader true,1948-01-01T14:57:13,,Chicago Sun-Times )"; std::string jtext = R"( [ { "text": "Chicago Reader", "float": 1.0, "datetime": "1971-01-01T04:14:00", "boolean": true, "nested": { "time": "04:14:00", "nested": { "date": "1971-01-01", "integer": 40 } } }, { "text": "Chicago Sun-Times", "datetime": "1948-01-01T14:57:13", "boolean": true, "nested": { "time": "14:57:13", "nested": { "date": "1948-01-01", "integer": 63 } } } ] )"; auto j = jsoncons::json::parse(jtext); //std::cout << pretty_print(j) << "\n"; std::string buf; csv::csv_string_encoder encoder(buf); j.dump(encoder); //std::cout << buf << "\n"; CHECK(expected == buf); } SECTION("array of arrays to csv") { std::string expected = R"(Chicago Reader,1.0,1971-01-01T04:14:00,true Chicago Sun-Times,1.27,1948-01-01T14:57:13,true )"; std::string jtext = R"( [ [ "Chicago Reader", 1.0, "1971-01-01T04:14:00", true, [ "04:14:00", [ "1971-01-01", 40 ] ] ], [ "Chicago Sun-Times", 1.27, "1948-01-01T14:57:13", true, [ "14:57:13", [ "1948-01-01", 63 ] ] ] ] )"; auto j = jsoncons::json::parse(jtext); //std::cout << pretty_print(j) << "\n"; std::string buf; csv::csv_string_encoder encoder(buf); j.dump(encoder); CHECK(expected == buf); } SECTION("array of arrays and subarrays to csv") { std::string expected = R"(calculationPeriodCenters,paymentCenters,resetCenters NY;LON,TOR,LON NY,LON,TOR;LON NY;LON,TOR,LON NY,LON,TOR;LON )"; std::string jtext = R"( [ ["calculationPeriodCenters","paymentCenters","resetCenters"], [ ["NY","LON"],"TOR","LON" ], ["NY","LON", ["TOR","LON"] ], [ ["NY","LON"],"TOR","LON" ], ["NY","LON", ["TOR","LON"] ] ] )"; auto j = jsoncons::json::parse(jtext); //std::cout << pretty_print(j) << "\n"; auto options = csv::csv_options{} .subfield_delimiter(';'); std::string buf; csv::csv_string_encoder encoder(buf, options); j.dump(encoder); CHECK(expected == buf); } SECTION("array of subarrays to csv") { std::string expected = R"(1;2;3,4;5;6 7;8;9,10;11;12 )"; const std::string jtext = R"( [ [[1,2,3],[4,5,6]], [[7,8,9],[10,11,12]] ] )"; auto j = jsoncons::json::parse(jtext); //std::cout << pretty_print(j) << "\n"; auto options = csv::csv_options{} .subfield_delimiter(';'); std::string buf; csv::csv_string_encoder encoder(buf, options); j.dump(encoder); //std::cout << buf << "\n"; CHECK(expected == buf); } SECTION("object of arrays and subarrays to csv") { std::string expected = R"(a,b,c 1;true;null,7;8;9,15 -4;5.5;6,10;11;12,16 ,,17 )"; const std::string jtext = R"( { "a" : [[1,true,null],[-4,5.5,"6"]], "b" : [[7,8,9],[10,11,12]], "c" : [15,16,17] } )"; auto j = jsoncons::json::parse(jtext); //std::cout << pretty_print(j) << "\n"; auto options = csv::csv_options{} .subfield_delimiter(';'); std::string buf; csv::csv_string_encoder encoder(buf, options); j.dump(encoder); //std::cout << buf << "\n"; CHECK(expected == buf); } SECTION("object of arrays and subarrays to csv with column mapping") { std::string expected = R"(B,A 7;8;9,1;true;null 10;11;12,-4;5.5;6 )"; const std::string jtext = R"( { "a" : [[1,true,null],[-4,5.5,"6"]], "b" : [[7,8,9],[10,11,12]], "c" : [15,16,17] } )"; auto j = jsoncons::json::parse(jtext); //std::cout << pretty_print(j) << "\n"; auto options = csv::csv_options{} .subfield_delimiter(';') .column_mapping({ {"/b","B"}, {"/a","A"} }); std::string buf; csv::csv_string_encoder encoder(buf, options); j.dump(encoder); //std::cout << buf << "\n"; CHECK(expected == buf); } //#endif } TEST_CASE("test json to non-flat csv with column mappings") { //#if 0 SECTION("array of objects to csv") { std::string expected = R"(Number,Date Time 1.0,1971-01-01T04:14:00 1.27,1948-01-01T14:57:13 )"; std::string jtext = R"( [ { "text": "Chicago Reader", "float": 1.0, "datetime": "1971-01-01T04:14:00", "boolean": true, "nested": { "time": "04:14:00", "nested": { "date": "1971-01-01", "integer": 40 } } }, { "text": "Chicago Sun-Times", "float": 1.27, "datetime": "1948-01-01T14:57:13", "boolean": true, "nested": { "time": "14:57:13", "nested": { "date": "1948-01-01", "integer": 63 } } } ] )"; auto j = jsoncons::json::parse(jtext); //std::cout << pretty_print(j) << "\n"; auto options = csv::csv_options{} .flat(false) .column_mapping({ {"/float","Number"}, {"/datetime","Date Time"} }); std::string buf; csv::csv_string_encoder encoder(buf, options); j.dump(encoder); //std::cout << buf << "\n"; CHECK(expected == buf); } SECTION("array of arrays to csv") { std::string expected = R"(Date Time,Newspaper,No Pages 1971-01-01T04:14:00,Chicago Reader,40 1948-01-01T14:57:13,Chicago Sun-Times,63 )"; std::string jtext = R"( [ [ "Chicago Reader", 1.0, "1971-01-01T04:14:00", false, [ "04:14:00", [ "1971-01-01", 40 ] ] ], [ "Chicago Sun-Times", 1.27, "1948-01-01T14:57:13", true, [ "14:57:13", [ "1948-01-01", 63 ] ] ] ] )"; auto j = jsoncons::json::parse(jtext); //std::cout << pretty_print(j) << "\n"; auto options = csv::csv_options{} .flat(false) .column_mapping({ {"/2","Date Time"}, {"/0","Newspaper"}, {"/3/0/1", "No Pages"} }); std::string buf; csv::csv_string_encoder encoder(buf, options); j.dump(encoder); CHECK(expected == buf); } //#endif } TEST_CASE("test json to non-flat csv") { //#if 0 SECTION("array of objects to csv") { std::string expected = R"(/boolean,/datetime,/float,/nested/nested/date,/nested/nested/integer,/nested/time,/text true,1971-01-01T04:14:00,1.0,1971-01-01,40,04:14:00,Chicago Reader true,1948-01-01T14:57:13,1.27,1948-01-01,63,14:57:13,Chicago Sun-Times )"; std::string jtext = R"( [ { "text": "Chicago Reader", "float": 1.0, "datetime": "1971-01-01T04:14:00", "boolean": true, "nested": { "time": "04:14:00", "nested": { "date": "1971-01-01", "integer": 40 } } }, { "text": "Chicago Sun-Times", "float": 1.27, "datetime": "1948-01-01T14:57:13", "boolean": true, "nested": { "time": "14:57:13", "nested": { "date": "1948-01-01", "integer": 63 } } } ] )"; auto j = jsoncons::json::parse(jtext); //std::cout << pretty_print(j) << "\n"; auto options = csv::csv_options{} .flat(false); std::string buf; csv::csv_string_encoder encoder(buf, options); j.dump(encoder); CHECK(expected == buf); } SECTION("array of objects with some missing members to csv") { std::string expected = R"(/boolean,/datetime,/float,/nested/nested/date,/nested/nested/integer,/nested/time,/text true,1971-01-01T04:14:00,1.0,1971-01-01,40,04:14:00,Chicago Reader true,,1.27,,63,14:57:13,Chicago Sun-Times )"; std::string jtext = R"( [ { "text": "Chicago Reader", "float": 1.0, "datetime": "1971-01-01T04:14:00", "boolean": true, "nested": { "time": "04:14:00", "nested": { "date": "1971-01-01", "integer": 40 } } }, { "text": "Chicago Sun-Times", "float": 1.27, "boolean": true, "nested": { "time": "14:57:13", "nested": { "integer": 63 } } } ] )"; auto j = jsoncons::json::parse(jtext); //std::cout << pretty_print(j) << "\n"; auto options = csv::csv_options{} .flat(false); std::string buf; csv::csv_string_encoder encoder(buf, options); j.dump(encoder); CHECK(expected == buf); } SECTION("array of arrays to csv") { std::string expected = R"(/0,/1,/2,/3,/3/0,/3/0/0,/3/0/1 Chicago Reader,1.0,1971-01-01T04:14:00,true,04:14:00,1971-01-01,40 Chicago Sun-Times,1.27,1948-01-01T14:57:13,true,14:57:13,1948-01-01,63 )"; std::string jtext = R"( [ [ "Chicago Reader", 1.0, "1971-01-01T04:14:00", true, [ "04:14:00", [ "1971-01-01", 40 ] ] ], [ "Chicago Sun-Times", 1.27, "1948-01-01T14:57:13", true, [ "14:57:13", [ "1948-01-01", 63 ] ] ] ] )"; auto j = jsoncons::json::parse(jtext); //std::cout << pretty_print(j) << "\n"; auto options = csv::csv_options{} .flat(false); std::string buf; csv::csv_string_encoder encoder(buf, options); j.dump(encoder); CHECK(expected == buf); } SECTION("array of object and subarrays to csv") { std::string expected = R"(calculationPeriodCenters,paymentCenters,resetCenters NY;LON,TOR,LON NY,LON,TOR;LON NY;LON,TOR,LON NY,LON,TOR;LON )"; std::string jtext = R"( [ {"calculationPeriodCenters" : ["NY","LON"], "paymentCenters" : "TOR", "resetCenters" : "LON"}, {"calculationPeriodCenters" : "NY", "paymentCenters" : "LON", "resetCenters" : ["TOR","LON"]}, {"calculationPeriodCenters" : ["NY","LON"], "paymentCenters" : "TOR", "resetCenters" : "LON"}, {"calculationPeriodCenters" : "NY", "paymentCenters" : "LON", "resetCenters" : ["TOR","LON"]} ] )"; auto j = jsoncons::json::parse(jtext); //std::cout << pretty_print(j) << "\n"; auto options = csv::csv_options{} .flat(true) .subfield_delimiter(';'); std::string buf; csv::csv_string_encoder encoder(buf, options); j.dump(encoder); CHECK(expected == buf); } //#endif } TEST_CASE("test json to flat csv with column names") { //#if 0 SECTION("array of objects to csv") { std::string expected = R"(boolean,datetime,float,text true,1971-01-01T04:14:00,1.0,Chicago Reader true,1948-01-01T14:57:13,1.27,Chicago Sun-Times )"; std::string jtext = R"( [ { "text": "Chicago Reader", "float": 1.0, "datetime": "1971-01-01T04:14:00", "boolean": true }, { "text": "Chicago Sun-Times", "float": 1.27, "datetime": "1948-01-01T14:57:13", "boolean": true } ] )"; auto j = jsoncons::json::parse(jtext); //std::cout << pretty_print(j) << "\n"; auto options = csv::csv_options{} .flat(true) .column_names("boolean,datetime,float,text"); std::string buf; csv::csv_string_encoder encoder(buf, options); j.dump(encoder); //std::cout << buf << "\n"; CHECK(expected == buf); } SECTION("array of objects to csv with missing name") { std::string expected = R"(boolean,datetime,float,text true,,1.0,Chicago Reader true,1948-01-01T14:57:13,1.27,Chicago Sun-Times )"; std::string jtext = R"( [ { "text": "Chicago Reader", "float": 1.0, "boolean": true }, { "text": "Chicago Sun-Times", "float": 1.27, "datetime": "1948-01-01T14:57:13", "boolean": true } ] )"; auto j = jsoncons::json::parse(jtext); //std::cout << pretty_print(j) << "\n"; auto options = csv::csv_options{} .flat(true) .column_names("boolean,datetime,float,text"); std::string buf; csv::csv_string_encoder encoder(buf, options); j.dump(encoder); //std::cout << buf << "\n"; CHECK(expected == buf); } SECTION("array of arrays to csv with column_names") { std::string expected = R"(text,float Chicago Reader,1.0 Chicago Sun-Times,1.27 )"; std::string jtext = R"( [ [ "Chicago Reader", 1.0, "1971-01-01T04:14:00", true, [ "04:14:00", [ "1971-01-01", 40 ] ] ], [ "Chicago Sun-Times", 1.27, "1948-01-01T14:57:13", true, [ "14:57:13", [ "1948-01-01", 63 ] ] ] ] )"; auto j = jsoncons::json::parse(jtext); //std::cout << pretty_print(j) << "\n"; auto options = csv::csv_options{} .flat(true) .column_names("text,float"); std::string buf; csv::csv_string_encoder encoder(buf, options); j.dump(encoder); CHECK(expected == buf); } //#endif SECTION("object of arrays and subarrays to csv with column_names") { std::string expected = R"(b,c,a 7;8;9,15,1;true;null 10;11;12,16,-4;5.5;6 ,17, )"; const std::string jtext = R"( { "a" : [[1,true,null],[-4,5.5,"6"]], "b" : [[7,8,9],[10,11,12]], "c" : [15,16,17] } )"; auto j = jsoncons::json::parse(jtext); //std::cout << pretty_print(j) << "\n"; auto options = csv::csv_options{} .subfield_delimiter(';') .column_names("b,c,a"); std::string buf; csv::csv_string_encoder encoder(buf, options); j.dump(encoder); //std::cout << buf << "\n"; CHECK(expected == buf); } } jsoncons-1.3.2/test/csv/src/csv_reader_tests.cpp000066400000000000000000000016011477700171100217600ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include namespace csv = jsoncons::csv; TEST_CASE("test csv_reader buffered read") { SECTION("test 1") { const std::string bond_yields = R"(Date,1Y,2Y,3Y,5Y 2017-01-09,0.0062,0.0075,0.0083,0.011 2017-01-08,0.0063,0.0076,0.0084,0.0112 2017-01-08,0.0063,0.0076,0.0084,0.0112 )"; jsoncons::json_decoder decoder; auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_rows); csv::csv_string_reader reader(bond_yields,decoder,options); reader.read(); auto val = decoder.get_result(); //std::cout << jsoncons::pretty_print(val) << "\n"; CHECK(4 == val.size()); } } jsoncons-1.3.2/test/csv/src/csv_subfield_tests.cpp000066400000000000000000000061051477700171100223170ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include #include using namespace jsoncons; using namespace jsoncons::literals; TEST_CASE("test_n_objects") { const std::string s = R"(calculationPeriodCenters,paymentCenters,resetCenters NY;LON,TOR,LON NY,LON,TOR;LON "NY";"LON","TOR","LON" "NY","LON","TOR";"LON" )"; auto options = csv::csv_options{} .assume_header(true) .subfield_delimiter(';'); json expected = R"( [ { "calculationPeriodCenters": ["NY","LON"], "paymentCenters": "TOR", "resetCenters": "LON" }, { "calculationPeriodCenters": "NY", "paymentCenters": "LON", "resetCenters": ["TOR","LON"] }, { "calculationPeriodCenters": ["NY","LON"], "paymentCenters": "TOR", "resetCenters": "LON" }, { "calculationPeriodCenters": "NY", "paymentCenters": "LON", "resetCenters": ["TOR","LON"] } ] )"_json; JSONCONS_TRY { json j = csv::decode_csv(s,options); CHECK(expected == j); //std::cout << pretty_print(j) << '\n'; } JSONCONS_CATCH (const std::exception& e) { std::cerr << e.what() << '\n'; } } TEST_CASE("test_n_rows") { const std::string s = R"(calculationPeriodCenters,paymentCenters,resetCenters NY;LON,TOR,LON NY,LON,TOR;LON "NY";"LON","TOR","LON" "NY","LON","TOR";"LON" )"; auto options = csv::csv_options{} .mapping_kind(csv::csv_mapping_kind::n_rows) .subfield_delimiter(';'); json expected = R"( [ ["calculationPeriodCenters","paymentCenters","resetCenters"], [ ["NY","LON"],"TOR","LON" ], ["NY","LON", ["TOR","LON"] ], [ ["NY","LON"],"TOR","LON" ], ["NY","LON", ["TOR","LON"] ] ] )"_json; JSONCONS_TRY { json j = csv::decode_csv(s,options); CHECK(expected == j); //std::cout << pretty_print(j) << '\n'; } JSONCONS_CATCH (const std::exception& e) { std::cerr << e.what() << '\n'; } } TEST_CASE("test_m_columns") { const std::string s = R"(calculationPeriodCenters,paymentCenters,resetCenters NY;LON,TOR,LON NY,LON,TOR;LON "NY";"LON","TOR","LON" "NY","LON","TOR";"LON" )"; auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::m_columns) .subfield_delimiter(';'); json expected = R"( { "calculationPeriodCenters": [ ["NY","LON"],"NY", ["NY","LON"],"NY" ], "paymentCenters": ["TOR","LON","TOR","LON"], "resetCenters": ["LON", ["TOR","LON"],"LON", ["TOR","LON"] ] } )"_json; json j = csv::decode_csv(s,options); CHECK(expected == j); } jsoncons-1.3.2/test/csv/src/csv_tests.cpp000066400000000000000000001456231477700171100204530ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("csv subfield delimiter tests") { SECTION("n_objects tests") { const std::string input = R"( [ {"a":[1,-2,3.0],"b":[true,false,null]}, {"a":["7","8","9"],"b":["10","11","12"]} ] )"; json j = json::parse(input); //std::cout << pretty_print(j) << "\n\n"; auto options = csv::csv_options{} .assume_header(true) .subfield_delimiter(';') .quote_style(csv::quote_style_kind::nonnumeric) .mapping_kind(csv::csv_mapping_kind::n_objects); std::string output; csv::encode_csv(j, output, options); json other = csv::decode_csv(output, options); //std::cout << pretty_print(other) << "\n\n"; CHECK(j == other); } SECTION("n_rows tests") { const std::string input = R"( [ [[1,2,3],[4,5,6]], [[7,8,9],[10,11,12]] ] )"; json j = json::parse(input); //std::cout << pretty_print(j) << "\n\n"; auto options = csv::csv_options{} .subfield_delimiter(';'); std::string output; csv::encode_csv(j, output, options); json other = csv::decode_csv(output, options); CHECK(j == other); } SECTION("m_columns tests") { const std::string input = R"( { "a" : [[1,true,null],[-4,5.5,"6"]], "b" : [[7,8,9],[10,11,12]], "c" : [15,16,17] } )"; json j = json::parse(input); //std::cout << pretty_print(j) << "\n\n"; auto options = csv::csv_options{} .subfield_delimiter(';') .quote_style(csv::quote_style_kind::nonnumeric) .mapping_kind(csv::csv_mapping_kind::m_columns) .assume_header(true) .ignore_empty_values(true); std::string output; csv::encode_csv(j, output, options); //std::cout << output << "\n\n"; json other = csv::decode_csv(output, options); //std::cout << other << "\n\n"; CHECK(j == other); } } TEST_CASE("csv_test_empty_values_with_defaults x") { std::string input = "bool-f,string-f" "\n,"; std::istringstream is(input); json_decoder decoder; auto options = csv::csv_options{} .assume_header(true); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); //std::cout << pretty_print(val) << '\n'; CHECK(val[0]["string-f"].as() == ""); } TEST_CASE("n_objects_test") { const std::string bond_yields = R"(Date,1Y,2Y,3Y,5Y 2017-01-09,0.0062,0.0075,0.0083,0.011 2017-01-08,0.0063,0.0076,0.0084,0.0112 2017-01-07,0.0063,0.0076,0.0084,0.0112 )"; json_decoder decoder; auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_rows); csv::csv_string_reader reader1(bond_yields,decoder,options); reader1.read(); ojson val1 = decoder.get_result(); //std::cout << "\n(1)\n"<< pretty_print(val1) << "\n"; CHECK(4 == val1.size()); options.assume_header(true); options.mapping_kind(csv::csv_mapping_kind::n_objects); csv::csv_string_reader reader2(bond_yields,decoder,options); reader2.read(); ojson val2 = decoder.get_result(); //std::cout << "\n(2)\n"<< pretty_print(val2) << "\n"; REQUIRE(3 == val2.size()); CHECK("2017-01-09" == val2[0]["Date"].as()); } TEST_CASE("m_columns_test") { const std::string bond_yields = R"(Date,ProductType,1Y,2Y,3Y,5Y 2017-01-09,"Bond",0.0062,0.0075,0.0083,0.011 2017-01-08,"Bond",0.0063,0.0076,0.0084,0.0112 2017-01-08,"Bond",0.0063,0.0076,0.0084,0.0112 )"; json_decoder decoder; auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::m_columns); std::istringstream is(bond_yields); csv::csv_stream_reader reader(is, decoder, options); reader.read(); ojson j = decoder.get_result(); CHECK(6 == j.size()); CHECK(3 == j["Date"].size()); CHECK(3 == j["1Y"].size()); CHECK(3 == j["2Y"].size()); CHECK(3 == j["3Y"].size()); CHECK(3 == j["5Y"].size()); } TEST_CASE("csv ignore_empty_value") { const std::string bond_yields = R"(Date,ProductType,1Y,2Y,3Y,5Y 2017-01-09,"Bond",0.0062,0.0075,0.0083,0.011 2017-01-08,"Bond",0.0063,0.0076,,0.0112 2017-01-08,"Bond",0.0063,0.0076,0.0084, )"; //std::cout << bond_yields << '\n' << "\n\n"; SECTION("m_columns") { json_decoder decoder; auto options = csv::csv_options{} .assume_header(true) .ignore_empty_values(true) .mapping_kind(csv::csv_mapping_kind::m_columns); std::istringstream is(bond_yields); csv::csv_stream_reader reader(is, decoder, options); reader.read(); ojson j = decoder.get_result(); //std::cout << "\n(1)\n"<< pretty_print(j) << "\n"; CHECK(6 == j.size()); CHECK(3 == j["Date"].size()); CHECK(3 == j["1Y"].size()); CHECK(3 == j["2Y"].size()); CHECK(2 == j["3Y"].size()); CHECK(2 == j["5Y"].size()); } /* SECTION("n_rows") { json_decoder decoder; auto options = csv::csv_options{} options.assume_header(false) .ignore_empty_values(true) .mapping_kind(csv::csv_mapping_kind::n_rows); std::istringstream is(bond_yields); csv::csv_stream_reader reader(is, decoder, options); reader.read(); ojson j = decoder.get_result(); std::cout << "\n(1)\n"<< pretty_print(j) << "\n\n"; } */ } TEST_CASE("csv_test_empty_values") { std::string input = "bool-f,int-f,float-f,string-f" "\n,,,," "\ntrue,12,24.7,\"test string\"," "\n,,,,"; std::istringstream is(input); json_decoder decoder; auto options = csv::csv_options{} .assume_header(true) .column_types("boolean,integer,float,string"); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(val[0]["bool-f"].is_null()); CHECK(val[0]["bool-f"].is()); CHECK(val[0]["int-f"].is_null()); CHECK(val[0]["int-f"].is()); CHECK(val[0]["float-f"].is_null()); CHECK(val[0]["float-f"].is()); CHECK(val[0]["string-f"].as() == ""); CHECK(val[0]["string-f"].is()); CHECK(val[1]["bool-f"] .as()== true); CHECK(val[1]["bool-f"].is()); CHECK(val[1]["int-f"] .as()== 12); CHECK(val[1]["int-f"].is()); CHECK(val[1]["float-f"] .as()== 24.7); CHECK(val[1]["float-f"].is()); CHECK(val[1]["string-f"].as() == "test string"); CHECK(val[1]["string-f"].is()); CHECK(val[0]["bool-f"].is_null()); CHECK(val[0]["bool-f"].is()); CHECK(val[0]["int-f"].is_null()); CHECK(val[0]["int-f"].is()); CHECK(val[0]["float-f"].is_null()); CHECK(val[0]["float-f"].is()); CHECK(val[0]["string-f"] .as() == ""); CHECK(val[0]["string-f"].is()); } TEST_CASE("csv_test_empty_values_with_defaults") { std::string input = "bool-f,int-f,float-f,string-f" "\n,,,," "\ntrue,12,24.7,\"test string\"," "\n,,,,"; std::istringstream is(input); json_decoder decoder; auto options = csv::csv_options{} .assume_header(true) .column_types("boolean,integer,float,string") .column_defaults("false,0,0.0,\"\""); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); //std::cout << pretty_print(val) << '\n'; CHECK(val[0]["bool-f"].as() == false); CHECK(val[0]["bool-f"].is()); CHECK(val[0]["int-f"] .as()== 0); CHECK(val[0]["int-f"].is()); CHECK(val[0]["float-f"].as() == 0.0); CHECK(val[0]["float-f"].is()); CHECK(val[0]["string-f"] .as() == ""); CHECK(val[0]["string-f"].is()); CHECK(val[1]["bool-f"] .as()== true); CHECK(val[1]["bool-f"].is()); CHECK(val[1]["int-f"] .as()== 12); CHECK(val[1]["int-f"].is()); CHECK(val[1]["float-f"] .as()== 24.7); CHECK(val[1]["float-f"].is()); CHECK(val[1]["string-f"].as() == "test string"); CHECK(val[1]["string-f"].is()); CHECK(val[2]["bool-f"].as() == false); CHECK(val[2]["bool-f"].is()); CHECK(val[2]["int-f"] .as()== 0); CHECK(val[2]["int-f"].is()); CHECK(val[2]["float-f"].as() == 0.0); CHECK(val[2]["float-f"].is()); CHECK(val[2]["string-f"].as() == ""); CHECK(val[2]["string-f"].is()); } TEST_CASE("csv_test_empty_values_with_empty_defaults") { std::string input = "bool-f,int-f,float-f,string-f" "\n,,,," "\ntrue,12,24.7,\"test string\"," "\n,,,,"; std::istringstream is(input); json_decoder decoder; auto options = csv::csv_options{} .assume_header(true) .column_types("boolean,integer,float,string") .column_defaults(",,,"); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(val[0]["bool-f"].is_null()); CHECK(val[0]["bool-f"].is()); CHECK(val[0]["int-f"].is_null()); CHECK(val[0]["int-f"].is()); CHECK(val[0]["float-f"].is_null()); CHECK(val[0]["float-f"].is()); CHECK(val[0]["string-f"] .as() == ""); CHECK(val[0]["string-f"].is()); CHECK(val[1]["bool-f"] .as() == true); CHECK(val[1]["bool-f"].is()); CHECK(val[1]["int-f"] .as()== 12); CHECK(val[1]["int-f"].is()); CHECK(val[1]["float-f"] .as()== 24.7); CHECK(val[1]["float-f"].is()); CHECK(val[1]["string-f"].as() == "test string"); CHECK(val[1]["string-f"].is()); CHECK(val[0]["bool-f"].is_null()); CHECK(val[0]["bool-f"].is()); CHECK(val[0]["int-f"].is_null()); CHECK(val[0]["int-f"].is()); CHECK(val[0]["float-f"].is_null()); CHECK(val[0]["float-f"].is()); CHECK(val[0]["string-f"] .as() == ""); CHECK(val[0]["string-f"].is()); } TEST_CASE("csv_test1_array_1col_skip1_a") { std::string text = "a\n1\n4"; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .header_lines(1); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(2 == val.size()); CHECK(1 == val[0].size()); CHECK(1 == val[1].size()); CHECK(json(1) == val[0][0]); CHECK(json(4) == val[1][0]); } TEST_CASE("csv_test1_array_1col_skip1_b") { std::string text = "a\n1\n4"; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .header_lines(1) .infer_types(false); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(2 == val.size()); CHECK(1 == val[0].size()); CHECK(1 == val[1].size()); CHECK(val[0][0]==json("1")); CHECK(val[1][0]==json("4")); } TEST_CASE("csv_test1_array_1col_a") { std::string text = "1\n4"; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .assume_header(false); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(2 == val.size()); CHECK(1 == val[0].size()); CHECK(1 == val[1].size()); CHECK(json(1) == val[0][0]); CHECK(json(4) == val[1][0]); } TEST_CASE("csv_test1_array_1col_b") { std::string text = "1\n4"; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .assume_header(false) .infer_types(false); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(2 == val.size()); CHECK(1 == val[0].size()); CHECK(1 == val[1].size()); CHECK(val[0][0]==json("1")); CHECK(val[1][0]==json("4")); } TEST_CASE("csv_test1_array_3cols") { std::string text = "a,b,c\n1,2,3\n4,5,6"; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .assume_header(false); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(3 == val.size()); CHECK(3 == val[0].size()); CHECK(3 == val[1].size()); CHECK(3 == val[2].size()); CHECK(val[0][0]==json("a")); CHECK(val[0][1]==json("b")); CHECK(val[0][2]==json("c")); CHECK(json(1) == val[1][0]); CHECK(json(2) == val[1][1]); CHECK(json(3) == val[1][2]); CHECK(json(4) == val[2][0]); CHECK(json(5) == val[2][1]); CHECK(json(6) == val[2][2]); } TEST_CASE("csv_test1_array_3cols_trim_leading") { std::string text = "a ,b ,c \n 1, 2, 3\n 4 , 5 , 6 "; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .assume_header(false) .trim_leading(true); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(3 == val.size()); CHECK(3 == val[0].size()); CHECK(3 == val[1].size()); CHECK(3 == val[2].size()); CHECK(val[0][0]==json("a ")); CHECK(val[0][1]==json("b ")); CHECK(val[0][2]==json("c ")); CHECK(json(1) == val[1][0]); CHECK(json(2) == val[1][1]); CHECK(json(3) == val[1][2]); CHECK(val[2][0]==json("4 ")); CHECK(val[2][1]==json("5 ")); CHECK(val[2][2]==json("6 ")); } TEST_CASE("csv_test1_array_3cols_trim_trailing") { std::string text = "a ,b ,c \n 1, 2, 3\n 4 , 5 , 6 "; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .assume_header(false) .trim_trailing(true); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(3 == val.size()); CHECK(3 == val[0].size()); CHECK(3 == val[1].size()); CHECK(3 == val[2].size()); CHECK(val[0][0]==json("a")); CHECK(val[0][1]==json("b")); CHECK(val[0][2]==json("c")); CHECK(json(" 1") == val[1][0]); CHECK(val[1][1]==json(" 2")); CHECK(val[1][2]==json(" 3")); CHECK(val[2][0]==json(" 4")); CHECK(val[2][1]==json(" 5")); CHECK(val[2][2]==json(" 6")); } TEST_CASE("csv_test1_array_3cols_trim") { std::string text = "a ,, \n 1, 2, 3\n 4 , 5 , 6 "; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .assume_header(false) .trim(true) .unquoted_empty_value_is_null(true); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(3 == val.size()); CHECK(3 == val[0].size()); CHECK(3 == val[1].size()); CHECK(3 == val[2].size()); CHECK(val[0][0]==json("a")); CHECK(val[0][1]==json::null()); CHECK(val[0][2]==json::null()); CHECK(json(1) == val[1][0]); CHECK(json(2) == val[1][1]); CHECK(json(3) == val[1][2]); CHECK(json(4) == val[2][0]); CHECK(json(5) == val[2][1]); CHECK(json(6) == val[2][2]); } TEST_CASE("csv_test1_array_3cols_comment") { std::string text = "a,b,c\n#1,2,3\n4,5,6"; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .comment_starter('#'); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(2 == val.size()); CHECK(3 == val[0].size()); CHECK(3 == val[1].size()); CHECK(val[0][0]==json("a")); CHECK(val[0][1]==json("b")); CHECK(val[0][2]==json("c")); CHECK(json(4) == val[1][0]); CHECK(json(5) == val[1][1]); CHECK(json(6) == val[1][2]); } TEST_CASE("csv comment header line") { std::string data = "#a,b,c\nA,B,C\n1,2,3"; auto options = csv::csv_options{} .comment_starter('#') .assume_header(true); auto j = csv::decode_csv(data, options); REQUIRE(j.is_array()); REQUIRE(1 == j.size()); REQUIRE(1 == j[0]["A"].as()); REQUIRE(2 == j[0]["B"].as()); REQUIRE(3 == j[0]["C"].as()); } TEST_CASE("csv_test1_object_1col") { std::string text = "a\n1\n4"; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .assume_header(true); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(2 == val.size()); CHECK(1 == val[0].size()); CHECK(1 == val[1].size()); CHECK(json(1) == val[0]["a"]); CHECK(json(4) == val[1]["a"]); } TEST_CASE("csv_test1_object_3cols") { std::string text = "a,b,c\n1,2,3\n4,5,6"; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .assume_header(true); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(2 == val.size()); CHECK(3 == val[0].size()); CHECK(3 == val[1].size()); CHECK(json(1) == val[0]["a"]); CHECK(json(2) == val[0]["b"]); CHECK(json(3) == val[0]["c"]); CHECK(json(4) == val[1]["a"]); CHECK(json(5) == val[1]["b"]); CHECK(json(6) == val[1]["c"]); } TEST_CASE("csv_test1_object_3cols_header") { SECTION("test 1") { std::string text = "a,b,c\n1,2,3\n4,5,6"; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .column_names("x,y,z") .header_lines(1); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(2 == val.size()); CHECK(3 == val[0].size()); CHECK(3 == val[1].size()); CHECK(json(1) == val[0]["x"]); CHECK(json(2) == val[0]["y"]); CHECK(json(3) == val[0]["z"]); CHECK(json(4) == val[1]["x"]); CHECK(json(5) == val[1]["y"]); CHECK(json(6) == val[1]["z"]); } SECTION("test 2") { std::string text = "a,b,c\n1,2,3\n4,5,6"; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .column_names("x,y") .header_lines(1); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(2 == val.size()); CHECK(3 == val[0].size()); CHECK(3 == val[1].size()); CHECK(json(1) == val[0]["x"]); CHECK(json(2) == val[0]["y"]); CHECK(json(3) == val[0]["c"]); CHECK(json(4) == val[1]["x"]); CHECK(json(5) == val[1]["y"]); CHECK(json(6) == val[1]["c"]); } } TEST_CASE("csv_test1_object_3cols_bool") { std::string text = "a,b,c\n1,0,1\ntrue,FalSe,TrUe"; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .column_names("x,y,z") .column_types("boolean,boolean,boolean") .header_lines(1); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(2 == val.size()); CHECK(3 == val[0].size()); CHECK(3 == val[1].size()); CHECK(val[0]["x"]==json(true)); CHECK(val[0]["y"]==json(false)); CHECK(val[0]["z"]==json(true)); CHECK(val[1]["x"]==json(true)); CHECK(val[1]["y"]==json(false)); CHECK(val[1]["z"]==json(true)); } TEST_CASE("csv_test1_object_1col_quoted") { std::string text = "a\n\"1\"\n\"4\""; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .assume_header(true); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); REQUIRE(2 == val.size()); CHECK(1 == val[0].size()); CHECK(1 == val[1].size()); CHECK(val[0]["a"]==json("1")); CHECK(val[1]["a"]==json("4")); } TEST_CASE("csv_test1_object_3cols_quoted") { std::string text = "a,b,c\n\"1\",\"2\",\"3\"\n4,5,\"6\""; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .assume_header(true); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(2 == val.size()); CHECK(3 == val[0].size()); CHECK(3 == val[1].size()); CHECK(val[0]["a"]==json("1")); CHECK(val[0]["b"]==json("2")); CHECK(val[0]["c"]==json("3")); CHECK(json(4) == val[1]["a"]); CHECK(json(5) == val[1]["b"]); CHECK(val[1]["c"]==json("6")); } TEST_CASE("csv_test1_array_1col_crlf") { std::string text = "1\r\n4"; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .assume_header(false); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(2 == val.size()); CHECK(1 == val[0].size()); CHECK(1 == val[1].size()); CHECK(json(1) == val[0][0]); CHECK(json(4) == val[1][0]); } TEST_CASE("csv_test1_array_3cols_crlf") { std::string text = "a,b,c\r\n1,2,3\r\n4,5,6"; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .assume_header(false); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(3 == val.size()); CHECK(3 == val[0].size()); CHECK(3 == val[1].size()); CHECK(3 == val[2].size()); CHECK(val[0][0]==json("a")); CHECK(val[0][1]==json("b")); CHECK(val[0][2]==json("c")); CHECK(json(1) == val[1][0]); CHECK(json(2) == val[1][1]); CHECK(json(3) == val[1][2]); CHECK(json(4) == val[2][0]); CHECK(json(5) == val[2][1]); CHECK(json(6) == val[2][2]); } TEST_CASE("csv_test1_object_1col_crlf") { std::string text = "a\r\n1\r\n4"; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .assume_header(true); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(2 == val.size()); CHECK(1 == val[0].size()); CHECK(1 == val[1].size()); CHECK(json(1) == val[0]["a"]); CHECK(json(4) == val[1]["a"]); } TEST_CASE("csv_test1_object_3cols_crlf") { std::string text = "a,b,c\r\n1,2,3\r\n4,5,6"; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .assume_header(true); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(2 == val.size()); CHECK(3 == val[0].size()); CHECK(3 == val[1].size()); CHECK(json(1) == val[0]["a"]); CHECK(json(2) == val[0]["b"]); CHECK(json(3) == val[0]["c"]); CHECK(json(4) == val[1]["a"]); CHECK(json(5) == val[1]["b"]); CHECK(json(6) == val[1]["c"]); } TEST_CASE("read_comma_delimited_file") { std::string in_file = "./csv/input/countries.csv"; std::ifstream is(in_file); REQUIRE(is); json_decoder decoder; auto options = csv::csv_options{} .assume_header(true); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json countries = decoder.get_result(); CHECK(4 == countries.size()); CHECK(json("ABW") == countries[0]["country_code"]); CHECK(json("ARUBA") ==countries[0]["name"]); CHECK(json("ATF") == countries[1]["country_code"]); CHECK(json("FRENCH SOUTHERN TERRITORIES, D.R. OF") == countries[1]["name"]); CHECK(json("VUT") == countries[2]["country_code"]); CHECK(json("VANUATU") ==countries[2]["name"]); CHECK(json("WLF") == countries[3]["country_code"]); CHECK(json("WALLIS & FUTUNA ISLANDS") == countries[3]["name"]); } TEST_CASE("read_comma_delimited_file_header") { std::string in_file = "./csv/input/countries.csv"; std::ifstream is(in_file); REQUIRE(is); json_decoder decoder; auto options = csv::csv_options{} .column_names("Country Code,Name") .header_lines(1); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json countries = decoder.get_result(); CHECK(4 == countries.size()); CHECK(json("ABW") == countries[0]["Country Code"]); CHECK(json("ARUBA") ==countries[0]["Name"]); CHECK(json("ATF") == countries[1]["Country Code"]); CHECK(json("FRENCH SOUTHERN TERRITORIES, D.R. OF") == countries[1]["Name"]); CHECK(json("VUT") == countries[2]["Country Code"]); CHECK(json("VANUATU") == countries[2]["Name"]); CHECK(json("WLF") == countries[3]["Country Code"]); CHECK(json("WALLIS & FUTUNA ISLANDS") == countries[3]["Name"]); } TEST_CASE("serialize_comma_delimited_file") { std::string in_file = "./csv/input/countries.json"; std::ifstream is(in_file); REQUIRE(is); auto options = csv::csv_options{} .assume_header(false); json_decoder encoder1; json_stream_reader reader1(is,encoder1); reader1.read(); ojson countries1 = encoder1.get_result(); std::stringstream ss; csv::csv_stream_encoder encoder(ss,options); countries1.dump(encoder); json_decoder encoder2; csv::csv_stream_reader reader2(ss,encoder2,options); reader2.read(); ojson countries2 = encoder2.get_result(); CHECK(countries1 == countries2); } TEST_CASE("test_tab_delimited_file") { std::string in_file = "./csv/input/employees.txt"; std::ifstream is(in_file); REQUIRE(is); json_decoder decoder; auto options = csv::csv_options{} .field_delimiter('\t') .assume_header(true); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json employees = decoder.get_result(); CHECK(4 == employees.size()); CHECK(std::string("00000001") ==employees[0]["employee-no"].as()); CHECK(std::string("00000002") ==employees[1]["employee-no"].as()); CHECK(std::string("00000003") ==employees[2]["employee-no"].as()); CHECK(std::string("00000004") ==employees[3]["employee-no"].as()); } TEST_CASE("serialize_tab_delimited_file") { std::string in_file = "./csv/input/employees.json"; std::ifstream is(in_file); REQUIRE(is); json_decoder decoder; auto options = csv::csv_options{} .assume_header(false) .header_lines(1) .column_names("dept,employee-name,employee-no,note,comment,salary") .field_delimiter('\t'); json_stream_reader reader(is,decoder); reader.read_next(); ojson employees1 = decoder.get_result(); //std::cout << pretty_print(employees1) << "\n"; std::stringstream ss; csv::csv_stream_encoder encoder(ss,options); //std::cout << pretty_print(employees1) << '\n'; employees1.dump(encoder); //std::cout << ss.str() << '\n'; json_decoder encoder2; csv::csv_stream_reader reader2(ss,encoder2,options); reader2.read(); ojson employees2 = encoder2.get_result(); //std::cout << pretty_print(employees2) << '\n'; CHECK(employees1.size() == employees2.size()); for (std::size_t i = 0; i < employees1.size(); ++i) { CHECK(employees1[i]["dept"] == employees2[i]["dept"]); CHECK(employees1[i]["employee-name"] ==employees2[i]["employee-name"]); CHECK(employees1[i]["employee-no"] ==employees2[i]["employee-no"]); CHECK(employees1[i]["salary"] == employees2[i]["salary"]); CHECK(employees1[i].get_value_or("note","") == employees2[i].get_value_or("note","")); } } TEST_CASE("csv_test1_array_3cols_grouped1") { std::string text = "1,2,3\n4,5,6\n7,8,9"; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .assume_header(false) .column_types("integer,integer*"); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); CHECK(3 == val.size()); CHECK(3 == val[0].size()); CHECK(3 == val[1].size()); CHECK(3 == val[2].size()); CHECK(1 == val[0][0].as()); CHECK(2 == val[0][1].as()); CHECK(3 == val[0][2].as()); CHECK(4 == val[1][0].as()); CHECK(5 == val[1][1].as()); CHECK(6 == val[1][2].as()); CHECK(7 == val[2][0].as()); CHECK(8 == val[2][1].as()); CHECK(9 == val[2][2].as()); } TEST_CASE("csv_test1_array_3cols_grouped2") { std::string text = "1,2,3,4,5\n4,5,6,7,8\n7,8,9,10,11"; std::istringstream is(text); json_decoder decoder; auto options = csv::csv_options{} .assume_header(false) .column_types("integer,[integer,integer]*"); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json val = decoder.get_result(); //std::cout << val << '\n'; /* REQUIRE(4 == options.column_types().size()); CHECK(options.column_types()[0].first == csv::csv_column_type::integer_t); CHECK(0 == options.column_types()[0].second); CHECK(options.column_types()[1].first == csv::csv_column_type::integer_t); CHECK(1 == options.column_types()[1].second); CHECK(options.column_types()[2].first == csv::csv_column_type::integer_t); CHECK(1 == options.column_types()[2].second); CHECK(options.column_types()[3].first == csv::csv_column_type::repeat_t); CHECK(2 == options.column_types()[3].second); */ } TEST_CASE("csv_test1_repeat") { const std::string text = R"(Date,1Y,2Y,3Y,5Y 2017-01-09,0.0062,0.0075,0.0083,0.011,0.012 2017-01-08,0.0063,0.0076,0.0084,0.0112,0.013 2017-01-08,0.0063,0.0076,0.0084,0.0112,0.014 )"; std::vector result; jsoncons::csv::detail::parse_column_types(std::string("string,float*"), result); REQUIRE(3 == result.size()); CHECK(result[0].col_type == csv::csv_column_type::string_t); CHECK(0 == result[0].level); CHECK(0 == result[0].rep_count); CHECK(result[1].col_type == csv::csv_column_type::float_t); CHECK(0 == result[1].level); CHECK(0 == result[1].rep_count); CHECK(result[2].col_type == csv::csv_column_type::repeat_t); CHECK(0 == result[2].level); CHECK(1 == result[2].rep_count); std::vector result2; jsoncons::csv::detail::parse_column_types(std::string("string,[float*]"), result2); REQUIRE(3 == result2.size()); CHECK(result2[0].col_type == csv::csv_column_type::string_t); CHECK(0 == result2[0].level); CHECK(0 == result2[0].rep_count); CHECK(result2[1].col_type == csv::csv_column_type::float_t); CHECK(1 == result2[1].level); CHECK(0 == result2[1].rep_count); CHECK(result2[2].col_type == csv::csv_column_type::repeat_t); CHECK(1 == result2[2].level); //-V521 CHECK(1 == result2[2].rep_count); //-V521 std::vector result3; jsoncons::csv::detail::parse_column_types(std::string("string,[float]*"), result3); REQUIRE(3 == result3.size()); //-V521 CHECK(result3[0].col_type == csv::csv_column_type::string_t); //-V521 CHECK(0 == result3[0].level); //-V521 CHECK(0 == result3[0].rep_count); //-V521 CHECK(result3[1].col_type == csv::csv_column_type::float_t); //-V521 CHECK(1 == result3[1].level); //-V521 CHECK(0 == result3[1].rep_count); //-V521 CHECK(result3[2].col_type == csv::csv_column_type::repeat_t); //-V521 CHECK(0 == result3[2].level); //-V521 CHECK(1 == result3[2].rep_count); //-V521 } TEST_CASE("csv_test1_repeat2") { auto options1 = csv::csv_options{} .column_types("[integer,string]*"); //for (auto x : options1.column_types()) //{ // std::cout << (int)x.col_type << " " << x.level << " " << x.rep_count << '\n'; //} } TEST_CASE("empty_line_test_1") { std::string input = R"(country_code,name ABW,ARUBA ATF,"FRENCH SOUTHERN TERRITORIES, D.R. OF" VUT,VANUATU WLF,WALLIS & FUTUNA ISLANDS )"; std::istringstream is(input); json_decoder decoder; auto options = csv::csv_options{} .assume_header(true); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json j = decoder.get_result(); REQUIRE(4 == j.size()); //-V521 CHECK(j[0]["country_code"].as() == std::string("ABW")); //-V521 CHECK(j[0]["name"].as() == std::string("ARUBA")); //-V521 CHECK(j[1]["country_code"].as() == std::string("ATF")); //-V521 CHECK(j[1]["name"].as() == std::string("FRENCH SOUTHERN TERRITORIES, D.R. OF")); //-V521 CHECK(j[2]["country_code"].as() == std::string("VUT")); //-V521 CHECK(j[2]["name"].as() == std::string("VANUATU")); //-V521 CHECK(j[3]["country_code"].as() == std::string("WLF")); //-V521 CHECK(j[3]["name"].as() == std::string("WALLIS & FUTUNA ISLANDS")); //-V521 //std::cout << pretty_print(j) << '\n'; } TEST_CASE("empty_line_test_2") { std::string input = R"(country_code,name ABW,ARUBA ATF,"FRENCH SOUTHERN TERRITORIES, D.R. OF" VUT,VANUATU WLF,WALLIS & FUTUNA ISLANDS )"; std::istringstream is(input); json_decoder decoder; auto options = csv::csv_options{} .assume_header(true) .ignore_empty_lines(false); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json j = decoder.get_result(); //std::cout << pretty_print(j) << "\n"; REQUIRE(5 == j.size()); //-V521 CHECK(j[0]["country_code"].as() == std::string("ABW")); //-V521 CHECK(j[0]["name"].as() == std::string("ARUBA")); //-V521 CHECK(!j[1].contains("country_code")); // ok, no delimiter //-V521 CHECK(j[2]["country_code"].as() == std::string("ATF")); //-V521 CHECK(j[2]["name"].as() == std::string("FRENCH SOUTHERN TERRITORIES, D.R. OF")); //-V521 CHECK(j[3]["country_code"].as() == std::string("VUT")); //-V521 CHECK(j[3]["name"].as() == std::string("VANUATU")); //-V521 CHECK(j[4]["country_code"].as() == std::string("WLF")); //-V521 CHECK(j[4]["name"].as() == std::string("WALLIS & FUTUNA ISLANDS")); //-V521 } TEST_CASE("line_with_one_space") { std::string input = R"(country_code,name ABW,ARUBA ATF,"FRENCH SOUTHERN TERRITORIES, D.R. OF" VUT,VANUATU WLF,WALLIS & FUTUNA ISLANDS )"; std::istringstream is(input); json_decoder decoder; auto options = csv::csv_options{} .assume_header(true); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json j = decoder.get_result(); REQUIRE(5 == j.size()); //-V521 CHECK(j[0]["country_code"].as() == std::string("ABW")); //-V521 CHECK(j[0]["name"].as() == std::string("ARUBA")); //-V521 CHECK(j[1]["country_code"].as() == std::string(" ")); // ok, one space, no delimiter //-V521 CHECK(j[2]["country_code"].as() == std::string("ATF")); //-V521 CHECK(j[2]["name"].as() == std::string("FRENCH SOUTHERN TERRITORIES, D.R. OF")); //-V521 CHECK(j[3]["country_code"].as() == std::string("VUT")); //-V521 CHECK(j[3]["name"].as() == std::string("VANUATU")); //-V521 CHECK(j[4]["country_code"].as() == std::string("WLF")); //-V521 CHECK(j[4]["name"].as() == std::string("WALLIS & FUTUNA ISLANDS")); //-V521 //std::cout << pretty_print(j) << '\n'; } TEST_CASE("line_with_one_space_and_trim") { std::string input = R"(country_code,name ABW,ARUBA ATF,"FRENCH SOUTHERN TERRITORIES, D.R. OF" VUT,VANUATU WLF,WALLIS & FUTUNA ISLANDS )"; std::istringstream is(input); json_decoder decoder; auto options = csv::csv_options{} .assume_header(true) .trim(true); csv::csv_stream_reader reader(is,decoder,options); reader.read(); json j = decoder.get_result(); REQUIRE(4 == j.size()); //-V521 CHECK(j[0]["country_code"].as() == std::string("ABW")); //-V521 CHECK(j[0]["name"].as() == std::string("ARUBA")); //-V521 CHECK(j[1]["country_code"].as() == std::string("ATF")); //-V521 CHECK(j[1]["name"].as() == std::string("FRENCH SOUTHERN TERRITORIES, D.R. OF")); //-V521 CHECK(j[2]["country_code"].as() == std::string("VUT")); //-V521 CHECK(j[2]["name"].as() == std::string("VANUATU")); //-V521 CHECK(j[3]["country_code"].as() == std::string("WLF")); //-V521 CHECK(j[3]["name"].as() == std::string("WALLIS & FUTUNA ISLANDS")); //-V521 //std::cout << pretty_print(j) << '\n'; } TEST_CASE("Test decode_csv, terminating newline") { std::string data = "some label\nsome value\nanother value\n"; SECTION("From string") { auto options = csv::csv_options{} .assume_header(true); auto j = csv::decode_csv(data,options); REQUIRE(j.is_array()); //-V521 REQUIRE(2 == j.size()); //-V521 CHECK(j[0]["some label"].as() == std::string("some value")); //-V521 CHECK(j[1]["some label"].as() == std::string("another value")); //-V521 } SECTION("From stream") { std::stringstream is(data); auto options = csv::csv_options{} .assume_header(true); auto j = csv::decode_csv(is,options); REQUIRE(j.is_array()); //-V521 REQUIRE(2 == j.size()); //-V521 CHECK(j[0]["some label"].as() == std::string("some value")); //-V521 CHECK(j[1]["some label"].as() == std::string("another value")); //-V521 } SECTION("m_columns") { auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::m_columns); auto j = csv::decode_csv(data,options); REQUIRE(j.is_object()); //-V521 REQUIRE(1 == j.size()); //-V521 CHECK(j["some label"][0].as() == std::string("some value")); //-V521 CHECK(j["some label"][1].as() == std::string("another value")); //-V521 } } TEST_CASE("Test decode_csv, no terminating newline") { std::string data = "some label\nsome value\nanother value"; SECTION("From string") { auto options = csv::csv_options{} .assume_header(true); auto j = csv::decode_csv(data,options); REQUIRE(j.is_array()); //-V521 REQUIRE(2 == j.size()); //-V521 CHECK(j[0]["some label"].as() == std::string("some value")); //-V521 CHECK(j[1]["some label"].as() == std::string("another value")); //-V521 } SECTION("From stream") { std::stringstream is(data); auto options = csv::csv_options{} .assume_header(true); auto j = csv::decode_csv(is,options); REQUIRE(j.is_array()); //-V521 REQUIRE(2 == j.size()); //-V521 CHECK(j[0]["some label"].as() == std::string("some value")); //-V521 CHECK(j[1]["some label"].as() == std::string("another value")); //-V521 } SECTION("m_columns") { auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::m_columns); auto j = csv::decode_csv(data,options); REQUIRE(j.is_object()); //-V521 REQUIRE(1 == j.size()); //-V521 CHECK(j["some label"][0].as() == std::string("some value")); //-V521 CHECK(j["some label"][1].as() == std::string("another value")); //-V521 } } TEST_CASE("test encode_csv") { json j(json_array_arg); j.push_back(json(json_object_arg, { {"a",1},{"b",2} })); SECTION("To stream") { auto options = csv::csv_options{} .assume_header(true); std::stringstream ss; csv::encode_csv(j, ss, options); auto j2 = csv::decode_csv(ss, options); REQUIRE(j2.is_array()); //-V521 REQUIRE(1 == j2.size()); //-V521 CHECK(1 == j2[0]["a"].as()); //-V521 CHECK(2 == j2[0]["b"].as()); //-V521 } } TEST_CASE("test_type_inference") { const std::string input = R"(customer_name,has_coupon,phone_number,zip_code,sales_tax_rate,total_amount "John Roe",true,0272561313,01001,0.05,431.65 "Jane Doe",false,416-272-2561,55416,0.15,480.70 "Joe Bloggs",false,"4162722561","55416",0.15,300.70 "John Smith",FALSE,NULL,22313-1450,0.15,300.70 )"; SECTION("n_rows") { auto expected = ojson::parse(R"( [ ["customer_name", "has_coupon", "phone_number", "zip_code", "sales_tax_rate", "total_amount"], ["John Roe", true, "0272561313", "01001", 0.05, 431.65], ["Jane Doe", false, "416-272-2561", 55416, 0.15, 480.7], ["Joe Bloggs", false, "4162722561", "55416", 0.15, 300.7], ["John Smith", false, null, "22313-1450", 0.15, 300.7] ] )"); auto options = csv::csv_options{} .mapping_kind(csv::csv_mapping_kind::n_rows); ojson j = csv::decode_csv(input,options); REQUIRE(expected == j); //-V521 } SECTION("n_objects") { auto expected = ojson::parse(R"( [ { "customer_name": "John Roe", "has_coupon": true, "phone_number": "0272561313", "zip_code": "01001", "sales_tax_rate": 0.05, "total_amount": 431.65 }, { "customer_name": "Jane Doe", "has_coupon": false, "phone_number": "416-272-2561", "zip_code": 55416, "sales_tax_rate": 0.15, "total_amount": 480.7 }, { "customer_name": "Joe Bloggs", "has_coupon": false, "phone_number": "4162722561", "zip_code": "55416", "sales_tax_rate": 0.15, "total_amount": 300.7 }, { "customer_name": "John Smith", "has_coupon": false, "phone_number": null, "zip_code": "22313-1450", "sales_tax_rate": 0.15, "total_amount": 300.7 } ] )"); auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_objects); ojson j = csv::decode_csv(input,options); REQUIRE(expected == j); //-V521 } SECTION("m_columns") { auto expected = ojson::parse(R"( { "customer_name": ["John Roe", "Jane Doe", "Joe Bloggs", "John Smith"], "has_coupon": [true, false, false, false], "phone_number": ["0272561313", "416-272-2561", "4162722561", null], "zip_code": ["01001", 55416, "55416", "22313-1450"], "sales_tax_rate": [0.05, 0.15, 0.15, 0.15], "total_amount": [431.65, 480.7, 300.7, 300.7] } )"); auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::m_columns); ojson j = csv::decode_csv(input,options); REQUIRE(expected == j); //-V521 } } TEST_CASE("csv_options lossless_number") { const std::string input = R"(index_id,observation_date,rate EUR_LIBOR_06M,2015-10-23,0.0000214 EUR_LIBOR_06M,2015-10-26,0.0000143 EUR_LIBOR_06M,2015-10-27,0.0000001 )"; auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_objects) .trim(true) .lossless_number(true); ojson j = csv::decode_csv(input,options); REQUIRE(3 == j.size()); //-V521 CHECK(j[0]["rate"].tag() == semantic_tag::bigdec); //-V521 CHECK((j[0]["rate"].as() == "0.0000214")); //-V521 CHECK(j[1]["rate"].tag() == semantic_tag::bigdec); //-V521 CHECK((j[1]["rate"].as() == "0.0000143")); //-V521 CHECK(j[2]["rate"].tag() == semantic_tag::bigdec); //-V521 CHECK((j[2]["rate"].as() == "0.0000001")); //-V521 } // Test case contributed by karimhm TEST_CASE("csv detect bom") { const std::string input = "\xEF\xBB\xBFstop_id,stop_name,stop_lat,stop_lon,location_type,parent_station\n" "\"8220B007612\",\"Hotel Merrion Street\",\"53\",\"-6\",\"\",\"\""; auto options = csv::csv_options{} .assume_header(true); std::istringstream is(input); ojson j = csv::decode_csv(is, options); REQUIRE(1 == j.size()); //-V521 ojson station = j[0]; JSONCONS_TRY { auto it = station.find("stop_id"); REQUIRE((it != station.object_range().end())); //-V521 std::string stop_id = it->value().as(); CHECK((stop_id == "8220B007612")); //-V521 } JSONCONS_CATCH (const std::exception& e) { std::cout << e.what() << '\n'; } } /* #if defined(JSONCONS_HAS_STATEFUL_ALLOCATOR) && JSONCONS_HAS_STATEFUL_ALLOCATOR == 1 #include #include template using MyScopedAllocator = std::scoped_allocator_adaptor>; TEST_CASE("csv_reader constructors") { const std::string input = R"(Date,1Y,2Y,3Y,5Y 2017-01-09,0.0062,0.0075,0.0083,0.011 2017-01-08,0.0063,0.0076,0.0084,0.0112 2017-01-08,0.0063,0.0076,0.0084,0.0112 )"; SECTION("stateful allocator") { using cust_json = basic_json>; MyScopedAllocator my_allocator{1}; auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_objects); json_decoder> decoder(my_allocator, my_allocator); csv::basic_csv_reader,MyScopedAllocator> reader(input, decoder, options, my_allocator); reader.read(); cust_json j = decoder.get_result(); CHECK(3 == j.size()); //-V521 //std::cout << pretty_print(j) << "\n"; } } #endif */ TEST_CASE("infinite loop") { SECTION("Whitespace follows quoted field") { char data[4] = {'\"', '\"', ' ', '\n'}; int size = 4; std::string input(data, size); json_decoder decoder; auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_rows); csv::csv_string_reader reader(input, decoder, options); std::error_code ec; reader.read(ec); CHECK(!ec); //-V521 } SECTION("Invalid character follows quoted field") { char data[4] = {'\"', '\"', '\x01', '\n'}; int size = 4; std::string input(data, size); json_decoder decoder; auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_rows); csv::csv_string_reader reader(input, decoder, options); std::error_code ec; reader.read(ec); CHECK(ec == csv::csv_errc::unexpected_char_between_fields); //-V521 } } TEST_CASE("csv_parser number detection") { SECTION("test 1") { std::string data = R"(Number 5001173100 5E10 5E-10 3e05 3e-05 5001173100E95978)"; auto options = jsoncons::csv::csv_options{} .assume_header(true) .field_delimiter(','); const auto csv = jsoncons::csv::decode_csv(data, options); CHECK(5001173100 == csv[0].at("Number").as()); CHECK(5E10 == csv[1].at("Number").as()); CHECK(5E-10 == Approx(csv[2].at("Number").as())); CHECK(3e5 == csv[3].at("Number").as()); CHECK(3e-5 == Approx(csv[4].at("Number").as())); CHECK(std::numeric_limits::infinity() == csv[5].at("Number").as()); // infinite } SECTION("test 2") { std::string data = R"(Number 5001173100 5e10 5e-10 3e05 3e-05 5001173100E95978)"; auto options = jsoncons::csv::csv_options{} .field_delimiter(',') .header_lines(1) .mapping_kind(jsoncons::csv::csv_mapping_kind::n_rows); auto result = jsoncons::csv::decode_csv>>(data, options); CHECK(5001173100 == result[0][0]); CHECK(5E10 == result[1][0]); CHECK(5E-10 == Approx(result[2][0])); CHECK(3e5 == result[3][0]); CHECK(3e-5 == Approx(result[4][0])); CHECK(std::numeric_limits::infinity() == result[5][0]); // infinite } } TEST_CASE("csv_parser edge cases") { SECTION("\r first line, n_rows") { json_decoder decoder; std::string input = { 0x0D,0x20 }; auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_rows); csv::csv_string_reader reader(input, decoder, options); std::error_code ec; reader.read(ec); REQUIRE_FALSE(ec); auto j = decoder.get_result(); REQUIRE(1 == j.size()); REQUIRE(1 == j[0].size()); CHECK(" " == j[0][0].as_string()); } SECTION("\n first line, n_rows") { json_decoder decoder; std::string input = { '\n',0x20 }; auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_rows); csv::csv_string_reader reader(input, decoder, options); std::error_code ec; reader.read(ec); REQUIRE_FALSE(ec); auto j = decoder.get_result(); REQUIRE(1 == j.size()); REQUIRE(1 == j[0].size()); CHECK(" " == j[0][0].as_string()); } SECTION("\r\n first line, n_rows") { json_decoder decoder; std::string input = { '\r', '\n' ,0x20 }; auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_rows); csv::csv_string_reader reader(input, decoder, options); std::error_code ec; reader.read(ec); REQUIRE_FALSE(ec); auto j = decoder.get_result(); REQUIRE(1 == j.size()); REQUIRE(1 == j[0].size()); CHECK(" " == j[0][0].as_string()); } SECTION("\r first line, n_objects") { json_decoder decoder; std::string input = { 0x0D,0x20 }; auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_objects); csv::csv_string_reader reader(input, decoder, options); std::error_code ec; reader.read(ec); REQUIRE_FALSE(ec); auto j = decoder.get_result(); REQUIRE(j.is_array()); REQUIRE(1 == j.size()); REQUIRE(j[0].empty()); } } jsoncons-1.3.2/test/csv/src/encode_decode_csv_tests.cpp000066400000000000000000000174301477700171100232650ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include using namespace jsoncons; namespace { class MyIterator { const char* p_; public: using iterator_category = std::input_iterator_tag; using value_type = char; using difference_type = std::ptrdiff_t; using pointer = const char*; using reference = const char&; MyIterator(const char* p) : p_(p) { } reference operator*() const { return *p_; } pointer operator->() const { return p_; } MyIterator& operator++() { ++p_; return *this; } MyIterator operator++(int) { MyIterator temp(*this); ++*this; return temp; } bool operator!=(const MyIterator& rhs) const { return p_ != rhs.p_; } }; } // namespace TEST_CASE("encode decode csv source") { using cpp_type = std::vector>; std::string input = "\"a\",1\n\"b\",2"; auto options = csv::csv_options{} .mapping_kind(csv::csv_mapping_kind::n_rows) .assume_header(false); SECTION("from string") { cpp_type v = csv::decode_csv(input, options); REQUIRE(2 == v.size()); //-V521 CHECK(std::get<0>(v[0]) == "a"); //-V521 CHECK(1 == std::get<1>(v[0])); //-V521 CHECK(std::get<0>(v[1]) == "b"); //-V521 CHECK(2 == std::get<1>(v[1])); //-V521 std::string s2; csv::encode_csv(v, s2, options); json j1 = csv::decode_csv(input); json j2 = csv::decode_csv(s2); CHECK(j2 == j1); //-V521 json j3 = csv::decode_csv(s2.begin(), s2.end()); CHECK(j3 == j1); //-V521 } SECTION("from stream") { std::stringstream is(input); cpp_type v = csv::decode_csv(is, options); REQUIRE(2 == v.size()); //-V521 CHECK(std::get<0>(v[0]) == "a"); //-V521 CHECK(1 == std::get<1>(v[0])); //-V521 CHECK(std::get<0>(v[1]) == "b"); //-V521 CHECK(2 == std::get<1>(v[1])); //-V521 std::stringstream ss2; csv::encode_csv(v, ss2, options); json j1 = csv::decode_csv(input); json j2 = csv::decode_csv(ss2); CHECK(j2 == j1); //-V521 } SECTION("from iterator") { cpp_type v = csv::decode_csv(input.begin(), input.end(), options); REQUIRE(2 == v.size()); //-V521 CHECK(std::get<0>(v[0]) == "a"); //-V521 CHECK(1 == std::get<1>(v[0])); //-V521 CHECK(std::get<0>(v[1]) == "b"); //-V521 CHECK(2 == std::get<1>(v[1])); //-V521 std::stringstream ss2; csv::encode_csv(v, ss2, options); json j1 = csv::decode_csv(input); json j2 = csv::decode_csv(ss2); CHECK(j2 == j1); //-V521 } SECTION("from custom iterator") { MyIterator it(input.data()); MyIterator end(input.data() + input.length()); cpp_type v = csv::decode_csv(it, end, options); REQUIRE(2 == v.size()); //-V521 CHECK(std::get<0>(v[0]) == "a"); //-V521 CHECK(1 == std::get<1>(v[0])); //-V521 CHECK(std::get<0>(v[1]) == "b"); //-V521 CHECK(2 == std::get<1>(v[1])); //-V521 std::stringstream ss2; csv::encode_csv(v, ss2, options); json j1 = csv::decode_csv(input); json j2 = csv::decode_csv(ss2); CHECK(j2 == j1); //-V521 } } namespace { struct csv_string_encoder_reset_test_fixture { std::string output1; std::string output2; csv::csv_string_encoder encoder; csv_string_encoder_reset_test_fixture() : encoder(output1, csv::csv_options().assume_header(true)) {} std::string string1() const {return output1;} std::string string2() const {return output2;} }; struct csv_stream_encoder_reset_test_fixture { std::ostringstream output1; std::ostringstream output2; csv::csv_stream_encoder encoder; csv_stream_encoder_reset_test_fixture() : encoder(output1, csv::csv_options().assume_header(true)) {} std::string string1() const {return output1.str();} std::string string2() const {return output2.str();} }; } // namespace TEMPLATE_TEST_CASE("test_csv_encoder_reset", "", csv_string_encoder_reset_test_fixture, csv_stream_encoder_reset_test_fixture) { using fixture_type = TestType; fixture_type f; // Parially encode, reset, then fully encode to same sink f.encoder.begin_array(); f.encoder.begin_array(); f.encoder.string_value("h1"); f.encoder.string_value("h2"); f.encoder.end_array(); f.encoder.begin_array(); f.encoder.uint64_value(1); // Missing column and array end f.encoder.flush(); CHECK("h1,h2\n1" == f.string1()); // streaming case f.encoder.reset(); f.encoder.begin_array(); f.encoder.begin_array(); f.encoder.string_value("h3"); f.encoder.string_value("h4"); f.encoder.end_array(); f.encoder.begin_array(); f.encoder.uint64_value(3); f.encoder.uint64_value(4); f.encoder.end_array(); f.encoder.end_array(); f.encoder.flush(); CHECK("h1,h2\n1h3,h4\n3,4\n" == f.string1()); // streaming case // Reset and encode to different sink f.encoder.reset(f.output2); f.encoder.begin_array(); f.encoder.begin_array(); f.encoder.string_value("h5"); f.encoder.string_value("h6"); f.encoder.end_array(); f.encoder.begin_array(); f.encoder.uint64_value(5); f.encoder.uint64_value(6); f.encoder.end_array(); f.encoder.end_array(); f.encoder.flush(); CHECK("h5,h6\n5,6\n" == f.string2()); } namespace { namespace ns { struct Person { std::string name; }; }} JSONCONS_ALL_MEMBER_TRAITS(ns::Person, name) #if defined(JSONCONS_HAS_STATEFUL_ALLOCATOR) && JSONCONS_HAS_STATEFUL_ALLOCATOR == 1 #include #include template using MyScopedAllocator = std::scoped_allocator_adaptor>; TEST_CASE("encode_csv allocator_set overloads") { MyScopedAllocator temp_alloc(1); auto alloc_set = temp_allocator_only(temp_alloc); json persons(json_array_arg); json person(json_object_arg); person.try_emplace("name", "John Smith"); persons.emplace_back(std::move(person)); SECTION("json, stream") { std::string s; std::stringstream ss(s); auto options = jsoncons::csv::csv_options{} .assume_header(true); options.mapping_kind(jsoncons::csv::csv_mapping_kind::n_objects); csv::encode_csv(/*alloc_set,*/ persons, ss, options); json other = csv::decode_csv(/*alloc_set,*/ ss, options); CHECK(other == persons); } SECTION("custom, stream") { std::string s; std::stringstream ss(s); auto options = jsoncons::csv::csv_options{} .assume_header(true); options.mapping_kind(jsoncons::csv::csv_mapping_kind::n_objects); csv::encode_csv(/*alloc_set,*/ persons, ss, options); auto other = csv::decode_csv>(/*alloc_set,*/ ss, options); REQUIRE(1 == other.size()); CHECK(other[0].name == persons[0].at("name").as_string()); } } #endif jsoncons-1.3.2/test/fuzz_regression/000077500000000000000000000000001477700171100175735ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/input/000077500000000000000000000000001477700171100207325ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/input/clusterfuzz-testcase-fuzz_bson-5637264110780416000066400000000000000000000025041477700171100306560ustar00rootroot00000000000000 PZ A  A  Z  ] XZ P ) XPZ  ) ] XPZ  ⁩ ) XPZ  )  XPZ   Z / ] XZ P ) XPZ  ) ] XPZ  ) XPZ  )  XPZ   XPZ  ) XPZ  ) PZ  )  XPZ    Z / ] XPZ  ) XPZ  )  XPZ   XPZ  ) XPZ  ) PZ  )  XPZ    Z / ] XZ P ) XPZ  ) ] XPZ  ) XPZ  )  XPZ   XPZ  ) XPZ  ) PZ  )  XPZ  X  XPZ  XP Z  )XPZ  ) XPZ  ) XPZ  ) XPZ   - TEjsoncons-1.3.2/test/fuzz_regression/input/clusterfuzz-testcase-fuzz_cbor-5141282369568768000066400000000000000000001224501477700171100306710ustar00rootroot00000000000000Y}d}}}}}}}}}}}}}}:AAAA5gwAAAgNAABnDQAAKA0AAAgAAABkAbAAaAGsAEwBrABRAacAOQGu AEYBswBIAbAAZAGwACIAAAAMAAAA/////yUAAAAMAAAMAAAAD wAAgCUAAAAMAAAADgAAgEsAAAAQAAAAAAAAAAUAAAAoAAAADAAAAAMAAAAoAAAADAAAAAQAAAAlAA AADAAAAAAAAIAlAAAADAAAAAcAAIAiAAAADAAAAP////8lAAAADAAAAA0AAIAoAAAADAAAAAEAAAA iAAAADAAAAP////8iAAAADAAAAP////9GAAAAcAAAAGQAAABFTUYrLEAAACQAAAAYAAAAjxcwQAAA AIAAAACAvfcqQH2JGEU3ozRFKkAAACQAAAAYAAAAAACAPwAAAMAAAACAAACAPwAAAIAAAACAIUAHA AwAAAAAAAAAB"AAAAwAAAAAAAAARgAAABQAAAAIAAAAR0RJQwMAAABGAAAAKAAAABwAAABHRElDAg AAABsMAABVDAAA/w0AACYNAAAAAAAARgAAAEwGAABABgAARU1GKypAAAAkAAAAGAAAAAAAgD8AAAC AAAAAgAAAgD8AAACAAAAAgCFABQAMAAAAAAAAAAhAAAWoBQAAnAUAAAIQwNsCAAAAAgAAAHQFAADX zcaaAAAbAaEArAHfAEgAAQAAAJBXAAABAAkAAAO6AgAABAAUAAAAAAAFAAAACwKhABsBBQAAAAwCP gCRAAQAAAAEAQ0ABAAAAC4BGAAEAAAAAgEBAAUAAAAJAgAAAAAFAAAAAQL///8AAwAAAB4ACgAAAC YGDwAKAP////8AAAAAAAAAAAA5gwAAAgNAABnDQAAKA0AAAgAAABkAbAAaAGsAEwBrABRAacAOQGu AEYBswBIAbAAZAGwACIAAAAMAAAA/////yUAAAAMAAAMAAAAD wAAgCUAAAAMAAAADgAAgEsAAAAQAAAAAAAAAAUAAAAoAAAADAAAAAMAAAAoAAAADAAAAAQAAAAlAA AADAAAAAAAAIAlAAAADAAAAAcAAIAiAAAADAAAAP////8lAAAADAAAAA0AAIAoAAAADAAAAAEAAAA iAAAADAAAAP////8iAAAADAAAAP////9GAAAAcAAAAGQAAABFTUYrLEAAACQAAAAYAAAAjxcwQAAA AIAAAACAvfcqQH2JGEU3ozRFKkAAACQAAAAYAAAAAACAPwAAAMAAAACAAACAPwAAAIAAAACAIUAHA AwAAAAAAAAAB"AAAAwAAAAAAAAARgAAABQAAAAIAAAAR0RJQwMAAABGAAAAKAAAABwAAABHRElDAg AAABsMAABVDAAA/w0AACYNAAAAAAAARgAAAEwGAABABgAARU1GKypAAAAkAAAAGAAAAAAAgD8AAAC AAAAAgAAAgD8AAACAAAAAgCFABQAMAAAAAAAAAAhAAAWoBQAAnAUAAAIQwNsCAAAAAgAAAHQFAADX zcaaAAAbAaEArAHfAEgAAQAAAJBXAAABAAkAAAO6AgAABAAUAAAAAAAFAAAACwKhABsBBQAAAAwCP gCRAAQAAAAEAQ0ABAAAAC4BGAAEAAAAAgEBAAUAAAAJAgAAAAAFAAAAAQL///8AAwAAAB4ACgAAAC YGDwAKAP////8AAAAAAAAKAAAAJgYPAAoA/////wAAAAAAAABsMAAAAcAAAD8AgAAAJbVAAAABAAAAC0BAAA JAAAA+gIFAAAAAAD///8QIgAEAAAALQEBAA4AAAAkAwUAGwHCABsB3gCJAd4AiQHCABsBwgAJAAAA +gIGAAEAAACq5v8AIgAEAAAALQECAA4AAAAkAwUAGwHCABsB3gCJAd4AiQHCABsBwgAHAAAA/AIAA ABagAAAAAQAAAAtAQMABAAAAPABAAAEAAAALQEBAAQAAADwAQIADgAAACQDBQCJAcIAqwGhAKsBvQ CJAd4AiQHCAAkAAAD6AgYAAQAAAKrm/wAiAAQAAAAtAQAADgAAACQDBQCJAcIAqwGhAKsBvQCJAd4 AiQHCAAcAAAD8AgAAALT/AAAABAAAAC0BAgAEAAAA8AEDAAQAAAAtAQEABAAAAPABAAAOAAAAJAMF AIkBwgCrAaEAPQGhABsBwgCJAcIACQAAAPoCBgABAAAAqub/ACIABAAAAC0BAAAOAAAAJAMFAIkBw gCrAaEAPQGhABsBwgCJAcIACgAAACYGDwAKAP////8BAAAAAAAKAAAAJgYPAAoA/////wAAAAAAAA oAAAAmBg8ACgD/////AAAAAAAABwAAAPwCAAAAAAAAAAAEAAAALQEDAAQAAADwAQAIBAAAAC0BAQA EAAAA8AEAABQAAAAkAwgAYAGyAFwBtgB4AbYAdAG7AIsBtQB/AbAAfAGyAGABsgAUAAAAJAMIAGAB sgBcAbYAeAG2AHQBuwCLAbUAfwGwAHwBsgBgAbIAFAAAACQDCABuAaUAagGpAIYBqQCBAa4AmQGnA IwBogCKAaUAbgGlABQAAAAkAwgAbgGlAGoBqQCGAakAgQGuAJkBpwCMAaIAigGlAG4BpQAUAAAAJA MIAFYBvQBaAbkAPQG5AEIBtAArAboANwG/ADkBvQBWAb0AFAAAACQDCABWAb0AWgG5AD0BuQBCAbQ AKwG6ADcBvwA5Ab0AVgG9ABQAAAAkAwgAYwGvAGcBqwBLAasAUAGmADgBrQBFAbIARwGvAGMBrwAU AAAAJAMIAGMBrwBnAasASwGrAFABpgA4Aa0ARQGyAEcBrwBjAa8ACgAAACYGDwAKAP////8BAAAAA AAKAAAAJgYPAAoA/////wAAAAAAAAcAAAD8gAA////AAAABAAAAC0BAAAUAAAAJAMIAGEBswBdAb cAeQG3AHUBvACMAbYAgAGxAH0BswBhAbMAFAAAACQDCABhAbMAXQZ3AHkBtwB1AbwAjAG2AIABsQB 9AbMAYQGzABQAAAAkAwgAbwGmAGsBqgCHAaoAggGvAJoBqACNAaMAiwGmAG8BpgAUAAAAJAMIAG8B pgBrAaoAhwGqAIIBrwCaAagAjQGjAIsBpgBvAaYAFAAAACQDCABXAb4AWwG6AD4BugBDAbUALAG7A DgBwAA6Ab4AVwG+ABQAAAAkAwgAVwG+AFsBugA+AboAQwG1ACwBuwA4AcAAOgG+AFcBvgAUAAAAJA MIAGQBsABoAawATAGsAFEBpwA5Aa4ARgGzAEgBsABkAbAAFAAAACQDCABkAbAAaAGsAEwBrABRAac AOQGuAEYBswBIAbAAZAGwAAoAAAAmBg8ACgD/////AQAAAAAACgAAACYGDwAKAP////8BAAAAAAAK AAAAJgYPAAoA/////wEAAAAAAAQAAAAnAf//AwAAAAAACEACCCQAAAAYAAAAAhDA2wEAAAADAAAAA AAAAAAAAAAAAAAA G0AAAEAAAAA0AAAAAgAAAAIAAAAAgI1DAAAhQwAAEUMAAHhCAwAAAP/HQUVUbUVFqexfRVRtRUX/x 0FFVFFSRSEAAAAIAAAAYgAAAAwAAAABAAAAIQAAAAgAAABiAAAADAAAAAEAAAARAAAADAAAAAgAAA AKAAAAEAAAABsBAAChAAAACQAAABAAAACRAAAAPgAAAAwAAAAQAAAAHAwAAFcMAAALAAAAE}}}}}}}}}}}}}}}}}}y}}}}}}}}}}/}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|}/}}}}}AAAAOM BAADOAAAAIQAAAAgAAAAlAAAADAAAAAcAAIAlAAAADAAAAAAAAIAWAAAADAAAAAAAAAAYAAAADAAA AAAAAAAZAAAADAAAAP///wAUAAAADAAAAA0AAABSAAAAcAEAAAEAAAAQAAAABwAAAAAAAAAAAAAAv AIAAAAAAAAHAgIiUwB5AHMAdABlAG0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAA8ncAAAAA6RQh7hkAsAGoJfJ3OJETAEU08ncNAA#A6RQh7hkAsAG oJfJ36RQh7hkAsAGoJfJ3JgCKAekUIe4LAIgBAQAAAIyQEwDLVfJ36RQh7qBd8ndEBWYPtJETAAAA AAAfAQIA/wARAgMA2AD/AAEAwADYAAEA8ABwpxwAAAAXA+kUIe4QAJABAAAAAFVVVQBwpxwAkI8TA OkUIe4hAIoBsAJbEekUIe4XALABSAcVAG0FkXxGEhCquAJbEQAAWxHmAQMAwADOAgcA/wAQAAAA4A AfASYGAAALBQQAqACdAgQAYAAtAQAAAAABBScBAAD4jxMAWyjyd+zYIQBkdgAIAAAAACUAAAAMAAA AAQAAAAoAAAAQAAAAGwEAAKEAAAAJAAAAEAAAAJEAAAA+AAAAFAAAAAwAAAANAAAAFgAAAAwAAAAY AAAAEgAAAAwAAAABAAAAGAAAAAwAAAAAAAAAGQAAAAwAAAD///8AIQAAAAgAAAAnAAAAGAAAAAQAA AAAAAAAAJbVAAAAAAAlAAAADAAAAAQAAAAlAAAADAAAAAgAAIBWAAAAMAAAABwMAADFDAAAig0AAC INAAAFAAAAGwHCABsB3gCJAd4AiQHCABsBwgAmAAAAHAAAAAMAAAAGAAAAAQAAAAAAACq5v8AJQA AAAwAAAADAAAAVgAAADAAAAAZDAAAwgwAAI0NAAAlDQAABQAAABsBwgAbAd4AiQHeAIkBwgAbAcIA JwAAABgAAAACAAAAAAAAAABagAAAAAAAJQAAAAwAAAACAAAAKAAAAAwAAAAEAAAAJQAAAAwAAAAIA ACAKAAAAAwAAAADAAAAVgAAADAAAACKDQAAVwwAAPwNAAAiDQAABQAAAIkBwgCrAaEAqwG9AIkB3g CJAcIAJgAAABwAAAADAAAABgAAAAEAAAAAAAAAqub/ACUAAAAMAAAAAwAAAFYAAAAwAAAAhw0AAFQ MAAD/DQAAJQ0AAAUAAACJAcIAqwGhAKsBvQCJAd4AiQHCACcAAAAYAAAABAAAAAAAAAAAtP8AAAAA ACUAAAAMAAAABAAAACgAAAAMAAAAAgAAACUAAAAMAAAACAAAgCgAAAAMAAAAAwAAAFYAAAAwAAAAH AwAAFcMAAD8DQAAxQwAAAUAAACJAcIAqwGhAD0BoQAbAcIAiQ0CACYAAAAcAAAAAwAAAAYAAAABAA AAAAAAAKrm/wAlAAAADAAAAAMAAABWAAAAMAAAABkMAABUDAAA/w0AAMgMAAAFAAAAiQHCAKsBoQA 9AaEAGwHCAIkBwgAnAAAAGAAAAAIAAAAAAAAAAAAAAAAAAAAlAAAADAAAAAIAAAAoAAAADAAAAAQA AAAlAAAADAAAAAgAAIAoAAAADAAAAAMAAABWAAAAPAAAAPUMAACJDAAAkQ0AAK0MAAAIAAAAYAGyA FwBtgB4AbYAdAG7AIsBtQB/AbAAfAGyAGABsgBWAAAAPAAAAPUMAACJDAAAkQ0AAK0MAAAIAAAAYA GyAFwBtgB4AbYAdAG7AIsBtQB/AbAAfAGyAGABsgBWAAAAPAAAACMNAABaDAAAwA0AAIIMAAAIAAA AbgGlAGoBqQCGAakAgQGuAJJAAAACAAA ZwkAAKoAAAAjBEwiLAQ2IkkE9CFdBMghdgSUIZQEWyG2BBwhyAT9INsE3CDvBLsgBAWaIBoFeCAxB VcgSAU1IGEFFSB5BfQfkwXVH64Fth/JBZcf5QV7HwEGXx8eBkUfOwYtH1gGFh93BgEfhQb4HpUG7h 6jBuYeswbeHsIG1h7RBs8e4AbJHvAGwx7/Br0eDwe4Hh4HtR4tB7EePQeuHk0Hqx5cB6oebYepHnw HqB6MB6kenAepHqwHqx68B60ezQewHt4Hsx7vB7geAAi9HhEIwx4jCMseNQjSHkcI2x5ZCOUebAjw Hn8I/B6TCAkfpggXH7oIJh/OCDcf4whIH/gIWx8MCW8fIQmEHzcJmx9MCbMfYgnMH3gJ5h+OCQIgp AkgILoJPiDRCV8gB6A I mP8JoyAWCsggLQrvIEQKFiFcCj8hcwpqIYsKliGjCsUhuwr0IdMKJiLrClkioQsEIocLzyFuC 5whVQtqITwLOiEkCwshCwveIPIKsiDZCoggwApfIKgKOCCPChIgdgrtH14Kyh9FCqgfLAqIHxQKaR /7CUsf4wkuH8oJEx+yCfkemQngHoAJyR5oCbIeTwmdHjYJiR4eCXYeBQlkHuwIVB7TCEQeuwg2HqI IKB6JCBwecAgRHlcICB4+CP8dJQj3HQ0I8R30B+sd2wfnHcMH4x2qB+EdkgfgHXoH4B1iB+EdSgfi HTMH5R0bB+gdBQftHe4G8h3XBvgdwQb/HasGBh6WBg8egAYYHmwGIR5XBiweQwY2Hi8GQh4bBk4eB wZbHuIFdB69BZEemgWuHngFzR5XBe0eNgUPHxcFMR/5BFQf3AR4H8AEnB+mBMAfjATlH3MECSBbBC 4gRQRSIC8EdiAaBJkgBgS8IOMD/SDDAzshqANyIZIDo*F0A+ghaAMEIhMAAAAMAAAAAgAAABMAZAA MAAAAAgAAAFYAAACgAAAAlwcAAGIJAAChBwAAaQkAACEAAABoAwQiZAMPImDGiJhAyUiYQMwImED OiJkA0MiZgNMImoDVSJvA10idQNlInsDbCKCA3IiiQN4IpEDfSKZA4EiogOFIqoDiCK0A4oivQOMI sYDjCLPA4wi2QOLIuIDiSLrA4ci8wODIvwDfiIEBHgiCwRyIhIEaiIYBGEiHgRXIiMETCITAAAADA AAAAIAAAATAAAADAAAAAEAAAAlAAAADAAAAAQAAAAlAAAADAAAAAMAAAAoAAAADAAAAAIAAAAnAAA AGAAAAAIAAAAAAAAA////AAAAAAAlAAAADAAAAAIAAAAlAAAADAAAAAgAAIATAAAADAAAAAIAAAAT AAAADAAAAAIAAABWAAAA4AAAAJIHAABbCQAApQcAAGgJAAAxAAAAgATtIXwE4SF3BNchcQTMIWsEw yFlBLkhXwSxIVgEqSFRBKEhSQSaIUIElCE6BI4hMgSIISoEgyEhBH8hGQR7IRAEdyH+A3Ih7ANuId kDbCHHA2shtANtIaEDcCGPA3QhfgN6IWwDgiFcA4shTAOVIT0DoCEwA6IQcD7CEEA/UhAQP+If8CByL9AhEi/AIbIvsCJSL7AjAi/AI6Iv0CRSL+AlAiAANbIgMDZiIHA3Ii CwN9IhMAAAAMAAAAAgAAABMAAAAMAAAAAgAAAFYAAADYAgAAkwcAAGAJAAAFCZAAoAkAAK8AAACTC tohkwraIXwKDCJlCjwiTQpqIjYKlyIfCsMiCArtIvEJFCPbCTsjxAlgI64JhCOYCaUjgwnFI2wJ5C NXCQIkQgkdJC0JOCQZCVEkBAloJPAIfiTcCJQkyQinJLcIuSSkCMokkQjaJIAI6CRuCPYkXQgCJU0 IDSU8CBclLAggJR0IKCUOCDAl/wc2JfEHPCXjB0Al1gdEJckHSCW8B0slsAdOJaMHTyWXB1AliwdQ JX8HUCV0B1AlaAdQJVwHTiVQB0wlRAdKJTgHRyUsB0UlIAdAJRQHPCUIBzgl/AYyJe8GLSXjBiYl1 gYfJckGGCW8BhAlsQYKJZUG9iR7BuIkYAbMJEYGtCQtBpwkEwaBJPoFZSThBUgkyQUqJLIFDCSaBe wjhAXNI24FrSNZzEFTSMfBS4jDgUQI+0E0yLQBJwitwRpIqQEPyKIBP4hgATtIQsDfSI XA50iNgPjIk4DFiNqA08jigOOI68D0SPEA/Yj2gMbJPADPyQIBGUkIASMJDoEsiRVBNgkcQT+JI8E JCWuBEklzgRuJe8EkiURBbYlNQXaJVoF+yWBBRomqAU5JtEFVSboBWUm/gVyJhUGfyYrBosmQgaWJ loGoSZzBqsmiwa1JqQGvia+BsUm2AbNJvIG0yYNB9gmKAfbJkQH3iZfB+EmfAfiJpgH4ia0B+Am0Q fdJu0H2SYKCNUmJwjOJkQIxyZhCL4mfCJwm0giOJu4IfyYKCW8mJQleJkEJSyZcCTg mdwkjJpMJDSatCfYlyAneJeIJxCX9CaklFwqOJTEKcSVLClIlZQozJX8KEiWZCvAkswrNJMwKqSTm CoIkAAtbJBkLMiQzCwgkTAvdI2YLryOAC4EjmQtSI7MLICPMC+0i5Qu5IgAMgyIADIMikwraIZMK2 iGTCtohEwAAAAwAAAACAAAAEwAAAAwAAAACAAAAVgAAANgCAADzBwAAKQkAAGUIAABpCQAArwAAAI kT4SGJE+EhfBPCIV0TeyFFE0ghKRMPIQkT0CDkEowgzxJoILoSRCCjEh8gjBL5H3MS0x9ZEqwfPhK GHyISYB8EEjof5hEVH8UR8B6kEcweghGoHl4RhR45EWMeEhFDHuoQJB7CEAgeqxD5HZUQ7B1+EN8d aBDTHVAQxx05ELwdIRCyHQcQqR3uD6Ad1Q+ZHbsPkR2gD4sdhg+GHWsPgh1PD38dNA99HRcPfB38D nwd3w5+HcMOgB2mDoUdiQ6JHW0OkB1PDpcdMw6gHRYOqh35DbUd3Q3CHcENzx2kDd4diQ3uHW0N/x 1SDRIeNg0mHhsNOh4ADVAe5gxnHssMfx6wDJkelgyzHnsMzx5hDOweSAwLHy0MKh8UDEsf+gttH+A LkB/HC7QfrQvbH5MLAiB6CysgYAtUIEcLgCAtC60gEwvcIPoKCyHgCjwhxwpvIa4KpCGTCtohAAyD IhcMUSIuDCEiRgzyIV0MxiF0DJohiwxwIaEMSSG4DCIhzgz9IOUM2SD7DLggEA2YICYNeSA7DVsgU Q1AIGYNJSB6DQwgjw31H6IN3x+2DcofyQ22H9wNpR/vDZMfAQ6EHxMOdR8lDmcfNQ5bH0YOUR9XDk YfZw49H3UONR+FDi4fkw4nH6IOIR+vDh0fvQ4ZH8kOFR/WDhMf4w4QH+8ODx/7Dg4fBw8NHxQPDR8 fDw0fKw8OHzcPDx9CDxEfTw8TH1oPFh9mDxkfcg8dH38PIR+KDyYflw8sH6QPMh+wDzcfvQ8/H8oP RR/XD04f4g9VH/4PaB8ZEHwfMxCSH00QqR9mEMIfgBDdH5kQ+R+yEBYgyhA0IOIQUiD5EHIgEBGSI CYRsSA6EdEgTxHxIGIRESF1ETEhhhFPIaYRiyHEEcMh3BH1IfARICIMEmAiExJyIhMSciKJE+EhiR PhIYkT4SETAAAADAAAAAIAAAATAAAADAAAAAIAAABWAAAA2AIAAFIIAABgCQAAxAgAAKAJAACvAAA AmhnQIZoZ0CGDGQMiaxkzIlMZYSI9GY8iJRm6Ig4Z5CL4GAsj4RgyI8sYVyO1GHojnxicI4kYvCNz GNsjXhj4I0kYFCQ0GC4kIBhHJAsYXiT3F3Uk4xeKJNAXnSS9F68kqxfAJJgX0CSGF94kdRfsJGQX+ CRUFwMlQxcNJTQXFiUkFx4lFRcmJQcXLCX4FjIl6xY2Jd0WOiXQFj5lxBZBJbcWQyWrFkUlnxZGJZ MWRiWGFkYlexZGJW8WRiVjFkQlWBZCJUwWQCVAFj0lNBY6JSkWNiUcFjIlEBYtJQMWKCX3FSIl6hU cJd0VFSXRFQ4lxBUGJbkV/ySdFeskgxXYJGkVwSRPFaokNRWRJBwVdiQCFVok6RQ+JNEUHyS6FAEk ohTiI4wUwiN3FKIjYRSCI0&UYiM6FEIjJxQiIxcUBSP1E8gi2BORIsETXiKsEzQikRP0IYkT4SETE nIiIBKRIj8S1yJWEgsjcxJDI5MSgyO3EsYjzBLrI+ISDyT4EjQkEBNaJCgTgCRCE6YkXRPMJHkT8y SXExklthM+JdUTZCX2E4glGRSrJTwUziVhFPAliBQQJrAULybYFEom7xRaJgUVZyYcFXQmMxWAJko ViyZiFZcmehWhJpIVqya~FbMmxRW7Jt8Vwib5FcgmFBbOJjAW0SZLFtQmZxbXJoMW2CaeFtgmuxbW JtcW0yb0FtAmERfLJi4XxCZLF70mZxe0JoQXqSagF54mvReSJtkXhCb1F3YmERhlJiwYVCZIGEImY xguJn4YGiaaGAQm tBjsJc8Y1SXpGLslBBmgJR4ZhCU4GWglUhlJJWwZKSWGGQkloBnnJLoZwyTTGZ8k7Rl5JAYaUSQgG ikkORr/I1Ma1CNsGqYjhhp4I58aSCO5Ghcj0hrkIuwasCIGG3oiBht6IpoZ0CGaGdAhmhnQIRMAAA AMAAAAAgAAABMAAAAMAAAAAgAAAFYAAADYAgAAsggAACkJAAAjCQAAaAkAAK8AAACKIuohiiLrIX4 iyyFgIoUhSCJRISwiGCELItgg5yGUINIhbyC9IUogpyElII8h/x92IdkfXSGyH0IhjB8mIWUfCCE/ H+ogGR/KIPMeqSDOHoYgqh5jIIcePiBlHhcgRB7vHyUeyB8JHrAf+h2bH+wdhR/fHW4f0h1WH8cdP x+7HScfsR0OH6cd9R6eHdwelh3CHo8dpx6IHYwegx1yHn4dVh57HToeeR0eHncdAh53HeYdeR3KHX sdrB1/HZAdhB1zHYodVh2RHTkdmh0dHaQdAB2vHeMcux3HHMgdqxzXHY8c5x1zHPgdWBwLHj0cHh4 iHDMeBxxJHusbXx7RG3cethuRHpwbqx6AG8ceaBvkHk4bAh8zGyEfGhtCHwAbZB/mGocfzRqsH7Ma 0h+ZGvkfgBoiIGYaTCBNGncgMxqkIBka0yAAGgMh5hkzIc0ZZiG0GZshmhnQIQYbeiIdG0giNBsYI SFjG7whehuRIZEbZyGoG0AhvhsZIdQb9CDrG9EgARyvIBYcjyAsHHEgQhxTIFccNyBsHB4ggB wFIJQc7R+oHNcfuxzCH88crx/iHJ0f9RyMHwYdfB8YHW4fKh1hHzsdVB9MHUofWx1AH2sdNx96HS8 fih0oH5gdIR+lHRwfsx0XH8EdEx/OHRAf2h0OH+YdDB/yHQof/h0JHwoeCR8WHgkfIx4JHy4eCh85 HgsfRh4dH1EeEB9cHhIfaR4WH3UeGh+BHh4fjR4jH5oeKR+nHi4fsx41H78ePB/MHkMf2R5LH+QeU h8BH2cfGx97HzUfkR9PH6kfaR/DH4If3h+bH/oftB8XIM0fNSDkH1Ug+x90IBEglCAoILUgPCDVIF Ag9iBkIBYhdiA2IYcgVCGoIJEhxSDJId0g/CHxICciDSFoIhUheiIVIXsiFSF6IhUheiIVIXsiEwA AAAwAAAACAAAAEwAAAAwAAAACAAAAVgAAANgCAAARCQAAYAkAAIMJAACgCQAArwAAAJso2iGbKNoh hCgMImwoPCJVKGoiPiiXIiYowyIQKO0i+ScUI+MnOyPMJ2AjtieDI6AnpSOKJ8UjdCfkI18nASRKJ x0kNSc4JCEnUSQMJ2gk+CZ+JOQmkyTRJqckvia4JKwmyiSZJtkkhyboJHYm9iRlJgIlVCYMJUQmFy U0JiAlJSYoJRYmLyUHJjYl+SU8JewlQCXeJUQl0SVIJcUlSiW4JUwlrCVOJZ8lTyWUJVAlhyVQJXw lUCVwJU8lZCVOJVglTCVNJUklQSVHJTUlRCUpJUAlHSU7JRElNyUEJTEl+CQsJeskJSXeJB4l0iQX JcUkECW6JAklniT1JIQk4SRqJMskUCS0JDYkmiQdJIAkAyRkJOojRyTSIyokuyMKJKMj7CONI8wje COsI2IjjCNOI2sjOyNLIygjLCMYIw4j9yLRItoimiLCImciriI9IpIi/SGKIuohFSF7IiEhmiJAIe AiVyEUI3QhTSOUIYwjuCHPI84h9CPjIRkk+SE+JBEiYyQpIokkQyKvJF4i1SR6IvwkmCIiJbciRyX WIm0l9yKRJRojtSU9I9glYiP6JYkjGSaxIzgm2CNUJvAjYyYGJHEmHSR+JjMkiiZKJJUmYiShJnok qyaTJLQmrCS9JsYkxCbgJMwm+iTSJhUl1yYwJdsmTCXeJmcl4CaEJeImnyXhJrwl4CbYJd0m9SXZJ hEm1CYvJs0mTCbGJmgmvSaFJrMmoSaoJr4mmytJ14mSSdLJmQnNyZ/JyMmmi cNJrUn9iXPJ94l6ifEJQUoqiUfKI4lOShxJVMoUiVtKDMlhygSJaEo8CS7KM0k1CipJO4ogiQHKVs kISkyJDopCCRUKd0jbimvI4cpgSOhKVIjuykgI9Qp7SLtKbkiByqDIgcqgyKbKNohmyjaIZso2iET AAAADAAAAAIAAAATAAAADAAAAAIAAABWAAAAxAIAAHEJAAApCQAA4gkAAGkJAACqAAAAjDHfIX8xw SFgMXohSTFHIS0xDiENMc}}8g6DCMINMwZiC+MEIgpzAdIJAw9x93MNIfXTCsH0Iwhh8mMF8fCTA5H+ ovFB/LL+8eqi/LHocvpx5kL4QePy9iHhgvQx7wLiQeyC4IHrAu+B2bLusdhC7eHW4u0h1WLscdPy6 8HSYush0OLqgd9C2fHdstmB3BLZEdpy2LHYwthR1xLYIdVi1/HTotfB0dLXsdAi17HeYsfR3JL-Ad rCyEHY8siR1yLJAdViyXHTksnx0dLKodACy1HeQrwR3HK88dqyveHZAr7h10KwAeWCsSHj0rJh4iK zoeBytQHu0qZx7SKLAeuCqZHp0qtB6DKs8eaSrsHk8qCx81KiofGypLHwEqbR/nKZAfzimH7Qp2x +bKQIggSkrIGgpVCBOKYAgNCmtIBsp3CACKQwh6Cg8Ic8obyδjaIQcqgyIeKlEiNiohIk4 q8iFkKsUhfCqaIZIqcCGpKkkhwCoiIdYq/SDsKtkgAiu4IBgrmCAuK3kgQytbIFgrQCBtKyUggSsM IJYr9R+qK98fvivJH9Erth/jK6Qf9iuTHwksgx8aLHcfLCxnHz0sWx9OLFAfXixGH24sPB99LDUfj CwtH5osJx+oLCEftiwdH8QsGR/RLBUf3iwTH+osEB/2LA4fAi0NHw4tDR8aLQ0fJi0NHzEtDR89LQ 8fSS0RH1UtEx9gLRYfbC0ZH3ktHR+ELSEfkS0mH5tKx+qLTAfti03H8MtPh/PLUUf3S1NH+ctUx8 DLmcfHS57HzcukR9RLqgfay7BH4Qu3B+dLvgfty4VIM8uMyDmLlEg/S5wIBQvkCApL68gPi/QIFMv 8CBmLxAheC8vIYkvTSGqL4khxy/BId8v8yHzLx0iDzBeIhYwcCITAAAADAAAAAIAAAATAAAADAAAA AIAAABWAAAAIAAAANAJAABhCQAA4wkAAG4JAAAxAAAAFjBwIhsweyIgMIYiJjCQIiswmiIyMKMiOD CsIj8wtCJGMLsiTTDCIlUwySJdMM8iZTDUIm0w2SJ1MN4ifjDiIocw5SKZMOsiqzDvIr4w8SLQMPE i4zDwIvUw7SIIMekiGTHiIiox2yI7MdIiSzHIIlkxvCJnMbAiczGiIn4xkiKIMYIijDF6Io8xcSKT MWgilTFfIpgxVSKZMUsimzFCIpsxNyKcMS0imzEjIpoxGCKZMQ0iljECIpQx9yGQMeshjDHfIRMAA AAMAAAAAgAAABMAAAAMAAAAAQAAACUAAAAMAAAABAAAACUAAAAMAAAAAwAAACgAAAAMAAAAAgAAAC UAAAAMAAAABwAAgCUAAAAMAAAA0AAAg.AAAAAMAAAADwAAgCUAAAAMAAAADgAAgEsAAAAQAAAAAAA AAAUAAAAoAAAADAAAAAMAAAAoAAAADAAAAAQAAAAlAAAADAAAAAAAAIAlAAAADAAAAAcAAIAiAAAA DAAAAP////8lAAAADAAAAA0AAIAoAAAADAAAAAEAAAAiAAAADAAAAP////8iAAAADAAAAP////9GA AAAcAAAAGQAAABFTUYrLEAAACQAAAAYAAAAZy+BPgAAAIAAAACAdSSBPlSeD0Wmcg9FKkAAACQAAA AYAAAAAACAPwAAAIAAAACAAACAPwAAAIAAAACAIUAHAAwAAAAAAAAABEAAAAwAAAAAAAAARgAAABQ AAAAIAAAAR0RJQwMAAABGAAAANAAAACgAAABFTUYrKkAAACQAAAAYAAAAAACAPwAAAIAAAACAAACA PwAAAIAAAACAIQAAAAgAAABiAAAADAAAAAEAAABMAAAAZAAAAGwHAACyBwAAhgoAADsKAABsBwAAs gcAABsDAACKAgAA KQCqAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAIgAAAAwAAAD/////RgAAABwAAAAQAAAARU1GKwJAAAAMAAAAAAAAAA4AAAAUAAAAAAAAABAAAA AUAAAA AAABAAEAICAQ/gAAAADoAgAAFgAAACgAAAAgAAAAQAAAAAEABAAAAAAAgAIAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/w D/AP//AAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAABmZmZmZmZmZmZmZmZoAAAAZmZmZmZmZmZmZmZmZoAAAGZmZmZmZmZm ZmZmZmZoAABmZmZmZmZmZmZmZmZmZgAAZmZmZmZmZmZmZmZmZmYAAGZmZmZmZmZ4PrQpUDwkLeg9kC5PYPb/D29v9vYGZmZgAAZgbwZvZvBm9m9mZmZmYAAGYGb2b2bwZvZvBvZmZmAABm9gb/b/b/9v9v8G ZmZgAAZmZmZmZmZmZmZmZmZmYAAGZmZmZmZmZmZmZmZmZmAABmZmZmZmZmZmZmZmZmZgAAZmZmZmZ mZmZmZmZmZmYAAGZmZmZmZmZmZmZmZmZmAABmZmZmaGZmat='' IconSize='1' AlignName='2' MatchByName='0' IconUpdate='1' UniqueID='{01E4C3DA-0013-0000-8E40-00608CF305B2}' BaseID='{6649EBFA-E92E-4D58-95A2-40628E525CDC}' PatternFlags='0' Hidden='0'>8.5110.125..ƑTZFUZZ-gmmmmmmmmmmmmmZmmmmmmmmmmmmmmmmmmmmmmmmmm0􈶥+/vZmmmmmmmmmmmmmmmmmmmmm1􈶥C+/vZ@/v~~~~~~~~~~~~~~~~~~~v~~~~~~󠿉󠟁󠁉󠟁󠁲࿲࿬󠟉󠟁󠁉O󠟁~~~󠟁󠁉󠟁~~~󠟉󠟁󠁲࿲࿉󠟁󠁉󠟁󠁲࿲࿬󠟉󠟁󠁉󠁲࿲࿬󠟉󠟁󠁉󠟁~~~~~~~࿬󠟉󠟁󠁉󠟁~~~󠟁󠁉󠟁~~~󠟉~࿲࿭FA󠟁`󠁲࿲࿉󠟁󠁉󠟁󠁲࿲࿬󠟉󠟁󠁉`AAGǔTZFUZZ-gmmmmmmmmmmmmmZmmmmmmmmmmmmmmmmmmmmmmmm2􈶥C+/vZ@/v]mmmmmmmmmmmmm2􈶥C+/v.Ƒ󠟁󠁉󠟁~~~󠟉󠟁󠁲࿲࿬󠟉󠟁󠁉󠟁~~~~~~~~~~~~~~~~~~~~v~~~~~~󠿉󠟁󠁉󠟁󠁲󠟉󠟁󠁉O󠟁~~~󠟁󠁉󠟁~~~󠟉󠟁󠁲࿲࿉󠟁󠁉󠟁󠁲࿲࿬󠟉󠟁󠁉󠁲࿲࿬󠟉󠟁󠁉󠟁~~~~~~~~~~~~~ L~~~~~~󠿉󠟁󠁉󠟁󠁲࿲࿬󠟉󠟁󠁉ҿ`AAG:ǔTZFUZZ-gmmmmmmmmmmmmmZmmmmmmmmmmmmmmmmmmmmmmmmmm0􈶥+/vZmmmmmmmmmmmmmmmmmmmmm1􈶥C+/v߅ Z@/v~~󠿉󠟁󠁉󠟁󠁲࿲࿬󠟉󠟁󠁉O󠟁~~~󠟁󠁉󠟁~~~󠟉󠟁󠁲࿲࿉󠟁󠁉󠟁󠁲࿲࿬󠟉󠟁󠁉󠁲࿲࿬󠟉󠟁󠁉󠟁~~~~~~~࿬󠟉󠟁󠁉󠟁~~~󠟁󠁉󠟁~~~󠟉~࿲࿭FA󠟁`󠁲࿲࿉󠟁󠁉󠟁󠁲࿲࿬󠟉󠟁󠁉`AAGǔTZFUZZ-gmmmmmmmmmmmmmZmmmmmmmmmmmmmmmmmmmmmmmm2􈶥C+/vZ@/v]mmmmmmmmmmmmm2􈶥C+/v.ƑJo#]AAmmmmm1􈶥C+/vZ@v/]>..ƑJu%@]2266]AAGǔTZFUZZ-ggFmmmmmmmZmmmmmmmmmmmmmmmmmmmmmmmm1􈶥C+/vZ@/vAmmmmm0􈶥C+/v22664118346046923173168730012]AAGǔTZFUZZ-gmmmmmmmmmmmmmZmmmmmmmmmmmmmmmmmmmmmmmm1􈶥C2􈶥C+/v.ƑJ#]AAmmmm1518597529m2􈶥C+/v.ƑJ#]AAmmmmm0􈶥C+/vZ@/v>..Ƒ4105Ӏ4 / &?/ 󠁍&?JMMMMMMMMMmmmmmmmmmmmmmmmmmmmmm984649239847MMMMMMMMMmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm98464923mmmmmmE ^ 9846MMMMMMMMMmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm9846MMMMMMMMMmmmmmmmmmmmmmmmmmmmmmzmmmmmmmmmmmmmmmmm98469846MMMMMMMMMmmmmmmmmmmmmmmmmmmmmm984649239847.MMMMMMMMMmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm9846 @̠94[̠98Zi̅&扈+/vi&/ 0cZA65555555c/ 0cZA65555555c/ 0cZA65555555c/ 0cZA65555555c/ 0cZA65555555c/ 0cZA65555555c/ 0cZA65555555c/ 0cZA65555555c/ 0cZA65555555c/ 0cZA65555555ʉʳ0cZA65555555c/ 0cZA65555555c/ 0cZA65555555c/ 0cZA65555555c/ ʳ0cZA65555555c/ 0cZA65555555c/ 0cZA65555555c/ 0cZAc/ 0cZA65555555c/ 0cZA65555555c/ 0cZA65555555c/ 0cZA65555555c/ 0cZA65555555c/ 0cZA65555555c/ 0cZA65555555c/ 0cZA65555555c/ 0cZA65555555c/ 0cZA65555555c/ 0cZA65555555c/ 0cZA65555555c/ 0cZA65555555c/ 128$:+/f@ސlc?1mmmmmm9847MMMMMMMMMmmmmmmmmmmmmmmmmmmmmmzmmmmmmmmmmmmmmmmm98469846,c1731697303715884105729*[Ѡ1701!࿲࿬󠟉󠟁󠁉󠟁~~~󠟉󠁉󠟁󠁲࿲࿬󠟉󠟁󠁉󠟁~~~󠟉󠟁󠁲࿲࿬󠟉󠟁󠁉󠟁~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~v~~~~~~󠿉󠟁󠁉󠟁󠁲󠟉󠟁󠁉O󠟁~~~󠟁󠁉󠟁~~~󠟉󠟁󠁲࿲࿉󠟁󠁉󠟁󠁲࿲࿬󠟉󠟁󠁉󠁲࿲࿬󠟉󠟁󠁉󠟁~~~~~~~~~~~~~ L~~~~~~󠿉󠟁󠁉󠟁󠁲࿲࿬󠟉󠟁󠁉󠟉󠟁󠁉󠁲࿲࿬󠟉󠟁󠁉󠟁~~~~~~~~~~~~~ L~~~~~~󠿉󠟁󠁉󠟁󠁲࿲࿬󠟉󠟁󠁉ҿ`AAG:ǔTZFUZZ-gmmmmmmmmmmmmmZmmmmmmmmmmmmmmmmmmmmmmmmmm0􈶥+/vZmmmmmmmmmmmmmmmmmmmmm4105?Q,'^5%}^go%f3_F sC'JJq7Ky+P8cF}>WpL/ZVi#ZVi#L]!2FUZZ-TAc22FUZZ-TAc2LLLLLLLLLLL21U]LLLLLLㆆ2]3LLLLLLLLL󠁛({;;(;~,;;;|;;;;(;~,;;;|;;;|;;|;&F;|;{;;{;;(|;|;;|;|;|;;|;|;|;{;;;|;;|;z;|;{;;{;;(|;|;;|;|;|;;|;|;;({?;텅;(;~,;;;|;;;|;;|;z;|ʅ|;;|;H;|;|;{;;({󠁛({;;(;~,;;;|;;;|;;|;&2S ^y\# 0#t S#S#t s 184 ^y\#|;;|;&F;|;{;;{;;(|;|;;|;|;|;;|;|;|;{;;;|;;|;z;|;{;;{;;(|;|;;|;|;|;;|;|;|;{;{;;{;;(|;|;;|;|;|;;|;|;|2;{;;({?;텅;(;~,;;;|;;;|;;|;z;|ʅ|;;|;H;|;|;|;{;;({;;(;~,;;;|;;;|;;|;;|;{;;{;;(|;|;;|;|;|;;|;|;|;{;;󠁛({;;(;~,;;;|;;;|;;|;&;|;{;;{;(|;|;;|;|;|;;|;|;|;{;;({󠁛({;;(;~,;;;|;;;|;;|;&/4ʚ 0'/04/0 0m604/0R7/\# 0#tLk*t=t$He^A ʳ\Sbnbxp=ﳷ+_#dUYA3`0^H4f57șlJz̔ 8D@eS2##z_Q_#_ҡ=+>>5͢ƒ\bƩkS^oqpf0RI^Q*f}Sʄ]ӵ'FH.ev.hA\\ƲYqŋM=9cbUb ,9a fK_ KCsySD}9d%I t&U7*`ϭ*7E"uhƏ§ e*&%Pl((þg,+u"zOH}u#˖ơͮ!] `H,)Vsx,vw,bU6!/A Wj_Uu:վ'Hf T>*aWݔ֐= 4,N\?q`t-?fucWإ=!z&6$%+jHBd6>}>#Tj$1c]DZ-gnjukS>]sf-'N)O BCo#ʫA\M^ŝ`D4L_sI^Q) }2_ }GLD,rq |NpdvV XXמ7ZB(x9/R|T]GE-{Z D-e%|}DۑMỏ;'A#|.⣷,_Kͧ݇Ծ*n|5Dt%p)}vH`C`qzL8nO6-ZW-@-! G)Zg9*fcZ@DxhDc %o#;} I-Nr3_'F#6CyݫUi&$^ᣪˎɸw(¤&dc8)G}zGOk-G\8"B1K"5yߦ+Y y 03. w΢8 ZO]YaËb^~}ޑݣ0(_mwEQ7RL FNvz>=F;;FʄGj)"QA֥CtU/.}23Mý+)VO?zWO񰡛ju\J}xFWTn^"z*cTR^vTѱbÞhLGa[k ,DI"'I }AfBb7ٺYCn#WqeuӘBCjF:q؍x0[7l#_`'ϘN-tqh H=tnkk* tLL7.~ j‹l[N7̝k-UuGЪOKkڲ 6zUj0Q>f+q>Eڀ*61@0OJDrgT^$,8*gs3ΧM*:8xZgEvΔsYP&I84u\IWgpO;76 ۏd%:3s9ZRGOrC@<pξ'7o-K'X}ɪ.T??whX#[4xa[ax&`֡t0:%CBy3D&w? 샊{^sA2 HvSUfLG`5/ %[a FywJtSV-S}O6*A-7\kYroSYAeJcw:E ٢c-j;1SN6A'<  w[c!Gh 0M(yQi \|=%)Z4< 5'19n8XuvT7}ha\T1ɐF/}U6oҡ6TWؕD\JCD䣻JHF"8VTQV99c/juc !M4(}Auk-=1fv;D=4HD$roBHs<;F0x_] }ô u%Mf'fb(sS--'t,vJ Cݕ{W7 mD$?/#F -8%~Tpd\ U[TsU}͎)M`n+Őg:^| +QE r/ IMA^iAayRqߊ1ѲGBO[o+ v4V鲛EU@E,{V"Xz\'T/98||V䎪sϸ{Q+E186+7-SKݹk3*JxN*VcR  寄f_= JC'wg˝ Fgk,qկ!LRwA^TxReGIrT1hR;9n7`6PDGx<~:@*tg[^-gC ((zEZ %iwqD5`DAh9g2uDVcNjb vR/߁t-%/ +Ldx(#10[MLJ= R'BMSy,R^س "Bʇ@#mh@Q,GBr/  ;\o?Ə]oW2 'N˦pyFgxIm -B^$&Ӗ^0]]];1&]][;&]];]-5;-b1/ӓ/ &}p1/{0 !Gk+{afа'yo΢fm`u౮g:^r|M+[\o)?V%7S$d/u&Նm_æ8_(13[C=)xG5=K̮[+C 1l1phFɽV>( BkZ_N7u(d ?:>l  Jcs&ph弴 ߓ8!]և&M=-PgaV .!a]c,JҖϖ`hZܤaZn_Lm=y]&O. \ OpiFZVVw\Ox[ '捈|jߌ> B`,>>:7mKGoinjzr~j\Oj8O9{^:@}*㖉ԃBPbUԳy0WA{ pF6?񠸉[x[JzYS @JwE8QL%q|ocq5N YMAl q`ՂߝRSe4]e"gDKP${MKF\2B7~ .[ڷ  =wPzEY)o`1nyFCAs+_UTg\h'XBlySj'j$Ime17Z/ KXq׍FS^O(H#)z{T*MF孫 LR^9TLx. XşF8~^ш*.Y빆X8eQ}< dPr< %?:5h)$yrrޑ½6J%4;!f4R#<\oq~4AvӅ}0cʅʅ&扈+&#扈+/v栅#扈+/vvʅ&扈+/v~&扈扈+/v扈0+/v扈+/vv)377742 3@)377742 35s4B3353=532:!vƞ[pޣTF}!.5&ξlV.չ<^aE)3rS@B[5H9Z¶F;H%6\Nm*y5ꟿiH}Z%ݡMBGFxbՆY +tH`m3`3Ƣr6f!8 :<< WMW36+K{F^2M=dbXrG.3y>mxEqzᅩ*{O`7rAHĺ.!7]e|({psxB "1YHOD[?E@k$g:pfUyyGtpDyCBubg)ٟM0P8m=JB :you!<o>" 5gzc -.Nnmͷ63'babހ AۂFà #_Tj:ZSܸFm@?}F\нfQ'*b DdMJ&Ū!{<-Snq/!ӿB4 R,př?¯]"Ej%Ę =+TglB g9-گR7Qҍ}ݶZQޑT}ۋf/$p}7>T ?dWi*].̬:A~Q.{57m.]y䐇51B+о+㕛 p8ɽ Bx'PhsXgeUuIhoG%Dh4Ȅ`Zr=xAcE~! `Ȗp;N<[ yF (:#?^dXPLv8  :هu! \e/Lg$[c6i)5toSZpZ}iAWs'X0hI\u Shq}료%[ O}.!;Ox1vmO}>l얃qfbOj䖒/93)cIKi=Уssu42춟k#qooPt뢦 tڍJlA\~utPd=[ yP>P0?o…Vⓦc%Po x{V7&0G;xVJ)P=!$3ĵeA2 nRmg$i /.ޖr-6"H;% wl#6W1[>פJPEtYGC~\_`OcIۧ`Fcr+UE4=Gᤷ?=MXp Jyk~\Z 4s0OkIbhGr#&P#DI'_buy g 鎁 4x5kɫ p<%vstUgo9#նhZkXlc= ҔWGihUea<གྷmܚiry4zfPkBrv'Vz=p09~{R]5A6Jo|HMl0$Yqŧ|:w޳3H$Ɉ 1;#CKV= ~`lҕ3ݦ2Ո!uN1+`5`*09L+).0̤ {T !jue 3ly~: T{̢J' G Pрie|3!3C[|cI$$1EGLk*t=t$He^A ʳ\Sbnbxp=ﳷ+_#dUYA3`0^H4f57șlJz̔ 8D@eS2##z_Q_#_ҡ=+>>5͢ƒ\bƩkS^oqpf0RI^Q*f}Sʄ]ӵ'FH.ev.hA\\ƲYqŋM=9cbUb ,9a fK_ KCsySD}9d%I t&U7*`ϭ*7E"uhƏ§ e*&%Pl((þg,+u"zOH}u#˖ơͮ!] `H,)Vsx,vw,bU6!/A Wj_Uu:վ'Hf T>*aWݔ֐= 4,N\?q`t-?fucWإ=!z&6$%+jHBd6>}>#Tj$1c]DZ-gnjukS>]sf-'N)O BCo#ʫA\M^ŝ`D4L_sI^Q) }2_ }GLD,rq |NpdvV XXמ7ZB(x9/R|T]GE-{Z D-e%|}DۑMỏ;'A#|.⣷,_Kͧ݇Ծ*n|5Dt%p)}vH`C`qzL8nO6-ZW-@-! G)Zg9*fcZ@DxhDc %o#;} I-Nr3_'F#6CyݫUi&$^ᣪˎɸw(¤&dc8)G}zGOk-G\8"B1K"5yߦ+Y y 03. w΢8 ZO]YaËb^~}ޑݣ0(_mwEQ7RL FNvz>=F;;FʄGj)"QA֥CtU/.}23Mý+)VO?zWO񰡛ju\J}xFWTn^"z*cTR^vTѱbÞhLGa[k ,DI"'I }AfBb7ٺYCn#WqeuӘBCjF:q؍x0[7l#_`'ϘN-tqh H=tnkk* tLL7.~ j‹l[N7̝k-UuGЪOKkڲ 6zUj0Q>f+q>Eڀ*61@0OJDrgT^$,8*gs3ΧM*:8xZgEvΔsYP&I84u\IWgpO;76 ۏd%:3s9ZRGOrC@<pξ'7o-K'X}ɪ.T??whX#[4xa[ax&`֡t0:%CBy3D&w? 샊{^sA2 HvSUfLG`5/ %[a FyJtSV-S}O6*A-7\kYroSYAeJcw:E ٢c-j;1SN6A'<  w[c!Gh 0M(yQi \|=%)Z4< 5'19n8XuvT7}ha\T1ɐF/}U6oҡ6TWؕD\JCD䣻JHF"8VTQV99c/juc !M4(}Auk-=1fv;D=4HD$z r-@0= .eHmFAm+\_<,7SSDټm>GPNd#xI Wl|W}+ReF:"k?qW j1/wmyF3]u]2= ##F{ 􏥡}8d;WL9v6ӆ71izi{~s3ҚKD7}ӀL#RZXħFl!LX*kspz>,4sT10D ]ʺyz=p}u#˖ơͮ!] `H,)Vsx,vw,bU6!/A Wj_Uu:վ'Hf T>*aWݔ֐= 4,N\?q`t-?fucWإ=!z&6$%+jHBd6>}>#Tj$1c]DZ 822834GC|HvC|C|SSFUZZ-4 0792660068822834C|'SS-8H]H##HHH-6HH+SFUZZ-4 0792660068822834C|'SS-8H]H##HHSSS  822834GC|HvC|C|SSFUZZ-4 0792660068822834C|'SSZ-TAGCFUZZ-TAGCT 扔E ͉͑ FUZ$Znn0nnoϑ$Z扔E ͉oϑϑ FU$Znn0nnoϑ$Y扔E ͉͑͊ϑ FUZ$Znn0nnoϑnn0nnoϑϑ͊ϑ FUZ$Znn0nnoϑ$Z扔E ͉͑͊ϑ FUZ$Znn0nnoϑϑ FU͊ FUZ$UZ$Zӑcccccccccccccccccccccccccccccccccccccccc͊ϑ F FUZ$Znn0nnoϑ$Z扔E ͉͑͊ϑ FUZ$Znn0nn͊ϑ FUZ$Znn0nnoϑ$Z扔E ͉͑͊ϑ FUZ$Znn0nnoϑnn0nnoϑϑ FU͊ FUZ$UZ$Zӑ͊ϑ FUZ$͊ϑ FUZ$Znn0nnoϑ$Z扔 FUZ$Znn0nnoZnn0nnoϑnn a5/<lRh^rk[[N*Ƹp\xi$ʅZʅsʅʅZʅZʅZ{ʅʅAs=`ʅʅZ{cʅZʅZ{ʅʅAs=`ʅʅZʅZʅʅZʅZZ#dʅZ{cs=`ʅʅZZU)vAUAAA#Z mmmmmmmmmmmmm)vAUAAFUZZ-TAGTZWA#ZmmmmmmmmmmmmmmmmmmmmmmmmmmZU)vAUAAZlmmm)vAUAA#6ZAz`mmmmmmmmmmmmmU)vAUAAZmmm)vAUAA#Zmmmmmmmmmmmmm)vAUAA#ZAA:#Zmmmmmmmmmmmmmmmmmmmmmmmmmm:mmmmmmmmmmmmm3714372634@0@U)vAUAAZmmm)vAUAAR/ &Z&ZU)vAUAAA#Z mmmmmmmmmmmmm)vAUAAFUZZ-TAGTZWA#ZmmmmmmmmmmmmmmmmmmmmmmmmmmZU)vAUAAZlmmm)vAUAA#6ZAz`mmmmmmmmmmmmmU)vAUAAZmmm)vAUAA#Zmmmmmmmmmmmmm)vAUAA#mmmmmmmmmmomm)vAUAA#ZmmmmmmmmA` Az`mmmmmmmmmmmmmU)vAUAAZmmm)vAUAA#Z˸˔mmmmmmmmmmmmmZU)vAUAAZlmmm)vAUAA#2ZAz`mmmmmmmmmmmmmU)vAUAA'C|'C|18446544073709548781' 2834C|......./˅&扈+/v&扈+/[ʀ扈+/v&z.%H530 773-2#x 7Z|i7777777777777777#777艔SF{ 􏥡0dp^ 0dp^ 0d 0dp^ 0dp^ 0dp^ ;ʪjsoncons-1.3.2/test/fuzz_regression/input/clusterfuzz-testcase-fuzz_ubjson-5681659887484928000066400000000000000000000120501477700171100312570ustar00rootroot00000000000000{#iiihi:[[[0[[Z{#iiihi:[[[0[[Z[[[]]][[UUUUUUUUUUUUUUUUUUUUUUUUUUUUUU[Z{#iiihi:[[[1[[Z[[[]]][[UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUU]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUU][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUUUUUUUUUU][[UUUUUUUU[[[]]][[UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUUUUUUU[Z{#iiihi:[[[1[[Z[[[]]][UUUUUUUUUU[Z{#iiihi:[[[1[[Z[[[]]][[UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUU][[]]][UUUUUUUUUUUU][[UUUUUUUU[[[]]][[UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUUUUUUU[Z{#iiihi:[[[0[[Z[[[]]][UUUUUUUUUU[Z{#iiihi:[[[1[[Z[[[]]][[UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUU][[]]][UUUUUUUUUUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]][UUUUUUUUUU[Z{#iiihi:[[[1[[Z[[[]]][[UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUU][[]]][UUUUUUUUUUUU][[UUUUUUUU[[[]]][[UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUUUUUUU[Z{#iiihi:[[[0[[Z[[[]]][UUUUUUUUUU[Z{#iiihi:[[[1[[Z[[[]]][[UUUUUUUUUUUUUUUUUU[Z[[[[[Z{#iiihi:[[[0[[Z[[[]]][[UUUUUUUUUUUUUUUUUUUUUUUUUUUUUU[Z{#iiihi:[[[1[[Z[[[]]][[UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUU]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUU][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUUUUUUUUUU][[UUUUUUUU[[[]]][[UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUUUUUUU[Z{#iiihi:[[[1[[Z[[[]]][UUUUUUUUUU[Z{#iiihi:[[[1[[Z[[[]]][[UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUU][[]]][UUUUUUUUUUUU][[UUUUUUUU[[[]]][[UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUUUUUUU[Z{#iiihi:[[[0[[Z[[[]]][UUUUUUUUUU[Z{#iiihi:[[[1[[Z[[[]]][[UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUU][[]]][UUUUUUUUUUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]][UUUUUUUUUU[Z{#iiihi:[[[1[[Z[[[]]][[UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUU][[]]][UUUUUUUUUUUU][[UUUUUUUU[[[]]][[UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUUUUUUU[Z{#iiihi:[[[0[[Z[[[]]][UUUUUUUUUU[Z{#iiihi:[[[1[[Z[[[]]][[UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUU][[]]][UUUUUUUUUUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUU][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUUUUUUUUUU][[UUUUUUUU[[[]]][[UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUUUUUUU[Z{#iiihi:[[[1[[Z[[[]]][UUUUUUUUUU[Z{#iiihi:[[[1[[Z[[[]]][[UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUU][[]]][UUUUUUUUUUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUdUUUU]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[UUUUU]]]][[[]][UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUUUuUUUUUUUUUUUUUU][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUUUUUUUUUU][[UUUUUUUUUU[[]]UUUUUUUUUU][[]]][UUUUUUUUUUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUUUUUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUdUUUU]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[UUUUU]]]][[[]][UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUUUuUUUUUUUUUUUUUU][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUUUUUUUUUU][[UUUUUUUUUU[[]]UUUUUUUUUU][[]]][UUUUUUUUUUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUUUUUUUUU]]UUUUUUUUUUUUUUUUUUUUUU][[]]][UUUUUUUUUUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUU][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUUUUUUUUUU][[UUUUUUUU[[[]]][[UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUUUUUUU[Z{#iiihi:[[[1[[Z[[[]]][UUUUUUUUUU[Z{#iiihi:[[[1[[Z[[[]]][[UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUU][[]]][UUUUUUUUUUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUdUUUU]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[UUUUU]]]][[[]][UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUUUuUUUUUUUUUUUUUU][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUUUUUUUUUU][[UUUUUUUUUU[[]]UUUUUUUUUU][[]]][UUUUUUUUUUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUUUUUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUdUUUU]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[UUUUU]]]][[[]][UUUUUUUUUUUUUUUUUU[Z[[[]]UUUUUUUuUUUUUUUUUUUUUU][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUUUUUUUUUU][[UUUUUUUUUU[[]]UUUUUUUUUU][[]]][UUUUUUUUUUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUU]]]][[[]]][[]][[[]]]UUUU]U[]]][[]]][UUUUUUUUUUUUUUUUdUU[Z[[[]]UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUdUUUUUUUUU]]]][[[]]][[]][[[]]]UUUUU]]]][[[]]]]][[[]]][[]][[[]]]UUUUU]]]][[[]]][[]]]]][[[[[[clusterfuzz-testcase-minimized-fuzz_bson_encoder-5420549982519296000066400000000000000000000000261477700171100343010ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/input  jsoncons-1.3.2/test/fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_cbor-5171679883165696000066400000000000000000000000031477700171100326500ustar00rootroot00000000000000[jsoncons-1.3.2/test/fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_cbor-5639265590706176000066400000000000000000000006441477700171100326500ustar00rootroot00000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFVFFclusterfuzz-testcase-minimized-fuzz_cbor-5740910806827008.fuzz000066400000000000000000001224501477700171100335520ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/inputY}d}}}}}}}}}}}}}}:AAAA5gwAAAgNAABnDQAAKA0AAAgAAABkAbAAaAGsAEwBrABRAacAOQGu AEYBswBIAbAAZAGwACIAAAAMAAAA/////yUAAAAMAAAMAAAAD wAAgCUAAAAMAAAADgAAgEsAAAAQAAAAAAAAAAUAAAAoAAAADAAAAAMAAAAoAAAADAAAAAQAAAAlAA AADAAAAAAAAIAlAAAADAAAAAcAAIAiAAAADAAAAP////8lAAAADAAAAA0AAIAoAAAADAAAAAEAAAA iAAAADAAAAP////8iAAAADAAAAP////9GAAAAcAAAAGQAAABFTUYrLEAAACQAAAAYAAAAjxcwQAAA AIAAAACAvfcqQH2JGEU3ozRFKkAAACQAAAAYAAAAAACAPwAAAMAAAACAAACAPwAAAIAAAACAIUAHA AwAAAAAAAAAB"AAAAwAAAAAAAAARgAAABQAAAAIAAAAR0RJQwMAAABGAAAAKAAAABwAAABHRElDAg AAABsMAABVDAAA/w0AACYNAAAAAAAARgAAAEwGAABABgAARU1GKypAAAAkAAAAGAAAAAAAgD8AAAC AAAAAgAAAgD8AAACAAAAAgCFABQAMAAAAAAAAAAhAAAWoBQAAnAUAAAIQwNsCAAAAAgAAAHQFAADX zcaaAAAbAaEArAHfAEgAAQAAAJBXAAABAAkAAAO6AgAABAAUAAAAAAAFAAAACwKhABsBBQAAAAwCP gCRAAQAAAAEAQ0ABAAAAC4BGAAEAAAAAgEBAAUAAAAJAgAAAAAFAAAAAQL///8AAwAAAB4ACgAAAC YGDwAKAP////8AAAAAAAAAAAA5gwAAAgNAABnDQAAKA0AAAgAAABkAbAAaAGsAEwBrABRAacAOQGu AEYBswBIAbAAZAGwACIAAAAMAAAA/////yUAAAAMAAAMAAAAD wAAgCUAAAAMAAAADgAAgEsAAAAQAAAAAAAAAAUAAAAoAAAADAAAAAMAAAAoAAAADAAAAAQAAAAlAA AADAAAAAAAAIAlAAAADAAAAAcAAIAiAAAADAAAAP////8lAAAADAAAAA0AAIAoAAAADAAAAAEAAAA iAAAADAAAAP////8iAAAADAAAAP////9GAAAAcAAAAGQAAABFTUYrLEAAACQAAAAYAAAAjxcwQAAA AIAAAACAvfcqQH2JGEU3ozRFKkAAACQAAAAYAAAAAACAPwAAAMAAAACAAACAPwAAAIAAAACAIUAHA AwAAAAAAAAAB"AAAAwAAAAAAAAARgAAABQAAAAIAAAAR0RJQwMAAABGAAAAKAAAABwAAABHRElDAg AAABsMAABVDAAA/w0AACYNAAAAAAAARgAAAEwGAABABgAARU1GKypAAAAkAAAAGAAAAAAAgD8AAAC AAAAAgAAAgD8AAACAAAAAgCFABQAMAAAAAAAAAAhAAAWoBQAAnAUAAAIQwNsCAAAAAgAAAHQFAADX zcaaAAAbAaEArAHfAEgAAQAAAJBXAAABAAkAAAO6AgAABAAUAAAAAAAFAAAACwKhABsBBQAAAAwCP gCRAAQAAAAEAQ0ABAAAAC4BGAAEAAAAAgEBAAUAAAAJAgAAAAAFAAAAAQL///8AAwAAAB4ACgAAAC YGDwAKAP////8AAAAAAAAKAAAAJgYPAAoA/////wAAAAAAAABsMAAAAcAAAD8AgAAAJbVAAAABAAAAC0BAAA JAAAA+gIFAAAAAAD///8QIgAEAAAALQEBAA4AAAAkAwUAGwHCABsB3gCJAd4AiQHCABsBwgAJAAAA +gIGAAEAAACq5v8AIgAEAAAALQECAA4AAAAkAwUAGwHCABsB3gCJAd4AiQHCABsBwgAHAAAA/AIAA ABagAAAAAQAAAAtAQMABAAAAPABAAAEAAAALQEBAAQAAADwAQIADgAAACQDBQCJAcIAqwGhAKsBvQ CJAd4AiQHCAAkAAAD6AgYAAQAAAKrm/wAiAAQAAAAtAQAADgAAACQDBQCJAcIAqwGhAKsBvQCJAd4 AiQHCAAcAAAD8AgAAALT/AAAABAAAAC0BAgAEAAAA8AEDAAQAAAAtAQEABAAAAPABAAAOAAAAJAMF AIkBwgCrAaEAPQGhABsBwgCJAcIACQAAAPoCBgABAAAAqub/ACIABAAAAC0BAAAOAAAAJAMFAIkBw gCrAaEAPQGhABsBwgCJAcIACgAAACYGDwAKAP////8BAAAAAAAKAAAAJgYPAAoA/////wAAAAAAAA oAAAAmBg8ACgD/////AAAAAAAABwAAAPwCAAAAAAAAAAAEAAAALQEDAAQAAADwAQAIBAAAAC0BAQA EAAAA8AEAABQAAAAkAwgAYAGyAFwBtgB4AbYAdAG7AIsBtQB/AbAAfAGyAGABsgAUAAAAJAMIAGAB sgBcAbYAeAG2AHQBuwCLAbUAfwGwAHwBsgBgAbIAFAAAACQDCABuAaUAagGpAIYBqQCBAa4AmQGnA IwBogCKAaUAbgGlABQAAAAkAwgAbgGlAGoBqQCGAakAgQGuAJkBpwCMAaIAigGlAG4BpQAUAAAAJA MIAFYBvQBaAbkAPQG5AEIBtAArAboANwG/ADkBvQBWAb0AFAAAACQDCABWAb0AWgG5AD0BuQBCAbQ AKwG6ADcBvwA5Ab0AVgG9ABQAAAAkAwgAYwGvAGcBqwBLAasAUAGmADgBrQBFAbIARwGvAGMBrwAU AAAAJAMIAGMBrwBnAasASwGrAFABpgA4Aa0ARQGyAEcBrwBjAa8ACgAAACYGDwAKAP////8BAAAAA AAKAAAAJgYPAAoA/////wAAAAAAAAcAAAD8gAA////AAAABAAAAC0BAAAUAAAAJAMIAGEBswBdAb cAeQG3AHUBvACMAbYAgAGxAH0BswBhAbMAFAAAACQDCABhAbMAXQZ3AHkBtwB1AbwAjAG2AIABsQB 9AbMAYQGzABQAAAAkAwgAbwGmAGsBqgCHAaoAggGvAJoBqACNAaMAiwGmAG8BpgAUAAAAJAMIAG8B pgBrAaoAhwGqAIIBrwCaAagAjQGjAIsBpgBvAaYAFAAAACQDCABXAb4AWwG6AD4BugBDAbUALAG7A DgBwAA6Ab4AVwG+ABQAAAAkAwgAVwG+AFsBugA+AboAQwG1ACwBuwA4AcAAOgG+AFcBvgAUAAAAJA MIAGQBsABoAawATAGsAFEBpwA5Aa4ARgGzAEgBsABkAbAAFAAAACQDCABkAbAAaAGsAEwBrABRAac AOQGuAEYBswBIAbAAZAGwAAoAAAAmBg8ACgD/////AQAAAAAACgAAACYGDwAKAP////8BAAAAAAAK AAAAJgYPAAoA/////wEAAAAAAAQAAAAnAf//AwAAAAAACEACCCQAAAAYAAAAAhDA2wEAAAADAAAAA AAAAAAAAAAAAAAA G0AAAEAAAAA0AAAAAgAAAAIAAAAAgI1DAAAhQwAAEUMAAHhCAwAAAP/HQUVUbUVFqexfRVRtRUX/x 0FFVFFSRSEAAAAIAAAAYgAAAAwAAAABAAAAIQAAAAgAAABiAAAADAAAAAEAAAARAAAADAAAAAgAAA AKAAAAEAAAABsBAAChAAAACQAAABAAAACRAAAAPgAAAAwAAAAQAAAAHAwAAFcMAAALAAAAE}}}}}}}}}}}}}}}}}}y}}}}}}}}}}/}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|}/}}}}}AAAAOM BAADOAAAAIQAAAAgAAAAlAAAADAAAAAcAAIAlAAAADAAAAAAAAIAWAAAADAAAAAAAAAAYAAAADAAA AAAAAAAZAAAADAAAAP///wAUAAAADAAAAA0AAABSAAAAcAEAAAEAAAAQAAAABwAAAAAAAAAAAAAAv AIAAAAAAAAHAgIiUwB5AHMAdABlAG0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAA8ncAAAAA6RQh7hkAsAGoJfJ3OJETAEU08ncNAA#A6RQh7hkAsAG oJfJ36RQh7hkAsAGoJfJ3JgCKAekUIe4LAIgBAQAAAIyQEwDLVfJ36RQh7qBd8ndEBWYPtJETAAAA AAAfAQIA/wARAgMA2AD/AAEAwADYAAEA8ABwpxwAAAAXA+kUIe4QAJABAAAAAFVVVQBwpxwAkI8TA OkUIe4hAIoBsAJbEekUIe4XALABSAcVAG0FkXxGEhCquAJbEQAAWxHmAQMAwADOAgcA/wAQAAAA4A AfASYGAAALBQQAqACdAgQAYAAtAQAAAAABBScBAAD4jxMAWyjyd+zYIQBkdgAIAAAAACUAAAAMAAA AAQAAAAoAAAAQAAAAGwEAAKEAAAAJAAAAEAAAAJEAAAA+AAAAFAAAAAwAAAANAAAAFgAAAAwAAAAY AAAAEgAAAAwAAAABAAAAGAAAAAwAAAAAAAAAGQAAAAwAAAD///8AIQAAAAgAAAAnAAAAGAAAAAQAA AAAAAAAAJbVAAAAAAAlAAAADAAAAAQAAAAlAAAADAAAAAgAAIBWAAAAMAAAABwMAADFDAAAig0AAC INAAAFAAAAGwHCABsB3gCJAd4AiQHCABsBwgAmAAAAHAAAAAMAAAAGAAAAAQAAAAAAACq5v8AJQA AAAwAAAADAAAAVgAAADAAAAAZDAAAwgwAAI0NAAAlDQAABQAAABsBwgAbAd4AiQHeAIkBwgAbAcIA JwAAABgAAAACAAAAAAAAAABagAAAAAAAJQAAAAwAAAACAAAAKAAAAAwAAAAEAAAAJQAAAAwAAAAIA ACAKAAAAAwAAAADAAAAVgAAADAAAACKDQAAVwwAAPwNAAAiDQAABQAAAIkBwgCrAaEAqwG9AIkB3g CJAcIAJgAAABwAAAADAAAABgAAAAEAAAAAAAAAqub/ACUAAAAMAAAAAwAAAFYAAAAwAAAAhw0AAFQ MAAD/DQAAJQ0AAAUAAACJAcIAqwGhAKsBvQCJAd4AiQHCACcAAAAYAAAABAAAAAAAAAAAtP8AAAAA ACUAAAAMAAAABAAAACgAAAAMAAAAAgAAACUAAAAMAAAACAAAgCgAAAAMAAAAAwAAAFYAAAAwAAAAH AwAAFcMAAD8DQAAxQwAAAUAAACJAcIAqwGhAD0BoQAbAcIAiQ0CACYAAAAcAAAAAwAAAAYAAAABAA AAAAAAAKrm/wAlAAAADAAAAAMAAABWAAAAMAAAABkMAABUDAAA/w0AAMgMAAAFAAAAiQHCAKsBoQA 9AaEAGwHCAIkBwgAnAAAAGAAAAAIAAAAAAAAAAAAAAAAAAAAlAAAADAAAAAIAAAAoAAAADAAAAAQA AAAlAAAADAAAAAgAAIAoAAAADAAAAAMAAABWAAAAPAAAAPUMAACJDAAAkQ0AAK0MAAAIAAAAYAGyA FwBtgB4AbYAdAG7AIsBtQB/AbAAfAGyAGABsgBWAAAAPAAAAPUMAACJDAAAkQ0AAK0MAAAIAAAAYA GyAFwBtgB4AbYAdAG7AIsBtQB/AbAAfAGyAGABsgBWAAAAPAAAACMNAABaDAAAwA0AAIIMAAAIAAA AbgGlAGoBqQCGAakAgQGuAJJAAAACAAA ZwkAAKoAAAAjBEwiLAQ2IkkE9CFdBMghdgSUIZQEWyG2BBwhyAT9INsE3CDvBLsgBAWaIBoFeCAxB VcgSAU1IGEFFSB5BfQfkwXVH64Fth/JBZcf5QV7HwEGXx8eBkUfOwYtH1gGFh93BgEfhQb4HpUG7h 6jBuYeswbeHsIG1h7RBs8e4AbJHvAGwx7/Br0eDwe4Hh4HtR4tB7EePQeuHk0Hqx5cB6oebYepHnw HqB6MB6kenAepHqwHqx68B60ezQewHt4Hsx7vB7geAAi9HhEIwx4jCMseNQjSHkcI2x5ZCOUebAjw Hn8I/B6TCAkfpggXH7oIJh/OCDcf4whIH/gIWx8MCW8fIQmEHzcJmx9MCbMfYgnMH3gJ5h+OCQIgp AkgILoJPiDRCV8gB6A I mP8JoyAWCsggLQrvIEQKFiFcCj8hcwpqIYsKliGjCsUhuwr0IdMKJiLrClkioQsEIocLzyFuC 5whVQtqITwLOiEkCwshCwveIPIKsiDZCoggwApfIKgKOCCPChIgdgrtH14Kyh9FCqgfLAqIHxQKaR /7CUsf4wkuH8oJEx+yCfkemQngHoAJyR5oCbIeTwmdHjYJiR4eCXYeBQlkHuwIVB7TCEQeuwg2HqI IKB6JCBwecAgRHlcICB4+CP8dJQj3HQ0I8R30B+sd2wfnHcMH4x2qB+EdkgfgHXoH4B1iB+EdSgfi HTMH5R0bB+gdBQftHe4G8h3XBvgdwQb/HasGBh6WBg8egAYYHmwGIR5XBiweQwY2Hi8GQh4bBk4eB wZbHuIFdB69BZEemgWuHngFzR5XBe0eNgUPHxcFMR/5BFQf3AR4H8AEnB+mBMAfjATlH3MECSBbBC 4gRQRSIC8EdiAaBJkgBgS8IOMD/SDDAzshqANyIZIDo*F0A+ghaAMEIhMAAAAMAAAAAgAAABMAZAA MAAAAAgAAAFYAAACgAAAAlwcAAGIJAAChBwAAaQkAACEAAABoAwQiZAMPImDGiJhAyUiYQMwImED OiJkA0MiZgNMImoDVSJvA10idQNlInsDbCKCA3IiiQN4IpEDfSKZA4EiogOFIqoDiCK0A4oivQOMI sYDjCLPA4wi2QOLIuIDiSLrA4ci8wODIvwDfiIEBHgiCwRyIhIEaiIYBGEiHgRXIiMETCITAAAADA AAAAIAAAATAAAADAAAAAEAAAAlAAAADAAAAAQAAAAlAAAADAAAAAMAAAAoAAAADAAAAAIAAAAnAAA AGAAAAAIAAAAAAAAA////AAAAAAAlAAAADAAAAAIAAAAlAAAADAAAAAgAAIATAAAADAAAAAIAAAAT AAAADAAAAAIAAABWAAAA4AAAAJIHAABbCQAApQcAAGgJAAAxAAAAgATtIXwE4SF3BNchcQTMIWsEw yFlBLkhXwSxIVgEqSFRBKEhSQSaIUIElCE6BI4hMgSIISoEgyEhBH8hGQR7IRAEdyH+A3Ih7ANuId kDbCHHA2shtANtIaEDcCGPA3QhfgN6IWwDgiFcA4shTAOVIT0DoCEwA6IQcD7CEEA/UhAQP+If8CByL9AhEi/AIbIvsCJSL7AjAi/AI6Iv0CRSL+AlAiAANbIgMDZiIHA3Ii CwN9IhMAAAAMAAAAAgAAABMAAAAMAAAAAgAAAFYAAADYAgAAkwcAAGAJAAAFCZAAoAkAAK8AAACTC tohkwraIXwKDCJlCjwiTQpqIjYKlyIfCsMiCArtIvEJFCPbCTsjxAlgI64JhCOYCaUjgwnFI2wJ5C NXCQIkQgkdJC0JOCQZCVEkBAloJPAIfiTcCJQkyQinJLcIuSSkCMokkQjaJIAI6CRuCPYkXQgCJU0 IDSU8CBclLAggJR0IKCUOCDAl/wc2JfEHPCXjB0Al1gdEJckHSCW8B0slsAdOJaMHTyWXB1AliwdQ JX8HUCV0B1AlaAdQJVwHTiVQB0wlRAdKJTgHRyUsB0UlIAdAJRQHPCUIBzgl/AYyJe8GLSXjBiYl1 gYfJckGGCW8BhAlsQYKJZUG9iR7BuIkYAbMJEYGtCQtBpwkEwaBJPoFZSThBUgkyQUqJLIFDCSaBe wjhAXNI24FrSNZzEFTSMfBS4jDgUQI+0E0yLQBJwitwRpIqQEPyKIBP4hgATtIQsDfSI XA50iNgPjIk4DFiNqA08jigOOI68D0SPEA/Yj2gMbJPADPyQIBGUkIASMJDoEsiRVBNgkcQT+JI8E JCWuBEklzgRuJe8EkiURBbYlNQXaJVoF+yWBBRomqAU5JtEFVSboBWUm/gVyJhUGfyYrBosmQgaWJ loGoSZzBqsmiwa1JqQGvia+BsUm2AbNJvIG0yYNB9gmKAfbJkQH3iZfB+EmfAfiJpgH4ia0B+Am0Q fdJu0H2SYKCNUmJwjOJkQIxyZhCL4mfCJwm0giOJu4IfyYKCW8mJQleJkEJSyZcCTg mdwkjJpMJDSatCfYlyAneJeIJxCX9CaklFwqOJTEKcSVLClIlZQozJX8KEiWZCvAkswrNJMwKqSTm CoIkAAtbJBkLMiQzCwgkTAvdI2YLryOAC4EjmQtSI7MLICPMC+0i5Qu5IgAMgyIADIMikwraIZMK2 iGTCtohEwAAAAwAAAACAAAAEwAAAAwAAAACAAAAVgAAANgCAADzBwAAKQkAAGUIAABpCQAArwAAAI kT4SGJE+EhfBPCIV0TeyFFE0ghKRMPIQkT0CDkEowgzxJoILoSRCCjEh8gjBL5H3MS0x9ZEqwfPhK GHyISYB8EEjof5hEVH8UR8B6kEcweghGoHl4RhR45EWMeEhFDHuoQJB7CEAgeqxD5HZUQ7B1+EN8d aBDTHVAQxx05ELwdIRCyHQcQqR3uD6Ad1Q+ZHbsPkR2gD4sdhg+GHWsPgh1PD38dNA99HRcPfB38D nwd3w5+HcMOgB2mDoUdiQ6JHW0OkB1PDpcdMw6gHRYOqh35DbUd3Q3CHcENzx2kDd4diQ3uHW0N/x 1SDRIeNg0mHhsNOh4ADVAe5gxnHssMfx6wDJkelgyzHnsMzx5hDOweSAwLHy0MKh8UDEsf+gttH+A LkB/HC7QfrQvbH5MLAiB6CysgYAtUIEcLgCAtC60gEwvcIPoKCyHgCjwhxwpvIa4KpCGTCtohAAyD IhcMUSIuDCEiRgzyIV0MxiF0DJohiwxwIaEMSSG4DCIhzgz9IOUM2SD7DLggEA2YICYNeSA7DVsgU Q1AIGYNJSB6DQwgjw31H6IN3x+2DcofyQ22H9wNpR/vDZMfAQ6EHxMOdR8lDmcfNQ5bH0YOUR9XDk YfZw49H3UONR+FDi4fkw4nH6IOIR+vDh0fvQ4ZH8kOFR/WDhMf4w4QH+8ODx/7Dg4fBw8NHxQPDR8 fDw0fKw8OHzcPDx9CDxEfTw8TH1oPFh9mDxkfcg8dH38PIR+KDyYflw8sH6QPMh+wDzcfvQ8/H8oP RR/XD04f4g9VH/4PaB8ZEHwfMxCSH00QqR9mEMIfgBDdH5kQ+R+yEBYgyhA0IOIQUiD5EHIgEBGSI CYRsSA6EdEgTxHxIGIRESF1ETEhhhFPIaYRiyHEEcMh3BH1IfARICIMEmAiExJyIhMSciKJE+EhiR PhIYkT4SETAAAADAAAAAIAAAATAAAADAAAAAIAAABWAAAA2AIAAFIIAABgCQAAxAgAAKAJAACvAAA AmhnQIZoZ0CGDGQMiaxkzIlMZYSI9GY8iJRm6Ig4Z5CL4GAsj4RgyI8sYVyO1GHojnxicI4kYvCNz GNsjXhj4I0kYFCQ0GC4kIBhHJAsYXiT3F3Uk4xeKJNAXnSS9F68kqxfAJJgX0CSGF94kdRfsJGQX+ CRUFwMlQxcNJTQXFiUkFx4lFRcmJQcXLCX4FjIl6xY2Jd0WOiXQFj5lxBZBJbcWQyWrFkUlnxZGJZ MWRiWGFkYlexZGJW8WRiVjFkQlWBZCJUwWQCVAFj0lNBY6JSkWNiUcFjIlEBYtJQMWKCX3FSIl6hU cJd0VFSXRFQ4lxBUGJbkV/ySdFeskgxXYJGkVwSRPFaokNRWRJBwVdiQCFVok6RQ+JNEUHyS6FAEk ohTiI4wUwiN3FKIjYRSCI0&UYiM6FEIjJxQiIxcUBSP1E8gi2BORIsETXiKsEzQikRP0IYkT4SETE nIiIBKRIj8S1yJWEgsjcxJDI5MSgyO3EsYjzBLrI+ISDyT4EjQkEBNaJCgTgCRCE6YkXRPMJHkT8y SXExklthM+JdUTZCX2E4glGRSrJTwUziVhFPAliBQQJrAULybYFEom7xRaJgUVZyYcFXQmMxWAJko ViyZiFZcmehWhJpIVqya~FbMmxRW7Jt8Vwib5FcgmFBbOJjAW0SZLFtQmZxbXJoMW2CaeFtgmuxbW JtcW0yb0FtAmERfLJi4XxCZLF70mZxe0JoQXqSagF54mvReSJtkXhCb1F3YmERhlJiwYVCZIGEImY xguJn4YGiaaGAQm tBjsJc8Y1SXpGLslBBmgJR4ZhCU4GWglUhlJJWwZKSWGGQkloBnnJLoZwyTTGZ8k7Rl5JAYaUSQgG ikkORr/I1Ma1CNsGqYjhhp4I58aSCO5Ghcj0hrkIuwasCIGG3oiBht6IpoZ0CGaGdAhmhnQIRMAAA AMAAAAAgAAABMAAAAMAAAAAgAAAFYAAADYAgAAsggAACkJAAAjCQAAaAkAAK8AAACKIuohiiLrIX4 iyyFgIoUhSCJRISwiGCELItgg5yGUINIhbyC9IUogpyElII8h/x92IdkfXSGyH0IhjB8mIWUfCCE/ H+ogGR/KIPMeqSDOHoYgqh5jIIcePiBlHhcgRB7vHyUeyB8JHrAf+h2bH+wdhR/fHW4f0h1WH8cdP x+7HScfsR0OH6cd9R6eHdwelh3CHo8dpx6IHYwegx1yHn4dVh57HToeeR0eHncdAh53HeYdeR3KHX sdrB1/HZAdhB1zHYodVh2RHTkdmh0dHaQdAB2vHeMcux3HHMgdqxzXHY8c5x1zHPgdWBwLHj0cHh4 iHDMeBxxJHusbXx7RG3cethuRHpwbqx6AG8ceaBvkHk4bAh8zGyEfGhtCHwAbZB/mGocfzRqsH7Ma 0h+ZGvkfgBoiIGYaTCBNGncgMxqkIBka0yAAGgMh5hkzIc0ZZiG0GZshmhnQIQYbeiIdG0giNBsYI SFjG7whehuRIZEbZyGoG0AhvhsZIdQb9CDrG9EgARyvIBYcjyAsHHEgQhxTIFccNyBsHB4ggB wFIJQc7R+oHNcfuxzCH88crx/iHJ0f9RyMHwYdfB8YHW4fKh1hHzsdVB9MHUofWx1AH2sdNx96HS8 fih0oH5gdIR+lHRwfsx0XH8EdEx/OHRAf2h0OH+YdDB/yHQof/h0JHwoeCR8WHgkfIx4JHy4eCh85 HgsfRh4dH1EeEB9cHhIfaR4WH3UeGh+BHh4fjR4jH5oeKR+nHi4fsx41H78ePB/MHkMf2R5LH+QeU h8BH2cfGx97HzUfkR9PH6kfaR/DH4If3h+bH/oftB8XIM0fNSDkH1Ug+x90IBEglCAoILUgPCDVIF Ag9iBkIBYhdiA2IYcgVCGoIJEhxSDJId0g/CHxICciDSFoIhUheiIVIXsiFSF6IhUheiIVIXsiEwA AAAwAAAACAAAAEwAAAAwAAAACAAAAVgAAANgCAAARCQAAYAkAAIMJAACgCQAArwAAAJso2iGbKNoh hCgMImwoPCJVKGoiPiiXIiYowyIQKO0i+ScUI+MnOyPMJ2AjtieDI6AnpSOKJ8UjdCfkI18nASRKJ x0kNSc4JCEnUSQMJ2gk+CZ+JOQmkyTRJqckvia4JKwmyiSZJtkkhyboJHYm9iRlJgIlVCYMJUQmFy U0JiAlJSYoJRYmLyUHJjYl+SU8JewlQCXeJUQl0SVIJcUlSiW4JUwlrCVOJZ8lTyWUJVAlhyVQJXw lUCVwJU8lZCVOJVglTCVNJUklQSVHJTUlRCUpJUAlHSU7JRElNyUEJTEl+CQsJeskJSXeJB4l0iQX JcUkECW6JAklniT1JIQk4SRqJMskUCS0JDYkmiQdJIAkAyRkJOojRyTSIyokuyMKJKMj7CONI8wje COsI2IjjCNOI2sjOyNLIygjLCMYIw4j9yLRItoimiLCImciriI9IpIi/SGKIuohFSF7IiEhmiJAIe AiVyEUI3QhTSOUIYwjuCHPI84h9CPjIRkk+SE+JBEiYyQpIokkQyKvJF4i1SR6IvwkmCIiJbciRyX WIm0l9yKRJRojtSU9I9glYiP6JYkjGSaxIzgm2CNUJvAjYyYGJHEmHSR+JjMkiiZKJJUmYiShJnok qyaTJLQmrCS9JsYkxCbgJMwm+iTSJhUl1yYwJdsmTCXeJmcl4CaEJeImnyXhJrwl4CbYJd0m9SXZJ hEm1CYvJs0mTCbGJmgmvSaFJrMmoSaoJr4mmytJ14mSSdLJmQnNyZ/JyMmmi cNJrUn9iXPJ94l6ifEJQUoqiUfKI4lOShxJVMoUiVtKDMlhygSJaEo8CS7KM0k1CipJO4ogiQHKVs kISkyJDopCCRUKd0jbimvI4cpgSOhKVIjuykgI9Qp7SLtKbkiByqDIgcqgyKbKNohmyjaIZso2iET AAAADAAAAAIAAAATAAAADAAAAAIAAABWAAAAxAIAAHEJAAApCQAA4gkAAGkJAACqAAAAjDHfIX8xw SFgMXohSTFHIS0xDiENMc}}8g6DCMINMwZiC+MEIgpzAdIJAw9x93MNIfXTCsH0Iwhh8mMF8fCTA5H+ ovFB/LL+8eqi/LHocvpx5kL4QePy9iHhgvQx7wLiQeyC4IHrAu+B2bLusdhC7eHW4u0h1WLscdPy6 8HSYush0OLqgd9C2fHdstmB3BLZEdpy2LHYwthR1xLYIdVi1/HTotfB0dLXsdAi17HeYsfR3JL-Ad rCyEHY8siR1yLJAdViyXHTksnx0dLKodACy1HeQrwR3HK88dqyveHZAr7h10KwAeWCsSHj0rJh4iK zoeBytQHu0qZx7SKLAeuCqZHp0qtB6DKs8eaSrsHk8qCx81KiofGypLHwEqbR/nKZAfzimH7Qp2x +bKQIggSkrIGgpVCBOKYAgNCmtIBsp3CACKQwh6Cg8Ic8obyδjaIQcqgyIeKlEiNiohIk4 q8iFkKsUhfCqaIZIqcCGpKkkhwCoiIdYq/SDsKtkgAiu4IBgrmCAuK3kgQytbIFgrQCBtKyUggSsM IJYr9R+qK98fvivJH9Erth/jK6Qf9iuTHwksgx8aLHcfLCxnHz0sWx9OLFAfXixGH24sPB99LDUfj CwtH5osJx+oLCEftiwdH8QsGR/RLBUf3iwTH+osEB/2LA4fAi0NHw4tDR8aLQ0fJi0NHzEtDR89LQ 8fSS0RH1UtEx9gLRYfbC0ZH3ktHR+ELSEfkS0mH5tKx+qLTAfti03H8MtPh/PLUUf3S1NH+ctUx8 DLmcfHS57HzcukR9RLqgfay7BH4Qu3B+dLvgfty4VIM8uMyDmLlEg/S5wIBQvkCApL68gPi/QIFMv 8CBmLxAheC8vIYkvTSGqL4khxy/BId8v8yHzLx0iDzBeIhYwcCITAAAADAAAAAIAAAATAAAADAAAA AIAAABWAAAAIAAAANAJAABhCQAA4wkAAG4JAAAxAAAAFjBwIhsweyIgMIYiJjCQIiswmiIyMKMiOD CsIj8wtCJGMLsiTTDCIlUwySJdMM8iZTDUIm0w2SJ1MN4ifjDiIocw5SKZMOsiqzDvIr4w8SLQMPE i4zDwIvUw7SIIMekiGTHiIiox2yI7MdIiSzHIIlkxvCJnMbAiczGiIn4xkiKIMYIijDF6Io8xcSKT MWgilTFfIpgxVSKZMUsimzFCIpsxNyKcMS0imzEjIpoxGCKZMQ0iljECIpQx9yGQMeshjDHfIRMAA AAMAAAAAgAAABMAAAAMAAAAAQAAACUAAAAMAAAABAAAACUAAAAMAAAAAwAAACgAAAAMAAAAAgAAAC UAAAAMAAAABwAAgCUAAAAMAAAA0AAAg.AAAAAMAAAADwAAgCUAAAAMAAAADgAAgEsAAAAQAAAAAAA AAAUAAAAoAAAADAAAAAMAAAAoAAAADAAAAAQAAAAlAAAADAAAAAAAAIAlAAAADAAAAAcAAIAiAAAA DAAAAP////8lAAAADAAAAA0AAIAoAAAADAAAAAEAAAAiAAAADAAAAP////8iAAAADAAAAP////9GA AAAcAAAAGQAAABFTUYrLEAAACQAAAAYAAAAZy+BPgAAAIAAAACAdSSBPlSeD0Wmcg9FKkAAACQAAA AYAAAAAACAPwAAAIAAAACAAACAPwAAAIAAAACAIUAHAAwAAAAAAAAABEAAAAwAAAAAAAAARgAAABQ AAAAIAAAAR0RJQwMAAABGAAAANAAAACgAAABFTUYrKkAAACQAAAAYAAAAAACAPwAAAIAAAACAAACA PwAAAIAAAACAIQAAAAgAAABiAAAADAAAAAEAAABMAAAAZAAAAGwHAACyBwAAhgoAADsKAABsBwAAs gcAABsDAACKAgAA KQCqAAAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAIgAAAAwAAAD/////RgAAABwAAAAQAAAARU1GKwJAAAAMAAAAAAAAAA4AAAAUAAAAAAAAABAAAA AUAAAA AAABAAEAICAQ/gAAAADoAgAAFgAAACgAAAAgAAAAQAAAAAEABAAAAAAAgAIAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/w D/AP//AAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAABmZmZmZmZmZmZmZmZoAAAAZmZmZmZmZmZmZmZmZoAAAGZmZmZmZmZm ZmZmZmZoAABmZmZmZmZmZmZmZmZmZgAAZmZmZmZmZmZmZmZmZmYAAGZmZmZmZmZ4PrQpUDwkLeg9kC5PYPb/D29v9vYGZmZgAAZgbwZvZvBm9m9mZmZmYAAGYGb2b2bwZvZvBvZmZmAABm9gb/b/b/9v9v8G ZmZgAAZmZmZmZmZmZmZmZmZmYAAGZmZmZmZmZmZmZmZmZmAABmZmZmZmZmZmZmZmZmZgAAZmZmZmZ mZmZmZmZmZmYAAGZmZmZmZmZmZmZmZmZmAABmZmZmaGZmat='' IconSize='1' AlignName='2' MatchByName='0' IconUpdate='1' UniqueID='{01E4C3DA-0013-0000-8E40-00608CF305B2}' BaseID='{6649EBFA-E92E-4D58-95A2-40628E525CDC}' PatternFlags='0' Hidden='0'>8.5110.1258D@@~@` `````~)C0047$`cî7$o\!Կݑ .̈́hh\;'OЩH>2q02a'iL1Lr onEJ4(jӘ ,-*pСvâZ؟PXj\sadb&CCYcF.rڅ'&E~7ªZ"M~a2 VE 2.ZQFE&E'|SSA%hMws,Hğ6'0dNΜ,Bzb<_DN 62 ;\8Wv%tbDD81wNA=q:hw|s0WrqucbSy.Mttttttttttttttttttttt_4i}@   !#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}%   !#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{} 89;=?AC !!!!! ! ! !!!!!!!!!!!!#!%!'!)!+!-!/!!13!5!7!9!;!=!?!A!C!E!G!I!K!M!O!Q!S!U!W!Y![!]!_!a!c!e!g!i!k!m!o!q!!u!w!y!{!}!!!!!!!!!"!!!!!!!!!!!!!!!!!!B!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!""""" " " """"""""""!"#"%"'")"+"-"/"1"1"5"7"9";"="?"A"C"E"G"I"K"M"O"Q"S"U"W"Y"["]"_"a"c"e"g"i"k"m"o"q"s"u"w"y"{"}""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""##### # # ##########!###%#'#)#+#-#/#1#3#5#7#9#;#=#?#A#C#E#G#I#K#M#O#Q#S#U#W#Y#[#]#_#a#c#e#g#i#k#m#o#q#s#u#w#y#{#}#################################################################$$$$$ $ $ $$$$$$$N3N5NN9N;N=N?NANCNENGNINK$$$!$Q$S$U$W$Y$[$]$_$a$c$e$g$i$k$m$o$q$s$u$w$y${$}$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$p$$$$%%%@   !#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}%   !#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{} ^^^^^^^^^^^^^^^^^^^^^^^^^^^_____ _ _ _________!_#_%_'_)_35FD+_ddddddddeeeee e e eeeeeeeeee!e#e%e'e)e+e-e/e1e3e5e7e9e;d=e?eAeCeEeGeIeKeMeOeQeSeUeWeYe[e]e_eaeceeegeiekemeoeqeseueweye{e}eeeeeeeeeeeeeeeeeeeee!C!E!G!I!K!M!O!Q!S!U!W!Y![!]!_!a!c!e!g!i!k!m!o!q!!u!w!y!{!}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-1""" " " """"""""""!"#"%"'*")"+"-"/"1"3"5"7"9";"="?"A"C"E"G"I"K"M"O"Q"S"U"W"Y"["]"_"a"c"e"g"i"k"m"o"q"s"u"w"y"{"}"""""""""""""""""""""""""ğ6'0dNΜ,Bzb<_DN 62 ;\8Wv%tbDD80wNA=q:hw|s1WrqucbSy.Mttttttttttttttttttttt_4i}@   !#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{} 79;=?AC !!!!! ! ! !!!!!!!!!!!!#!%!'!)!+!-!/!!13!5!7!9!;!=!?!A!C!E!G!I!K!M!O!Q!S!U 89;=?AC !!!!! ! ! !!!!!!!!!!!!#!%!'!)!+!-!/!!13!5!7!9!;!=!?!A!C!E!G!I!K!M!O!Q!S!U!W!Y![!]!_!a!c!e!g!i!k!m!o!q!!u!w!y!{!}!!!!!!!!!"!!!!!!!!!!!!!!!!!!B!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!""""" " " """"""""""!"#"%"'")"+"-"/"1"1"5"7"9";"="?"A"C"E"G"I"K"M"O"Q"S"U"W"Y"["]"_"a"c"e"g"i"k"m"o"q"s"u"w"y"{"}""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""##### # # ##########!###%#'#)#+#-#/#1#3#5#7#9#;#=#?#A#C#E#G#I#K#M#O#Q#S#U#W#Y#[#]#_#a#c#e#g#i#k#m#o#q#s#u#w#y#{#}#################################################################$$$$$ $ $ $$$$$$$N3N5NN9N;N=N?NANCNENGNINK$$$!$Q$S$U$W$Y$[$]$_$a$c$e$g$i$k$m$o$q$s$u$w$y${$}$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$p$$$$%%%@   !#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}%   !#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{} ^^^^^^^^^^^^^^^^^^^^^^^^^^^_____ _ _ _________!_#_%_'_)_35FD+_ddddddddeeeee e e eeeeeeeeee!e#e%e'e)e+e-e/e1e3e5e7e9e;d=e?eAeCeEeGeIeKeMeOeQeSeUeWeYe[e]e_eaeceeegeiekemeoeqeseueweye{e}eeeeeeeeeeeeeeeeeeeee!C!E!G!I!K!M!O!Q!S!U!W!Y![!]!_!a!c!e!g!i!k!m!o!q!!u!w!y!{!}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!""""" " " """"""""""!"#"%"'*")"+"-"/"1"3"5"7"9";"="?"A"C"E"G"I"K"M"O"Q"S"U"W"Y"["]"_"a"c"e"g"i"k"m"o"q"s"u"w"y"{"}"""""""""""""""""""""""""ğ6'0dNΜ,Bzb<_DN 62 ;\8Wv%tbDD80wNA=q:hw|s1WrqucbSy.Mttttttttttttttttttttt_4i}@   !#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{} 79;=?AC !!!!! ! ! !!!!!!!!!!!!#!%!'!)!+!-!/!!13!5!7!9!;!=!?!A!C!E!G!I!K!M!O!Q!S!U!W!Y![!]!_!a!c!e!g!i!k!m!o!q!!u!w!y!{!}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!""""" " " """"""""""!"#"%"'")"+"-"/"1"3"5"7"9";"="?"A"C"E"G"I"K"M"O"Q"S"U"W"Y"["]"_"a"c"e"g"i"k"m"o"q"s"u"w"y"{"}""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""##### # # ##########!###%#'#)#+#-#/#1#3#5#7#9#;#=#?#A#C#E#G#I#K#M#O#Q#S#U#W#Y#[#]#_#a#c#e#g#i#k#m#o#q#s#u#w#y#{#}#################################################################$$$$$ $ $ $$$$$$$N3N5N+oǗ7!q2YOu1Q>}?)/6v\#<p*_6p2_L H8jrcd֩A{2g&2q02a'iL1Lr onEJ4(jӘ ,-*pСvâZ؟PXj\sadb&CCYcF.rڅ'&%   !#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}   !#%')+-/13529;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}   !}E~7ªZ"M~a2 VE 2.ZQFE&E'|SSA%hMws,Hğ6'0dNΜ,Bzb<_DN w[y[{[}[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\\\\\ \ \ \\\\\\\\\\!\#\%\'\)\+\-\/\1\3\5\7\9\;\=\?\A\C\E\G\I\KF.@  GGGGGGGGGGGGGGGG@)GGGGGGGGGGGGGGGGG\\\\\\\\\\\\\\\\\\\]]]]] ] ] ]]]]]]]]]]!]#]%]'])]+]-]/]1]3]5]7]9];]=]?]A]C]E]G]I]K]M]O]Q]S]U]W]Y][]]]_]a]c]e]g]i]k]m]o]q]s]u]w]y]{]}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]Rcí[*.iMd@WmȄ)/DM':4ݎY #FLQQ.6%w] `SjLnilLzՓ<. ŘÕԽ.aсM!nLたxc)@r~pQLvPt^bAxr~`4D^\Z|Cl`|d7~|ZѸ@'FFȝ*#&5ި ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_____ _ _ _________!_#_%_'_)_35FD+_ddddddddeeeee e e eeeeeeeeee!e#e%e'e)e+e-e/e1e3e5e7e9e;d=e?eAeCeEeGeIeKeMeOeQeSeUeWeYe[e]e_eaeceeegeiekemeoeqeseueweye{e}eeeeeeeeeeeeeeeeeeeee2@@@``@@@````$.Mttttttttttttttttttttt_4i}@   !#%')+-/12579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}A$8A$I$X 1DAvAEAA$D) LDuA@D)A$A$DA$,H=DH=H=H=H=DH=DH=DH=DH=A$$I<$1$I$X 1t ]ԉA$As AE`$t]ԉu0LM4$A^ 1tRc1LK11L6 1Ev1D1EۉH[A\A]A^A_]UHAWAVAUATSPAIHdH;(sdH(DE|. DE1AAAA D)4)z)))M))))f)))8))) )R)))$)k)4;/AuGNTHZ`gmasy4zMf8 R$k*4*;/*Au*G*N*TH*Z*`*g*ma*s*y*Հ4*Նz*Ռ*Փ*ՙM*՟*ե*լ*ղf*ո*վ*8*** *R***$*k*0*40*;/0*Au0*G0*N0*TH0*Z0*`0*g0*ma0*s0*y0*40*z0*0*0*M0*0*0*0*f0*0*0*80*0*0* 0*R0*0*0*$0*k0*545;/5Au5G5N5TH5Z5`5g7ma5s5y545z555M5555f5558555 5R555$5k5:4:;/:Au:G:N:TH:Z:`:g:ma:s:y:Հ4:Նz:Ռ:Փ:ՙM:՟:ե:լ:ղf:ո:վ:8::: :R:::$:k:@*4@*;/@*Au@*G@*N@*TH@*Z@*`@*g@*ma@*s@*y@*4@*z@*@*@*M@*@*@*@*f@*@*@*8@*@*@* @*R@*@*@*$@*k@*E4E;/EAuEGENETHEZE`EgEmaEsEyE4EzEEEMEEEEfEE)8))) )R)))$)k)4;/AuGNTHZ`gmasy 4zMf8 R$k*4*;/*Au*G*N*TH*Z*`*g*ma*s*y*Հ4*Նz*Ռ*Փ*ՙM*՟*ե*լ*ղf*ո*վ*8*** *R***$*k*0*40*;/0*Au0*G0*N0*TH0*Z0*`0*g0*ma0*s0*y0*40*z0*0*0*M0*0*0*0*f0*0*0*80*0*0* 0*R0*0*0*$0*k0*545;/5Au5G5N5TH5Z5`5g5ma5s5y545z555M5555f5558555 5R555$5k5:4:;/:Au:G:N:g:ma:s:y:Հ3:Նz:Ռ:Փ:ՙM:՟:ե:լ:ղf:ո:վ:8::: :R:::$:k:@*4@*;/@*Au@*G@*N@*TH@*Z@*`@*g@*ma@*s@*y@*4@*z@*@*@*M@*@*@*@*f@*@*@*8@*@*@* @*R@*@*@*$@*k@*E4E;/EAuEGENETHK11L6 1Ev1D1EۉH[A\A]A^A_]UHAWAVAUATSPAIHdH;(sdH(DE|. DE1AAAA D)4)z)))M))))f)))8))) )R)))$)k)4;/AuGNTHZ`gmasy4zMf8 R$k*4*;/*Au*G*N*TH*Z*`*g*ma*s*y*Հ4*Նz*Ռ*Փ*ՙM*՟*ե*լ*ղf*ո*վ*8*** *R***$*k*0*40*;/0*Au0*G0*N0*TH0*Z0*`0*g0*ma0*s0*y0*40*z0*0*0*M0*0*0*0*f0*0*0*80*0*0* 0*R0*0*0*$0*k0*545;/5Au5G5N5TH5Z5`5g7ma5s5y545z555M5555f5558555 5R555$5k5:4:;/:Au:G:N:TH:Z:`:g:ma:s:y:Հ4:Նz:Ռ:Փ:ՙM:՟:ե:լ:ղf:ո:վ:8::: :R:::$:k:@*4@*;/@*Au@*G@*N@*TH@*Z@*`@*g@*ma@*s@*y@*4@*z@*@*@*M@*@*@*@*f@*@*@*8@*@*@* @*R@*@*@*$@*k@*E4E;/EAuEGENETHEZE`EgEmaEsEyE4EzEEEMEEEEfEE)8))) )R)))$)k)4;/AuGNTHZ`gmasy 4zMf8 R$k*4*;/*Au*G*N*TH*Z*`*g*ma*s*y*Հ4*Նz*Ռ*Փ*ՙM*՟*ե*լ*ղf*ո*վ*8*** *R***$*k*0*40*;/0*Au0*G0*N0*TH0*Z0*`0*g0*ma0*s0*y0*40*z0*0*0*M0*0*0*0*f0*0*0*80*0*0* 0*R0*0*0*$0*k0*545;/5Au5G5N5TH5Z5`5g5ma5s5y545z555M5555f5558555 5R555$5k5:4:;/:Au:G:N:g:ma:s:y:Հ3:Նz:Ռ:Փ:ՙM:՟:ե:լ:ղf:ո:վ:8::: :R:::$:k:@*4@*;/@*Au@*G@*N@*TH@*Z@*`@*g@*ma@*s@*y@*4@*z@*@*@*M@*@*@*@*f@*@*@*8@*@*@* @*R@*@*@*$@*k@*E4E;/EAuEGENETHEZE`EgEmaEsEyE4EzEEEMEEEEfEEE8EFEE EREEE$EkEJ4J;/JAuJGJNJTHJZJ`JgJmaJsJyJՀ4JՆzJՌJՓJՙMJ՟JեJլJղfJոJվJ8JUMUUUUfUUU0UUU URUUU$UkUZ4Z;/ZAuZGZNZTHZZZ`ZgZmaZsZyZՀ340282366920938463463374607431768211457ZՆzZՌZՓZՙMZ՟ZեZլZղfZոZվZ8ZZZ ZRZZ EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEZYZ[Z]Z_ZaZcZeZgZikZmZoZqZsZuZwZyZ{Z}ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ,,,,,,o,,,e , ,,,,eeeeeemoqsuwy{}fpZ)nIriD asC=~ڐs^dW]ɚo.!pFq 0&Ab Ic\1i0ڒDPawFE]CV m2_=(]cA:]K=4^~gS-ڽ=}Þ3E <ݎ~RO@';ucqs1fbX$\ߢ b(*d)ڸD" 6v.0<󲹯ҶGLͻɵWL#$,V\%ql/iD#Ńo 48ғ?0>OT֗FK\EN^M (tz7yJY"A 8yrL!ߢxq1VŻQ, 5B!zhsHB7_A+\[ wa "W`4V~BEw#:'D; о@jGt*XdiY5+]Z ,!/OTC9Z)띝ʪ\4ntS@ZBӣfe ZJPIq_f͇nȒlR^_]!lcP!ԀU?@n_nzoendstream endobj 6 0 obj 3605 endobj 17 0 obj <> stream xuX۲Ժ}vX9/á>Jў12djɲ=~cKիW.X@oQo6a~Fl)j RzmII<Ȗ~ݽl|JpnOo`r׿}^_>݋dι%Xu֨4u}6LpɅ1筈(fʼ@k{$e);ñgjr9IT8~kLt忧N=kM}JpY$ R/o92A"̑ _t$ICLc !Jrux܇f@UņYUi¥h>gugU?"HWiC9J<] 38Z:?螁[JZ^ٗ́=vmM׬}݈K?ob x/\~cדU)fpZ)nIriD asC=~ڐs^dW]ɚo.!pFq 6&Ab Ic\4i4ڒDPawFE]CV m5_=2q02a'iL1Lr onEJ4(jӘ ,-*pСvâZ؟PXj\sadb&CCYcF.rڅ'&E~7ªZ"M~a2 VE 2.ZQFE&E'|SSA%hMws,Hğ6'0dNΜ,Bzb<_DN 62 ;\8Wv%tbDD80wNA=q:hw|s0WrqucbSy.Mttttttttttttttttttttt_4i}@   !#%')+-/12579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}579;=?ACEGIKMOQSUWrY[]_aceyyyyygikmoqsuwy{}~   !#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}! P !gikmoqsuwy{}X   !#%')+-/10579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}t   !#%')+-/13579;=1ACEGIKMOQSUWY[]_acegikmoqsuwy{}   !#%')+-/13579;=?ACEGIKMOQSUWY[c_acegikmoqsuwk{}   !#%')+-/03578;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}   !#%')+-/13579;=?ACEGIKMOQSU! P !gikmoqsuwy{}X   !#%')+-/10579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}t   !#%')+-/13579;=1A֓֋֖]ֶԖCEGIKMOQSUWY[]_acegikmoqsuwy{} CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC4% CCCCCCCCCCCCCCCCCCCCCCCAA$QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ[QQQQQQQQ% ?0@@A2A2A2@@@@@@@@@@@@@@@@A$QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ[QQQQQQQQ% ?7@@%%%%%%%%%%%%%}}}}}}A2A2@@@@@@@@@@@@@@<@@>'''''   !#%')+-/13579;=?ACEGIKMOQSUWY[c_acegikmoqsuwk{}   !#%')+-/03578;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}   !#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqrsuwy{}   kmo qsuwy{}              ! # % ' ) + - / 0 3 5 7 9 ; = ? A C E G I K M O Q S U W Y [ ] _ a c e g i k m o q s u w y { } ' 39;=?AC !!!!! ! ! !!!!!!!!!!!!#!%!'!)!+!-!/!1!3!5!7!9!;!=!?!A!C!E!G!I!K!M!O!Q!S!U!W!Y![!]!_!a!c!e!g!i!k!m!o!q!!u!w!y!{!}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!""""" " " """"""""""!"#"%"'*")"+"-"/"1"3"5"7"9";"="?"A"C"E"G"I"K"M"O"Q"S"U"W"Y"["]"_"a"c"e"g"i"k"m"o"q"s"u"w"y"{"}""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""##### # # ##########!###%#'#)#+#-#/#1#3#5#7#9#;#=#?#A#C#E#G#I#K#M#O#Q#S#U#W#Y#[#]#_#a#c#e#g#i#k#m#o#q#s#u#w#y#{#}#################################################################$$$$$ $ $ $$$$$$$N3N5NN9N;N=N?NANCNENGNINK$$$!$Q$S$U$W$Y$[$]$_$a$c$e$g$i$k$m$o$q$s$u$w$y${$}$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$|\0[}056_A*aUvض`]{KEJq$_/)5Wt C^/-lW!xe$Z BVE))|B*VDΰ] 45DʇAβxLl[s|}r2]={4;AiHa/%|; uL=^!h9OTCl?([ <@*?Rk8uuvζX&i%i5EE[W'cqi?6 6O"Hb0Y¹k3me/zM76} >^fٺe( _ҐDI }?)/6v\#<p*_6p2_L H8jrcd֩A{2g&2q02a'iL1Lr onEJ4(jӘ ,-*pСvâZ؟PXj\sadb&CCYcF.rڅ'&E~7ªZ"M~a2 VE 2.ZQFE&E'|SSA%hMws,Hğ6'0dNΜ,Bzb<_DN 62 ;\8Wv%tbDD81wNA=q:hw|s0WrqucbSy.Mttttttttttttttttttttt_4i}@   !#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}%   !#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{} 89;=?AC !!!!! ! ! !!!!!!!!!!!!#!%!'!)!+!-!/!!13!5!7!9!;!=!?!A!C!E!G!I!K!M!O!Q!S!U!W!Y![!]!_!a!c!e!g!i!k!m!o!q!!u!w!y!{!}!!!!!!!!!"!!!!!!!!!!!!!!!!!!B!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!""""" :2% ``````````@@@@@@@(4(44 P^5^5RM֓,,,,,,,,,,,,?:A0zo.=+z%]e!!a,,,,CCCCCCCCCCCC!CCA®CCCCCC,,,,CCCCCCCCCCCC!CCA®CCCCCCCCCCCCCCCC],C@CCCCCCCCCJJJJJJJJJJJ__)________,,,,CCCCCCCCCCCC!CCA®CCCCCC,,,,CCCCCCCCCCCC!CCA®CCCCCCCCCCCCCCCC```````````@@````@@@@>@@@@@@@@@d@@@@@@@@D@````$````$'4% 4% &APA24% &APA&APA2AAزd2AA&APA24% &APA8% &APA24% &APA2AAزd2AA&APA2AAزd2AA<%%%%%%%9444444444444444444%%.&%%%%%%%%y@'S101t'522%%%)%}555%9444444444444444444%%.&%%%%%%%%qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqy@'55555555A55555555555555555555555555555555*@##@1#@`<%2@F`@` ݿ```````b0@@@``+++++++ķ%%%})`/VT~! A%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝ(HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHH`HHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXH2554y@z'Rҙb/1ß@`;@BHHHHHHHHHH}@AAޔy@'Rҙb/2@F@`@BHHHHHHHHHH@AAޔy@@BHHHHHHHHHH}@AAޔy@'Rҙb/2@F@`@BHHHHHHHHHH@AAޔy@' AA?1@fa' AA?1@faKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'//zS?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHFHHH%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?HHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHhH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%%%%%%%%%%%%%%%'%%%%Kø@%%]%%%%%%%%*%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHH%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝ2614@'HdHHHHHHHHHHHHHHHHy@z'S?@'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHH%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?HHHHHHHHy@z'S%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@ 'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHH?ҙ Kø@%%]%%%%%%%%*%?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝ(HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHH`HHHHHHHHHHҝHHHHHHAHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%%%%%%%%%HHHHHHHHHHHH?ҙ @'H<%%%%%%%%%%%%%%%%%%% ò?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHH%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHH HHHHHHHy@z'S?HHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHhH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHH%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHH%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%HHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝ(HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'/HHHHH`HHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Ý%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHH%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHH%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%HHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~iiiiiiii%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%:ł::::ffffffffffffff%~%Kø@%%]%%%%%%%%*%?Kø@%%]%%%%%%%%~%S;%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdH<%y@%%%%%%%%%iiiiiiiiiiiiiii.........HHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝ(HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝ-@ CCCCCCCC-QQ@N@-QN@CCCCCCCCCL,Q@`-QQ@N@-QN@CCCCCCCC@N@-QN@CCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@-@ CCCCCCCC-QQ@N@-QN@CCCCCCCCCL,Q@CRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QNRN@-QN@CCCCCCCC@N@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRQN@CCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QNRN@-QN@CCCCCCCC@N@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-CCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRN@-QN@CCCCCCCC@N@-N@CCCCCCCCCL,Q@Q@N@-QN@CCCCCCCC-QQ@N@-QN@CCCCCCCCCL,Q@`-QQ@N@-@ CCCCCCCC-QQ@N@-QN@CCCCCCCCCL,Q@`-QQ@N@-QN@CCCCCCCC@N@-QN@CCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QNRN@-QN@CCCCCCCC@N@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEQQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRQN@CCCCCCCRRRRRRRRRRRRRRRRRRRR RRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QNRN@-QN@CCCCCCCC@N@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@NCCCCCCCCCL,Q@`-QQ@N@-QN@CCCCCCCC@N@-QN@CCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@-@ CCCCCCCC-QQ@N@-QN@CCCCCCCCCL,Q@CRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QNRN@-QN@CCCCCCCC@N@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRQN@CCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QNRN@-QN@CCCCCCCC@N@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-CCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRN@-QN@CCCCCCCC@N@-N@CCCCCCCCCL,Q@Q@N@-QN@CCCCCCCC-QQ@N@-QN@CCCCCCCCCL,Q@`-QQ@N@-@ CCCCCCCC-QQ@N@-QN@CCCCCCCCL,Q@`-QQ@N@-QN@CCCCCCCC@N@-QN@CCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QNRN@-QN@CCCCCCCC@N@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEQQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRQN@CCCCCCCRRRRRRRRRRRRRRRRRRRR RRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QNRN@-QN@CCCCCCCC@N@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@N@-QN@CCCNCCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QNRN@-QN@CCCCCCCC@N@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCN@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QNRN@-QN@CCCCCCCC@N@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRR@CCCCCCCC@N@-N@CCCCCCCCCL,Q@Q@N@-QN@CCCCCCCC-QQ@N@-QN@CCCCCCCCCL,Q@`-QQ@N@-@ CCCCCCCC-QQ@N@-QN@CCCCCCCCCL,Q@`-QQ@N@-QN@CCCCCCCC@N@-QN@CCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QNRN@-QN@CCCCCCCC@N@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-طQN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRQN@CCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QNRN@-QN@CCCCCCCC@N@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-CCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRN@-QN@CCCCCCCC@N@-N@CCCCCCCCCL,Q@Q@N@-QN@CCCCCCCC-QQ@N@-QN@CCCCCCCCCL,Q@`-QQ@N@-@ CCCCCCCC-QQ@N@-QN@CCCCCCCCCL,Q@`-QQ@N@-QN@CCCCCCCC@N@-QN@CCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QNRN@-QN@CCCCCCCC@N@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRQN@CCCCCCCRRRRRRRRRRRRRRRRRRRR RRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-Q@-QN@CCCNCCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QNRN@-QN@CCCCCCCC@N@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCN@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QNRN@-QN@CCCCCCCC@N@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcQN@CCCCCCCCCL,Q@`-QQ@N@-QN@CCCCCCCCCCCCC@N@-QN@CCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QNRN@-QN@CCCCCCCC@N@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRQN@CCCCCCCRRRRRRRRRRRRRRRRRRRR RRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QNRN@-QN@CCCCCCCC@N@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QN@CCCcCCCC@N@-QN@CCCN@-QN@CCCCCCCCRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`-QQ@N@-QNRN@-@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHhH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ((((((sfs( ((@(#2614@'HdHHHHHHHHHHHHHHHHy@&&&&<&0:::::::::ł::::::&&&&<&@::::::::ł:::::::::ł:::-:::&&&&<&@K@:::::::z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ H'@HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%%%%%%%%%%%%%.$-t-1 362 <%y@<%y%#y@<%y@<%y@%%%%%%%%%..........020%%%.......:=$1%%@3333M666A33`AAAAAAAȾAAA51AAA31`AAAA0:::::::::ł::::::&&&&<&@::::::::ł:::::::::ł:::-:::&&&&<&@%K@::::::::ł::::::&&&&<AAA31`AAAA0:::::::::ł:::AAA51AAA31`AAAA0:::::::::ł::::::&&&&<&@::::::::ł:::::::::ł:::-:::&&&&<&@:&&&&<AAA-1979875316435`AAAA0:::::::::ł::::::&&&&<&@::::::::ł:::::::::ł:::-:::&&&&<&0:::::::::ł::::::&&&&<&@::::::::ł:::::::::ł:::-:::&&&&<&@K@::::::::ł::::ffffffffffffff%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%@A@@M@@bè%%]%%%%%%%%~-, RMz/ %AAAAAAA< /%IAADkd%AAAAAAA< /%IAA1%%AAAAAAA< /%IAA1%DkHHHA%D@````0%$1%DkHHHA%ÊU$UUAҠҔy@<%y%#y@<%y@<%y@%%%%%%%%%..........020%%%.......:=$1%%@3333M666A33`AAAAAAAȾAAA51AAA31`AAAA0:::::::::ł::::::&&&&<&@::::::::ł:::::::::ł:::-:::&&&&<&@%K@::::::::ł::::::&&&&<AAA31`AAAA0:::::::::ł:::AAA51AAA31`AAAA0:::::::::ł::::::&&&&<&@::::::::ł:::::::::ł:::-:::&&&&<&@:&&&&<AAA-1979875316435`AAAA0:::::::::ł::::::&&&&<&@::::::::ł:::::::::ł:::-:::&&&&<&0:::::::::ł::::::&&&&<&@::::::::ł:::::::::ł:::-:::&&&&<&@K@::::::::ł::::ffffffffffffff<%y@%%%%%%%%%iiiiiiiiiiiiiii.........<%y@%%%%%%%%%261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHH%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%\?| d]9223372036547758079223358070X @?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHH%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%HHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~iiiiiiii%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%:ł::::ffffffffffffff%~%Kø@%%]%%%%%%%%*%?Kø@%%]%%%%%%%%~%S;%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdH<%y@%%%%%%%%%iiiiiiiiiiiiiii.........HHHHHHHHHHHHHHHy@z'S?M@`M@`%%%%%%%%%HHHHHHHHHHHHҝ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝ(HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%%%%%%%%%HHHHHHHHHHH<%y@%%%%%%%%%iiiiiiiiiiiiiii..........40%%%.......:=$1%%%%00%iiiiiiiiiiiiiiiiiiiiiiiiiiinnnnnH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%?ҙ @'Hؔiiiiiii..........4HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHH`HHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%?Kø@%%]%%%%%%%%~%0%%%.......:=$1%%%%00%iiiiiiiiiiiiiiiiiiiiiiiiiiin%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Kø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHHҝKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~%Kø@%%]%%%%%%%%*%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ261HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2614@'HdHHHHHHHHHHHHHHHHy@z'S?nnnnKø@%%]%%%%%%%%~%%%%%%%%%HHHHHHHHHHHH?ҙ @'HHXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH^Ҡ2624@'HHHHHHHHHHHHHHHHHy@z'%%:-S?103t'5224@'HHS4@'HdHHHHHHHHHHHHHHHHy@z'S?Knnnnnnnnø@%%]%%%%%%%%~%%%%%%%%%%%HHHHHHHHHHHH?ҙ @'H?HXHHHHHHHHHHHHHHy@z'HHHHHHHHHHHHHHHҝ2%%z:-2%%zHHHHHHHHHHHHHHHHHH%%]%%%%%%%%~`<I%%]%%%%%%%%~%J%%]%%%.%%]%%%%%%%%%%%Ү RM/J%%~%J%%]%%%.%%]%%%%%%%%%%%Ү RM/Jk%%]M/Jkk/-D% u%%%%%%%%1Ү RM/J% u%%%%%%%%Ү RM/J%%%%%%%%%%Ү RM/Jk%%]M/Jkk/kkkkk% u%%%%%%%%Ү RM/J% k%%]M/Jkk/-D% u%%%%%%%%1Ү RM/J% u%%%%%%%%Ү RM/J%%%%%%%%%%Ү RM/Jk%%]M/Jkk/% u%%%%%%%%Ү RM/J% k%%]M/Jk k/-D% u%%%%%%%%1Ү RM/J% u%%%%%%%%Ү RM/J%%%%%%%%%%Ү RM/Jk%%]M/Jkk/kk%%]M/Jkk/-D% u%%%%%%%%1Ү RM/J% u%%%%%%%%k/kkku% % `y@z'S?103-----------------------------------HHHHHHHHHHHHHHHHy@z'S?103t'5224@'HHHHHHHHHHHHHHHHHHHHHHHHHHHH<%%Õßß X+<:QM_ü@%%%%%ü@%%<%%%%%%ü@?00@%%%%%%%%%%%%%%%%%5%%%%%%%%%%<%%%%%%%@@@@@@@@@@"""""""""//%%%%%%%%%%%%%%%%%% FFFFFFFFFF%%%%-%%%%%%%%%%%%%%%%%b%%%%%%%%%%%%%%%%%%%%%%%%%G?@%%%%%%%%%%%%%%%%%%%%%<%%%%%%%%%%%%%%%%%%%%%%%øø@0@000@Gø%%7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777ø@ @@%%%ø@*''''''''''''''''''''''''''''''P@@@LLLLLLLLLLLLLLLLLLLLLLLLL@>@@@%%%%%%%%%%%%%% @C@@>@@@@@@@@@@@@@P@@@@@@@@@@@@@@@@@-''''''''''''''''''''''''''''''Pҿ2@@@``` '80;>?ACEGIKMOF(: yHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHIIIII I IIIIIIIICN?LMNTUVWXYZ[\]^_`abcdefghijkl+>@@@@@@@@@@@@@@JJJJ%%%J@@@@@@@@@@@@@@@@@@@@@@@@`0`+`kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk{kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk0kkkkkkkkkkkkkkkkkkk%kkkk````````@```@``@>@@@@D@@@@@@@@@@@````````@```@```````@```@``82@82@@@@@``````@@@``82@@@````%%%%%%%-2%%JMM?M?')+-/21580;>CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCbbbbbbbbbbbbbbbbbb"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbabbbbbbbbcbbbbbbbbbbbbbbbbbbCCbbbbbbbbbbbb+-/21580;>?Abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb2```````````````@@@@>@@@@D@@@@@@@@@@@@@@@@`````@@@@@""""""""""""""""""""""""""""""""""""""""c//"/ @@@@@@7036261t' \?| d]9223372036547758079223358070X @"""""""""""""""""""""""""""""c//"/%%%%%%%-2%%7036261|t' %%%A%%%%%%%%%%%%%%%%%%%%.8............000%%%%%%%%%%%%%%................01000@00AK@`@F@`(`#@CC$@`ww Cstseam @+*$>@@EUHӈt]};#^  V0 R/Filtex /FlateD wecode>> ww Cstseam @+*$>@@EUHӈt]};#^(EE$a$$$$$  V5 R/Filtex /FlateD wecode>> ww Cstseam @+*$>@@EUHӈt]}#^``OW-BQ--A4y--y-BQ--A-BQ--A---A-BQ--A-- -- A-> @E ^`,([((#(((,*[((#(((((]3#(((#(((((2@N`@`KEEED@kk% u%%%%%%%%Ү RMI%%]%%%%%%%%~%J`@#`FD@`@`````888888$88888888888888884@#@`@@#@`@%@@@@@@@@@@@@@@`@@]ԮRM RM/Կ2Kø@%%]%%%%%%%%~%/%%]%%%%%%%%~%J[%%]%%%%%%%%%%k%Ү RM/kHHHHҝ%%%%%%%%HHHHHHHHHHHHҙ<%% RM/@@@$@@@@@@@@@@@`@@ԮRM RM/?Y103t'%5224`603t'522HHHHHHXXXXXXBXXVXXXXXXXXXXXXXXXXXXXXXXXXXXҙ5224@'HSHHHHHHHHHHHHHHHHHHHHHH%U$UU$?Y103t'%5224`6H5224`6HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXBX$?Y103t'%5224`603t'522HHHHH'HXX--˳k@A@A@+++++++++zAAA@@@`````@@@@>@@@@`@@@J.%%]n%%%%%%%%~%%%%%%%%%%%<5,((((((((((((#((Ό(((,,,,6((((((((((((((%(#(((((( 8(((( 8(((,((((((((((((((#(((((( 8(((((*(#((Ό(((((,,,(#((Ό(((,,,,6((((((((((((((%(#(((((( 8(((( 8(((,((((((((((((((#(((((( 8(((((*(#((Ό(((((,,,,6(((((((((((((((#(((((( ]8(((((((#((Ό(((,,,, (#(((((( ,6(((((((((((((((#(((((( ]8(((((((#((Ό(((,,,, (#(((((( 8(%((,,,,6(((((((((((((((#(((((( 8(((((((#((Ό(((((,,,,6(((((((((((((((#(((((( %8(((((((#((((8(((((((((('((,("0(D= J@(u@@@@@@@@@````.+````@@""""""""""""""""""""""""""""""""""""""""""""""""""""""[;r|. N EGENETHEZE`EgEmaEsEyE4EzEEEMEEEEfEEE8EFEE EREEE$EkEJ4J;/JAuJGJNJTHJZJ`JgJmaJsJyJՀ4JՆzJՌJՓJՙMJ՟JեJլJղfJոJվJ8JUMUUUUfUU,(( (CC%CCC=CwC,,,,CCCCCCCCCCCACC,CCCCCCCCCCCCCCCCC=CwC,,,,CCCCCCCCCCCCCCCCCCCCCCCCCCCz)=CC,,,C,CCCCCCCCCCCCCCCCCCCCCz@@@@@@a@@,,,,CCCCCCCCCC%CCC=CCL,,,CCCCCCCCCCACC,,,,CCCCCCCCCC%CCC=CCL,,,CCCCCCCCCCACC,CCCCCCCCCCCCCCCCC=CwC,,,,CCCCCCCCCCCCCCCCCCCCCCCCCCCz)=CC,,,C,CCCCCCCCCCCCCCCCCCCCCz@@@@@@a@@,,,,CCCCCCCCCC%CCC=CCL,,,CCCCCCCCCCACC,CCCCCCCCCCCCCCCCC=CwC,,,,CCCCCCCCCCCCCCCCCCCCCCCCCCCz)=CC,,,C,CCCCCCCCCCCCCCCCCCCCCz@@@@@@a@@,,,,CCCCCCCCCC%CCC=CCL,,,CCCCCCCCCCACC,CCCCCCCCCCCCCCCCC=CwC,,,,CCCCCCCCCCCCCCCCCCCCCCCCCCCz)=CC,,,C,CCCCCCCCCCCCCCCCCCCCCz@@@@@@a@@,,,,CCCCCCCCCC% EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEN̵-A O*U@ ߒ RM RMǮ/JRMǮخ/JKA`[E[:>:]*()()\2\2\2\2\2\2\2\2\2\2\2T2\2\R2\2\2\2\2\2\\2\22\22\\2\2\2\\2\M2\\2\2\2\2\2\2\2\22\2\2\23\2\2\2\2\2T2\2\R2\2\2\2\2\2\\2\2\22\2\2\\2\2\2\1\2\2\\2\2\2\2\2\2\22\2\2\2\\2\2\22\2\2\2\2\1\2\M2\\2\2\2\2\2\2\2\22\2a\2\2\2()()\2\2\2\2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][Z:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:N:-][00000-][::-][[-][:-][:[-][:-][:-][:!000000000000000000-][:![-][:-][:][:-]][:000000000000000000000000000000p00000000000000000000000000000000\2\2\2\2\2\2\2\2\2\2\2\2\00000000000000000000000000000000000000000000080000-][:@::(((((((((((((((((((((((((((((((((((ttttttttt********************\ \\Φ))))))))))))))):((((((((((((((((((((((((((((((:#"*:0000000000000000000000.(z00000002][:-]][:00000000000000000000000000000000000000000000000000000*(("*:0000000000000000000000\2\2\2\2\[.\2\2\2\2\2\2\2\2\2\2\2\000000000000000000000000000000000-][:@[()()\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\oooooooooooooooooo:]\ \\ [:!<:]]\ \******************************************[-][:-][:-][:]][:00000000000000000000000000000000000000008000000000000000000000000000000000000000-][::-][2\2\2\2+][:]2![-][:-][:]2xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:N:-][00000-][::-][[-][:-][:[-][:-][:-][:!000000000000000000-][:![-][:-][:][:-]][:000000000000000000000000000000p00000000000000000000000000000000\2\2\2\2\2\2\2\2\2\2\2\2\00000000000000000000000000000000000000000000080000-][:@::(((((((((((((((((((((((((((((((((((ttttttttt********************\ \\Φ))))))))))))))):((((((((((((((((((((((((((((((:#"*:0000000000000000000000.(z00000002][:-]][:00000000000000000000000000000000000000000000000000000*(("*:0000000000000000000000\2\2\2\2\[.\2\2\2\2\2\2\2\2\2\2\2\000000000000000000000000000000000-][:@[()()\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\oooooooooooooooooo:]\ \\ [:!<:]]\ \******************************************[-][:-][:-][:]][:00000000000000000000000000000000000000008000000000000000000000000000000000000000-][::-][2\2\2\2+][:]2![-][:-][:]2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaa*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:N:-][00000-][::-][[-][:-][:[-][:-][:-][:!000000000000000000-][:![-][:-][:][:-]][:000000000000000000000000000000p00000000000000000000000000000000\2\2\2\2\2\2\2\2\2\2\2\2\00000000000000000000000000000000000000000000080000-][:@::(((((((((((((((((((((((((((((((((((ttttttttt********************\ \\Φ))))))))))))))):((((((((((((((((((((((((((((((:#"*:0000000000000000000000.(z00000002][:-]][:00000000000000000000000000000000000000000000000000000*(("*:0000000000000000000000\2\2\2\2\[.\2\2\2\2\2\2\2\2\2\2\2\000000000000000000000000000000000-][:@[()()\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\oooooooooooooooooo:]\ \\ [:!<:]]\ \******************************************[-][:-][:-][:]][:00000000000000000000000000000000000000008000000000000000000000000000000000000000-][::-][2\2\2\2+][:]2![-][:-][:]2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:N:-][00000-][::-][[-][:-][:[-][:-][:-][:!000000000000000000-][:![-][:-][:][:-]][:000000000000000000000000000000p00000000000000000000000000000000\2\2\2\2\2\2\2\2\2\2\2\2\00000000000000000000000000000000000000000000080000-][:@::(((((((((((((((((((((((((((((((((((ttttttttt********************\ \\Φ))))))))))))))):((((((((((((((((((((((((((((((:#"*:0000000000000000000000.(z00000002][:-]][:00000000000000000000000000000000000000000000000000000*(("*:0000000000000000000000\2\2\2\2\[.\2\2\2\2\2\2\2\2\2\2\2\000000000000000000000000000000000-][:@[()()\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\oooooooooooooooooo:]\ \\ [:!<:]]\ \******************************************[-][:-][:-][:]][:00000000000000000000000000000000000000008000000000000000000000000000000000000000-][::-][2\2\2\2+][:]2![-][:-][:]2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9ł73M6 ł7`M6 UEE@EEE@EEE`@ł73M6 UEE@```*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:N:-][00000-][::-][[-][:-][:[-][:-][:-][:!000000000000000000-][:![-][:-][:][:-]][:000000000000000000000000000000p00000000000000000000000000000000\2\2\2\2\2\2\2\2\2\2\2\2\00000000000000000000000000000000000000000000080000-][:@::(((((((((((((((((((((((((((((((((((ttttttttt********************\ \\Φ))))))))))))))):((((((((((((((((((((((((((((((:#"*:0000000000000000000000.(z00000002][:-]][:00000000000000000000000000000000000000000000000000000*(("*:0000000000000000000000\2\2\2\2\[.\2\2\2\2\2\2\2\2\2\2\2\000000000000000000000000000000000-][:@[()()\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\oooooooooooooooooo:]\ \\ [:!<:]]\ \******************************************[-][:-][:-][:]][:00000000000000000000000000000000000000008000000000000000000000000000000000000000-][::-][2\2\2\2+][:]2![-][:-][:]2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaa*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:N:-][00000-][::-][[-][:-][:[-][:-][:-][:!000000000000000000-][:![-][:-][:][:-]][:000000000000000000000000000000p00000000000000000000000000000000\2\2\2\2\2\2\2\2\2\2\2\2\00000000000000000000000000000000000000000000080000-][:@::(((((((((((((((((((((((((((((((((((ttttttttt********************\ \\Φ))))))))))))))):((((((((((((((((((((((((((((((:#"*:0000000000000000000000.(z00000002][:-]][:00000000000000000000000000000000000000000000000000000*(("*:0000000000000000000000\2\2\2\2\[.\2\2\2\2\2\2\2\2\2\2\2\000000000000000000000000000000000-][:@[()()\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\oooooooooooooooooo:]\ \\ [:!<:]]\ \******************************************[-][:-][:-][:]][:00000000000000000000000000000000000000008000000000000000000000000000000000000000-][::-][2\2\2\2+][:]2![-][:-][:]2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:N:-][00000-][::-][[-][:-][:[-][:-][:-][:!000000000000000000-][:![-][:-][:][:-]][:000000000000000000000000000000p00000000000000000000000000000000\2\2\2\2\2\2\2\2\2\2\2\2\00000000000000000000000000000000000000000000080000-][:@::(((((((((((((((((((((((((((((((((((ttttttttt********************\ \\Φ))))))))))))))):((((((((((((((((((((((((((((((:#"*:0000000000000000000000.(z00000002][:-]][:00000000000000000000000000000000000000000000000000000*(("*:0000000000000000000000\2\2\2\2\[.\2\2\2\2\2\2\2\2\2\2\2\000000000000000000000000000000000-][:@[()()\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\2\oooooooooooooooooo:]\ \\ [:!<:]]\ \******************************************[-][:-][:-][:]][:00000000000000000000000000000000000000008000000000000000000000000000000000000000-][::-][2\2\2\2+][:]2![-][:-][:]2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:]][^:][^:][^:][^:][^::][^:][^:][^:][^:][^:][^:][^:][^:][^:][^:]][^::][^:][^:][^::][^:][^:][^:][^:][^:][\:]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~AAAAAAAAłRM%X mXXXXXXXXpX000d@󠁴mmmmmmmmm @/󠁴mmmm}mmmmmmXXXXXXXXpX000d@XXl@OBO@O@O@O@`ֿ#@`@`'O@O@O@O@O@O@`'C````@@`<%%AAAAAA2@@@``@@@#@O@O@Dk9#4`@`#@`#@`@@O@O@O@`ֿ#@`@`'@::::::::ł:::::::::UUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\CCCUUUUUUU\Cl]j_j0VX`x,(06TV"Ҷ jw:?}NFը S7P԰tϜθ-Js4dr䏞t`P̳ɠdjQPmBƮ]ˣܯ]S_bt?=0T"M삟#<& 1Wq]e-ZZ-r] D_Ґ;9ILPR7D?*z;^-Y+:^xLgYo9jsoncons-1.3.2/test/fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_csv-4925110364733440000066400000000000000000000000021477700171100324550ustar00rootroot00000000000000 jsoncons-1.3.2/test/fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_csv-5762751990595584000066400000000000000000000000101477700171100325130ustar00rootroot00000000000000 -6.6E6clusterfuzz-testcase-minimized-fuzz_csv_encoder-4850580052312064000066400000000000000000002302021477700171100341010ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/input,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1000E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E11E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1U16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E255 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1000E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E161 16E 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1EE16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E6 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E166 1E16 1E16 1E16 1E 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1EE16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 01E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 #1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E17 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1000E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1'E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 9E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E161 16E 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E1E66 111E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E08 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1U16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E255 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 696E16 1E16 1E16 18446744073709551615E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 116 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E255 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 696E16 1E16 1E16 18446744073709551615E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E161 16E 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E1E66 111E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1U16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E255 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 696E16 1E16 1E16 18446744073709551615E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 116 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E1. 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E06 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E17 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1000E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E161 16E 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E161E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 6 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E1z 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 9E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E15 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E255 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 696E16 1E16 1E16 18446744073709551615E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 116 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E1. 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E17 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E16 1E,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,clusterfuzz-testcase-minimized-fuzz_csv_encoder-5202115606872064.fuzz000066400000000000000000000000001477700171100350670ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/inputclusterfuzz-testcase-minimized-fuzz_csv_encoder-5682837304115200.fuzz000066400000000000000000000000311477700171100350730ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/input-E-1841678677841678677440clusterfuzz-testcase-minimized-fuzz_csv_encoder-5699775833047040000066400000000000000000000000241477700171100341260ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/input-9223372036854775808clusterfuzz-testcase-minimized-fuzz_json_cursor-5656793396150272000066400000000000000000000000001477700171100341730ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/inputclusterfuzz-testcase-minimized-fuzz_json_cursor-5686693027119104000066400000000000000000000000011477700171100341640ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/input[clusterfuzz-testcase-minimized-fuzz_json_cursor-6585089218707456000066400000000000000000000000011477700171100342010ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/input clusterfuzz-testcase-minimized-fuzz_json_encoder-5639543840702464000066400000000000000000000000351477700171100342770ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/input{":":[trueclusterfuzz-testcase-minimized-fuzz_json_encoder-5769370349076480000066400000000000000000033321071477700171100343220ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/input[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[446744073709551615,2e+0,2e+0 ,2 ,1844674406,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,6,7,3,6,9,9,6,7,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,9,6,7,6,6,6,7,6,9,9,6,7,6,7,6,9,8,9,[0],66,6,6,7,6,9,9,6,60,6,3,5,3,6,6,3,6,9,9,6,6,6,7,2,9,8,9,9,6,6,6,7,9,9,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,6,7,3,6,9,9,6,7,9,8,9,6,3,6,3,6,6,3,6,9,39,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,79,9,6,6,6,7,6,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,5,6,5,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,6,7,3,6,9,9,6,7,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,9,6,7,6,6,6,7,6,9,9,6,7,6,7,6,9,8,9,6,2,66,6,6,7,6,9,9,6,60,6,3,5,3,6,6,3,6,96,3,6,9,9,6,6,5,7,6,9,8,8,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,6,7,3,6,9,9,6,7,9,8,9,6,3,6,3,6,6,3,6,9,9,3,6,6,39,9,6,3,6,3,6,6,3,6,9,399,6,3,6,3,6,6,3,3,6,6,3,6,9,9,6,6,6,7,6,97,6,7,9,9,6,6,6,7,6,9,8,9,6,3,3,6,6,3,6,9,9,6,6,5,7,6,9,8,8,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,6,7,3,6,9,9,6,7,9,8,9,6,3,6,3,6,6,3,6,9,9,3,6,6,39,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,97,6,7,9,9,6,6,6,7,6,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,5,6,5,7,6,9,8,8,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,39,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,97,6,7,9,9,6,6,6,7,6,6,6,3,6,9,9,6,6,6,7,6,97,6,7,9,9,6,6,6,7,6,9,8,9,6,3,6,3,6,6,3,6,6,6,6,7,6,9,8,9,6,3,3,6,6,3,6,9,9,6,6,5,7,6,9,8,8,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,67,6,7,9,9,6,6,6,7,6,9,8,9,6,3,6,3,6,6,3,6,9,9,6,3,6,6,3,6,9,9,6,6,6,7,6,97,6,7,9,9,6,6,6,7,6,6,6,3,6,9,9,6,6,6,7,6,97,6,7,9,9,6,6,6,7,6,9,8,9,6,3,6,3,6,6,3,6,6,6,6,7,6,9,8,9,6,3,3,6,6,3,6,9,9,6,6,5,7,6,9,8,8,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,67,6,7,9,9,6,6,6,7,6,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,5,6,5,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,6,7,3,6,9,9,6,7,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,9,6,7,6,6,6,7,6,9,9,6,7,6,7,6,9,8,9,[0],66,6,6,7,6,9,9,6,60,6,3,5,3,6,6,3,6,9,9,6,6,6,7,2,9,8,9,9,6,6,6,7,9,9,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,1,6,9,7,6,9,8,8,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,39,8,9,6,3,6,3,6,6,39,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,39,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,97,6,7,9,9,6,6,6,7,6,6,6,3,6,9,9,6,6,6,7,6,97,6,7,9,9,6,6,6,7,6,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,5,6,5,3,6,9,6,9,9,6,6,97,6,7,9,9,6,6,6,7,6,9,8,9,6,3,5,3,6,6,3,6,9,9,6,6,6,7,2,9,8,9,9,6,6,6,7,9,9,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,96,6,7,6,9,8,9,6,3,3,6,6,3,6,9,9,6,6,5,7,6,9,8,8,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,6,6,6,7,6,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,5,6,5,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,66,7,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,9,6,7,6,6,6,7,6,9,9,6,7,6,7,6,9,8,9,6,7,9,9,6,6,6,7,6,6,6,3,6,9,9,6,6,6,7,6,97,6,7,9,9,6,6,6,7,6,9,8,9,6,3,6,3,6,6,3,6,6,6,6,7,6,9,8,9,6,3,3,6,6,3,6,9,9,6,6,5,7,6,9,8,8,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,67,6,7,9,9,6,6,6,7,6,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,5,6,5,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,6,7,3,6,9,9,6,7,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,9,6,7,6,6,6,7,6,9,9,6,7,6,7,6,9,8,9,[0],66,6,6,7,6,9,9,6,60,6,3,5,3,6,6,3,6,9,9,6,6,6,7,2,9,8,9,9,6,6,6,7,9,9,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,63,6,3,6,6,3,6,9,39,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,79,9,6,6,6,7,6,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,5,6,5,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,6,7,3,6,9,9,6,7,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,9,6,7,6,6,6,7,6,9,9,6,7,6,7,6,9,8,9,6,2,6,6,5,6,5,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,6,7,3,6,9,9,6,7,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,9,6,7,6,6,6,7,6,9,9,6,7,6,7,6,9,8,9,[0],66,6,6,7,6,9,9,6,60,6,3,5,3,6,6,3,6,9,9,6,6,6,7,2,9,8,9,9,6,6,6,7,60,6,3,5,3,6,6,3,6,9,9,6,6,6,7,2,9,8,9,9,6,6,6,7,9,9,66,9,9,6,7,9,8,9,6,3,6,3,6,6,3,6,9,39,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,79,9,6,6,6,7,6,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,5,6,5,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,6,7,3,6,9,9,6,7,9,8,9,6,3,6,3,6,6,3,6,9,9,6,7777777777777777776,3,6,6,3,6,9,9,3,6,6,39,9,6,3,6,3,6,6,3,6,9,399,6,3,6,3,6,6,3,3,6,6,3,6,9,9,6,6,6,7,6,97,6,7,9,9,6,6,6,7,6,9,8,9,6,3,3,6,6,3,6,9,9,6,6,5,7,6,9,8,8,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,6,7,3,6,9,9,6,7,9,8,9,6,3,6,3,6,6,3,6,9,9,3,6,6,39,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,97,6,7,9,9,6,6,6,7,6,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,5,6,5,7,6,9,8,8,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,39,8,9,6,3,6,3,6,6,39,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,39,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,97,6,7,9,9,6,6,6,7,6,6,6,3,6,9,9,6,6,6,7,6,97,6,7,9,9,6,6,6,7,6,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,5,6,5,3,6,9,6,9,9,6,6,97,6,7,9,9,6,6,6,7,6,9,8,9,6,3,5,3,6,6,3,6,9,9,6,6,6,7,2,9,8,9,9,6,6,6,7,9,9,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,96,6,7,6,9,8,9,6,3,3,6,6,3,6,9,9,6,6,5,7,6,9,8,8,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,6,7,3,6,9,9,6,7,9,8,9,6,3,6,3,6,6,3,6,9,9,3,6,6,39,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,97,6,7,9,9,6,6,6,7,6,9,8,9,6,[[9],2],6,3,6,9,9,6,6,5,6,5,7,6,9,8,8,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,39,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,6,6,3,6,9,9,6,6,6,7,6,97,6,7,9,9,6,6,6,7,6,9,8,9,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,5,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,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,-1.2e+3,0,0,0,0,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,5,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,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0.0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,1,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,5,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,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0.0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,5,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,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,1,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,5,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,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0.0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,1,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,-1.2e+3,0,0,0,0,0,0,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,9,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,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,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,1,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,5,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,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,5,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,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,-1.2e+3,0,0,0,0,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,5,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,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0.0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,1,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,5,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,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0.0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,5,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,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,1,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,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,1,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,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,00,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,5,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,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0.0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-922330,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,4,1,0,0,0,1,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,1,0,0,7,0,0,0,0,0,0,0,1,0,0,0,0,0.0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,130,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,1,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,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,[0],0,0,0,0,0,0,1,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,1,0,0,0,1,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,1,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,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,1,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,false,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,1,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,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,1,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,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,6,3,6,3,6,6,3,6,6,6,6,7,6,9,8,9,6,3,3,6,6,3,6,9,9,6,6,5,7,6,9,8,8,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,67,6,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,6,7,3,6,9,9,6,7,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,9,6,7,6,6,6,7,6,9,9,6,7,6,7,6,9,8,9,[0],66,6,6,7,6,9,9,6,60,6,3,5,3,6,6,3,6,9,9,6,6,6,7,2,9,8,9,9,6,6,6,7,9,9,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,7,6,9,8,8,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,39,8,9,6,3,6,3,6,6,39,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,39,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,97,6,7,9,9,6,6,6,7,6,6,6,3,6,9,9,6,6,6,7,6,97,6,7,9,9,6,6,6,7,6,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,5,6,5,3,6,9,6,9,9,6,6,97,6,7,9,9,6,6,6,7,6,9,8,9,6,3,5,3,6,6,3,6,9,9,6,6,6,7,2,9,8,9,9,6,6,6,7,9,9,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,96,6,7,6,9,8,9,6,3,3,6,6,3,6,9,9,6,6,5,7,6,9,8,8,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,6,7,3,6,9,9,6,7,9,8,9,6,3,6,3,6,6,3,6,9,9,3,6,6,39,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,97,6,7,9,9,6,6,6,7,6,9,8,9,6,[[9],2],6,3,6,9,9,6,6,5,6,5,7,6,9,8,8,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,39,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,97,6,7,9,9,6,6,6,7,6,6,6,3,6,9,9,6,6,6,7,6,97,6,7,9,9,6,6,6,7,6,9,8,9,6,3,6,3,6,6,3,6,6,6,6,7,6,9,8,9,6,3,3,6,6,3,6,9,9,6,6,5,7,6,9,8,8,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,67,6,7,9,9,6,6,6,7,6,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,5,6,5,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,6,7,3,6,9,9,6,7,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,9,6,7,6,6,6,7,6,9,9,6,7,6,7,6,9,8,9,6,7,9,9,6,6,6,7,6,6,6,3,6,9,9,6,6,6,7,6,97,6,7,9,9,6,6,6,7,6,9,8,9,6,3,6,3,6,6,3,6,6,6,6,7,6,9,8,9,6,3,3,6,6,3,6,9,9,6,6,5,7,6,9,8,8,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,67,6,7,9,9,6,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,6,7,3,6,9,9,6,7,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,9,6,7,6,6,6,7,6,9,9,6,7,6,7,6,9,8,9,6,2,66,6,6,7,6,9,9,6,62716200.713130E0,6371316200.04050037131300,62040e501313040500,355076,9,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,6,7,3,6,9,9,6,7,9,8,97,6,9,8,9,6,3,6,3,6,6,3,6,9,9,6,6,5,6,5,79,8,9,6,3,6,3,6,6,3,6,9,39,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,78,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,9,6,7,6,6,6,7,6,9,9,6,7,6,7,6,9,8,9,6,2,66,6,6,7,6,9,9,6,60,6,3,5,3,6,6,3,6,9,9,6,6,6,7,2,9,9,9,9,6,6,6,7,9,9,6,6,3,6,9,9,6,6,6,7,3,6,9,6,9,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6,9,8,9,6,3,6,9,9,6,6,6,7,3,6,9,9,6,7,9,8,9,6,3,6,3,6,6,3,6,9,9,3,6,6,39,8,9,6,3,6,3,6,6,3,6,9,9,6,6,6,7,6clusterfuzz-testcase-minimized-fuzz_msgpack-5651190114418688000066400000000000000000000036541477700171100332640ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/input3333333=凈킂凈减]#a减减减G减G剉凈⇏G凈凈减340282366920938463463374607431768#211455G=凈凈0减G减臇减凈减减#a减减减G减G剉凈⇏G~减$ #a clusterfuzz-testcase-minimized-fuzz_msgpack_encoder-5091553277706240000066400000000000000000000000171477700171100347440ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/input clusterfuzz-testcase-minimized-fuzz_msgpack_parser_max-6248108141576192000066400000000000000000000000171477700171100354700ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/input jsoncons-1.3.2/test/fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_parse-5763671533027328000066400000000000000000004562431477700171100330360ustar00rootroot00000000000000[ 5, [-5, [-796 , 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 1 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 1 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 1 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 1 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]], 2 ,[ 5, [-796 , 2 ,[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]] , 2 ,[ [5, [-3535,[ [5, [-398 , [5, [-535,[ [5, [-5, [-35,[ [5, [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] , 2 ,[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] [7, [-clusterfuzz-testcase-minimized-fuzz_parse-5981995560730624.fuzz000066400000000000000000000000041477700171100337430ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/input clusterfuzz-testcase-minimized-fuzz_ubjson-5151420333555712000066400000000000000000000037551477700171100331210ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/input[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lECC[CKCCCC[$Z#lEclusterfuzz-testcase-minimized-fuzz_ubjson-5667315455361024000066400000000000000000000000021477700171100331120ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/input{ clusterfuzz-testcase-minimized-fuzz_ubjson-5737197673381888000066400000000000000000000034341477700171100331620ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/input{UFF[[[[[[[[[[[[[[[]]]]]][[[[[[[[[[[U]]]]]]]]][[[[{UFF[[[[[[[[[[[[[[[]]]]]][[[[[[[][]]]]]][[[[[]]]]]]{UFF[[[[[[[[[]]]]{UFF[[[[[[[[[[[[[[[]]]]]][[[[[[[[[[[U]]]]]]]]][[[[{UFF[[[[[[[[[[[[[[[]]]]]][[[[[[[[[[[U]]]]]]]]][[[[[][]]]]]][[[[[[][][U]]]]]]]]][[[[[][]]]]]][[[[[[][]]]]]][[[[[]]][[[[[[U]]]]]]]]][[[[[][]]]]]][[[[[[][]]]]]][[[[[]]]]]]{UFF[[[[[[[[[[[[[[[][]]]]]][[[[[]]][[[[[U]]]][[[[{UFF[[[[[[[[[[[[[[[]]]L]][[[[[[[[[[][[[[[[][]]]]]][[[[[]]]]]]{UFF[[[[[[[[[[[[[[[[]]]]]][[[[[[[[[[[U]]]]]]]]][[[[{UFF[[[[[[[[[[[[[[[]]]]]][[[[[[[[]{UFF[[[[[[[[[[[[[[[]]]]]][[[[[[[[[[[U]]]]]]]]][[[[{UFF[[[[[[[[[[[[[[[]]]]]][[[[[[[[[[[U]]]]]]]]][[[[[][]]]]]][[[[[[][][U]]]]]]]]][[[[[][]]]]]][[[[[[][]]]]]][[[[[]]][[[[[[U]]]]]]]]][[[[[][]]]]]][[[[[[][]]]]]][[[[[]]]]]]{UFF[[[[[[[[[[[[[[[][]]]]]][[[[[]]][[[[[[U]]]][[[[{UFF[[[[[[[[[[[[[[[]]]L]][[[[[[[[[[][[[[[[][]]]]]][[[[[]]]]]]{UFF[[[[[[[[[[[[[[[]]]]]][[[[[[[[[[[U]]]]]]]]][[[[{UFF[[[[[[[[[[[[[[[]]]]]][[[[[[[[[[[U]]]]]]]]][[[[[][]]]]]][[[[[[][][U]]]]]]]]][[[[[][][[[[[[]]]]]][[[[[[[[[[[U]]]]]]]]][[[[{UFF[[[[[[[[[[[[[[[]]]L]][[[[[[[[[[][[[[[[][]]]]]][[[[[]]]]][[[[[U]]]]]]]]][[[[{UFF[[[[[[[[[[[[[[[]]]L]][[[[[[[[[[][[[[[[][]]]]]][[[[[]]]]]]{UFF[[[[[[[[[[[[[[[]]]]]][[[[[[[[[[[U]]]]]]]]][[[[{UFF[[[[[[[[[[[[[[[]]]]]][[[[[[[[[[[U]]]]]]]]][[[[[][]]]]]][[[[[[][][U]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]UUUUUUUUUUUUUUUUUUUUUUUU]]]UUUUUU]]U][[Uclusterfuzz-testcase-minimized-fuzz_ubjson-5738905124208640000066400000000000000000000001361477700171100331230ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/input[III[$F#L*[$F#i[[$F#It[III[$F#I*[$F#i[[$F#It[II[III[$F#I*[$F#i[[$F#I[$F#i[[$F#It[I[``clusterfuzz-testcase-minimized-fuzz_ubjson-5751108612653056000066400000000000000000000000011477700171100331070ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/inputNclusterfuzz-testcase-minimized-fuzz_ubjson_encoder-5711604342849536000066400000000000000000000012041477700171100346230ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/input[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#lZ#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#lZ#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[[[[[$Z#l[clusterfuzz-testcase-minimized-fuzz_ubjson_encoder-6542820946542592000066400000000000000000001257001477700171100346400ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/input[ZiZ[[UUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/UUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUFFFFFFFFFFFFFFFFFFF[[$F#l[$F#lFFUUUHUUUUUUUUUUUUUUUUUUU{UUU{U{U[{#U{U[FFFUUUUUUUUUUUUUUUUUUUUUUFFFFFUUUUUUUUUUUUUUUUUUUU51UUUUUUU516 U4UUU/jsoncons-1.3.2/test/fuzz_regression/src/000077500000000000000000000000001477700171100203625ustar00rootroot00000000000000jsoncons-1.3.2/test/fuzz_regression/src/fuzz_regression_tests.cpp000066400000000000000000000643701477700171100255600ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("oss-fuzz issues") { #if 0 // Fuzz target: fuzz_parse // Issue: Stack-overflow // Diagnosis: During basic_json destruction, an internal compiler stack error occurred in std::vector // destructor after reaching a certain nesting depth, // approximately 270 with visual studio on windows. // Resolution: // - Implement destructors for json_array and json_object that flatten std::vector elements // - max_nesting_depth option for all parsers and encoders (default 1024) SECTION("issue 21589") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_parse-5763671533027328"; auto options = json_options{} .max_nesting_depth(std::numeric_limits::max()); std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); REQUIRE_THROWS_WITH(json::parse(is, options), Catch::Matchers::Contains(json_error_category_impl().message((int)json_errc::expected_comma_or_rbracket).c_str())); } // Fuzz target: fuzz_cbo // Issue: Abrt in __cxxabiv1::failed_throw // Diagnosis: Huge length field in binary data formats // Resolution: Read from source in chunks, to avoid bad_alloc, and fail with unexpected_eof SECTION("issue 21619") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_cbor-5171679883165696"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 auto options = cbor::cbor_options{} .max_nesting_depth(std::numeric_limits::max()); default_json_visitor visitor; cbor::cbor_stream_reader reader(is,visitor,options); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); CHECK((ec.value() == (int)cbor::cbor_errc::unexpected_eof || // x64 arch //-V521 ec.value() == (int)cbor::cbor_errc::number_too_large)); // x86 arch } // Fuzz target: fuzz_cbor // Issue: Timeout in fuzz_cbor SECTION("issue 21631") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_cbor-5639265590706176"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 default_json_visitor visitor; auto options = cbor::cbor_options{} .max_nesting_depth(std::numeric_limits::max()); cbor::cbor_stream_reader reader(is,visitor,options); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); CHECK((ec == cbor::cbor_errc::unknown_type || // x64 arch //-V521 ec == cbor::cbor_errc::number_too_large)); // x86 arch } // Fuzz target: fuzz_csv // Issue: Integer-overflow SECTION("issue 21663") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_csv-5762751990595584"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 json_decoder visitor; auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_rows); csv::csv_stream_reader reader(is,visitor,options); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); CHECK_FALSE(ec); //-V521 //std::cout << visitor.get_result() << "" << '\n'; } SECTION("issue 21663b") { std::string s = "-6.6E6"; int64_t n{ 0 }; auto result = jsoncons::detail::to_integer(s.data(),s.size(), n); CHECK_FALSE(result); //-V521 } // Fuzz target: fuzz_ubjson // Issue: Out-of-memory // Diagnosis: Issue with huge length for a strongly typed array of no-op, null, false, or true, // e.g. [[][$][T][#][I][9223372036854775807] // Resolution: limit number of items to max_items set in options SECTION("issue 21667") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_ubjson-5738905124208640"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 default_json_visitor visitor; ubjson::ubjson_stream_reader reader(is,visitor); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); CHECK((ec == ubjson::ubjson_errc::max_items_exceeded || // x64 arch //-V521 ec == ubjson::ubjson_errc::number_too_large)); // x86 arch } // Fuzz target: fuzz_ubjson // Issue: Timeout SECTION("issue 21697") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_ubjson-5737197673381888"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 json_decoder visitor; ubjson::ubjson_stream_reader reader(is,visitor); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); CHECK(ec == ubjson::ubjson_errc::key_expected); //-V521 } // Fuzz target: fuzz_cbor // Issue: Stack overflow SECTION("issue 21709") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_cbor-5740910806827008.fuzz"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); auto options = cbor::cbor_options{} .max_nesting_depth(10000); REQUIRE_THROWS_WITH(cbor::decode_cbor(is,options), Catch::Matchers::Contains(cbor::cbor_error_category_impl().message((int)cbor::cbor_errc::max_nesting_depth_exceeded).c_str())); } // Fuzz target: fuzz_cbor // Issue: Stack overflow SECTION("issue 21710") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-fuzz_cbor-5141282369568768"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 auto options = cbor::cbor_options{} .max_nesting_depth(10000); REQUIRE_THROWS_WITH(cbor::decode_cbor(is,options), Catch::Matchers::Contains(cbor::cbor_error_category_impl().message((int)cbor::cbor_errc::max_nesting_depth_exceeded).c_str())); } SECTION("issue 21710b") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-fuzz_cbor-5141282369568768"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 auto options = cbor::cbor_options{} .max_nesting_depth(std::numeric_limits::max()); default_json_visitor visitor; cbor::cbor_stream_reader reader(is,visitor,options); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); CHECK(ec.value() == (int)cbor::cbor_errc::unknown_type); //-V521 } // Fuzz target: fuzz_msgpack // Issue: Out of memory SECTION("issue 21801") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_msgpack-5651190114418688"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 json_decoder visitor; auto options = msgpack::msgpack_options{}; msgpack::msgpack_stream_reader reader(is,visitor); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); CHECK(ec == msgpack::msgpack_errc::unexpected_eof); //-V521 } // Fuzz target: fuzz_cbor // Issue: Stack overflow SECTION("issue 21805") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-fuzz_cbor-5687592176844800"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 default_json_visitor visitor; auto options = cbor::cbor_options{} cbor::cbor_stream_reader reader(is,visitor,options); std::error_code ec; //reader.read(ec); //std::cout << ec.message() << "" << '\n'; REQUIRE_NOTHROW(reader.read(ec)); CHECK((ec == cbor::cbor_errc::max_nesting_depth_exceeded)); //-V521 } // Fuzz target: fuzz_msgpack // Issue: Timeout SECTION("issue 21813") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-fuzz_msgpack-5727715157344256"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 default_json_visitor visitor; auto options = msgpack::msgpack_options{} .max_nesting_depth(std::numeric_limits::max()); msgpack::msgpack_stream_reader reader(is,visitor,options); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); CHECK(ec == msgpack::msgpack_errc::unexpected_eof); //-V521 } // Fuzz target: fuzz_ubjson // Issue: Timeout SECTION("issue 21865") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-fuzz_bson-5637264110780416"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 default_json_visitor visitor; auto options = bson::bson_options{} .max_nesting_depth(std::numeric_limits::max()); bson::bson_stream_reader reader(is,visitor,options); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); CHECK(ec == bson::bson_errc::unexpected_eof); } // Fuzz target: fuzz_csv_encoder // Issue: Failed throw // Resolution: check if csv_parser is still in start state when no more input SECTION("issue 21912") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_csv_encoder-5202115606872064.fuzz"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 std::string s2; csv::csv_string_encoder visitor(s2); csv::csv_stream_reader reader(is, visitor); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); CHECK((ec == csv::csv_errc::source_error)); //-V521 //std::cout << visitor.get_result() << "" << '\n'; } // Fuzz target: fuzz_cbor // Issue: failed_throw SECTION("issue 21948") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_cbor-5743359164678144"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 json_decoder visitor; auto options = cbor::cbor_options{}; cbor::cbor_stream_reader reader(is,visitor,options); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); CHECK((ec == cbor::cbor_errc::unknown_type)); //-V521 } // Fuzz target: fuzz_csv_encoder // Issue: Failed throw // Resolution: Fixed check for floating point values SECTION("issue 21990") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_csv_encoder-5682837304115200.fuzz"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 std::string s2; csv::csv_string_encoder visitor(s2); csv::csv_stream_reader reader(is, visitor); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); } // Fuzz target: fuzz_cbor_encoder // Issue: failed_throw // Resolution: Replaced assert that array containing decimal fraction // has size 2 with error code invalid_decimal_fraction SECTION("issue 22000") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-fuzz_cbor_encoder-5685492533428224"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 std::vector buf; cbor::cbor_bytes_encoder encoder(buf); cbor::cbor_stream_reader reader(is, encoder); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); CHECK(ec == cbor::cbor_errc::invalid_decimal_fraction); //-V521 } // Fuzz target: fuzz_cbor_encoder // Issue: failed_throw // Resolution: prettify_string with decimal fractions failed with exponents >= 1000 SECTION("issue 22018") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-fuzz_cbor_encoder-5673305546948608"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 std::vector buf; cbor::cbor_bytes_encoder encoder(buf); cbor::cbor_stream_reader reader(is, encoder); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); CHECK((ec == cbor::cbor_errc::illegal_chunked_string || ec == cbor::cbor_errc::invalid_decimal_fraction)); //-V521 } // Fuzz target: fuzz_cbor_encoder // Issue: Stack-overflow // Resolution: SECTION("issue 22023") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-fuzz_cbor_encoder-5681910597812224"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 std::vector buf; cbor::cbor_bytes_encoder encoder(buf); cbor::cbor_stream_reader reader(is, encoder); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); CHECK(ec == cbor::cbor_errc::unexpected_eof); //-V521 } // Fuzz target: fuzz_msgpack_encoder // Issue: Timeout SECTION("issue 22024") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-fuzz_msgpack_encoder-5677646685143040"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 std::vector buf; msgpack::msgpack_bytes_encoder visitor(buf); msgpack::msgpack_stream_reader reader(is,visitor); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); CHECK((ec == msgpack::msgpack_errc::unexpected_eof || //-V521 ec == msgpack::msgpack_errc::unknown_type)); } // Fuzz target: fuzz_cbor_encoder // Issue: TIMEOUT // Resolution: /* SECTION("issue 22379") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_cbor_encoder-6266427819687936"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); std::vector buf; cbor::cbor_bytes_encoder encoder(buf); cbor::cbor_stream_reader reader(is, encoder); std::error_code ec; try { reader.read(ec); } catch (const std::exception& e) { std::cout << e.what() << "\n"; } //REQUIRE_NOTHROW(reader.read(ec)); //CHECK(ec == cbor::cbor_errc::unexpected_eof); } */ // Fuzz target: fuzz_ubjson // Issue: Direct-leak in std::__1::__libcpp_allocate SECTION("issue 24216") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_ubjson-5667315455361024"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 try { json j2 = ubjson::decode_ubjson(is); } catch(const jsoncons::ser_error&) { //std::cout << e.what() << "\n\n"; } } // Fuzz target: fuzz_msgpack_parser_max // Issue: Integer-overflow SECTION("issue 24574") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_msgpack_parser_max-6248108141576192"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 default_json_visitor visitor; auto options = msgpack::msgpack_options{} .max_nesting_depth(std::numeric_limits::max()); msgpack::msgpack_stream_reader reader(is, visitor, options); std::error_code ec; reader.read(ec); } // Fuzz target: fuzz_ubjson // Issue: failed_throw SECTION("issue 25891") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_ubjson-5751108612653056"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 try { json j2 = ubjson::decode_ubjson(is); } catch(const jsoncons::ser_error&) {} } // Fuzz target: fuzz_json_encoder // Issue: Out-of-memory SECTION("issue 27342") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_json_encoder-5769370349076480"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 std::string s2; json_string_encoder visitor(s2); json_stream_reader reader(is, visitor); try { std::error_code ec; reader.read(ec); } catch (const std::exception& e) { std::cout << e.what() << '\n'; } } // Fuzz target: fuzz_json_encoder // Issue: Container-overflow READ 1 SECTION("issue 33781") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_json_encoder-5639543840702464"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 std::string s2; json_string_encoder visitor(s2); json_stream_reader reader(is, visitor); std::error_code ec; reader.read(ec); } // Fuzz target: jsoncons:fuzz_json_cursor // Issue: failed_throw SECTION("issue 22091") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_json_cursor-5686693027119104"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 std::error_code ec; json_stream_cursor reader(is, ec); while (!reader.done() && !ec) { const auto& event = reader.current(); std::string s2 = event.get(ec); if (!ec) { reader.next(ec); } } CHECK(ec == conv_errc::not_string); //-V521 } // Fuzz target: jsoncons:fuzz_bson_encoder // Issue: Index-out-of-bounds in jsoncons::bson::decimal128_from_chars SECTION("issue 34814") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_bson_encoder-5420549982519296"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 std::vector s1; bson::bson_bytes_encoder encoder(s1); bson::bson_stream_reader reader(is, encoder); std::error_code ec; reader.read(ec); //CHECK(ec == bson::bson_errc::unexpected_eof); //std::cout << ec.message() << "\n"; } // Fuzz target: fuzz_ubjson // Issue: Timeout in fuzz_ubjson // Diagnosis: // Resolution: SECTION("issue 31888") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_ubjson-5151420333555712"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 //json_decoder visitor; default_json_visitor visitor; ubjson::ubjson_stream_reader reader(is,visitor); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); std::cout << ec.message() << "\n"; } // Fuzz target: fuzz_parse // Issue: Abrt in __cxxabiv1::failed_throw // Diagnosis: // Resolution: SECTION("issue 35879") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_parse-5981995560730624.fuzz"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 try { json::parse(is); } catch(const jsoncons::ser_error&) {} } // Fuzz target: jsoncons:fuzz_json_cursor // Issue: Timeout (exceeds 60 secs) SECTION("issue 36013") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_json_cursor-6585089218707456"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 std::error_code ec; json_stream_cursor reader(is, ec); while (!reader.done() && !ec) { const auto& event = reader.current(); std::string s2 = event.get(ec); if (!ec) { reader.next(ec); } } //CHECK(ec == json_errc::unexpected_eof); } // Fuzz target: jsoncons:fuzz_json_cursor // Issue: Timeout (exceeds 60 secs) SECTION("issue 36926") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_json_cursor-5656793396150272"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 std::error_code ec; json_stream_cursor reader(is, ec); while (!reader.done() && !ec) { const auto& event = reader.current(); std::string s2 = event.get(ec); if (!ec) { reader.next(ec); } } } // Fuzz target: fuzz_csv_encoder // Issue: Failed throw // Resolution: SECTION("issue 391917540") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_csv_encoder-4850580052312064"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 std::string s2; csv::csv_string_encoder visitor(s2); csv::csv_stream_reader reader(is, visitor); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); std::cout << ec.message() << "\n"; //CHECK((ec == csv::csv_errc::source_error)); //-V521 //std::cout << visitor.get_result() << "" << '\n'; } } TEST_CASE("Fuzz target: fuzz_ubjson_encoder") { // Issue: Timeout /*SECTION("issue 23840") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_ubjson_encoder-5711604342849536"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 std::vector output; ubjson::ubjson_bytes_encoder encoder(output); ubjson::ubjson_stream_reader reader(is, encoder); std::error_code ec; reader.read(ec); CHECK(ec == ubjson::ubjson_errc::unknown_type); //-V521 }*/ // Issue: Timeout (exceeds 60 secs) /*SECTION("issue 378891965") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_ubjson_encoder-6542820946542592"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 std::vector output; ubjson::ubjson_bytes_encoder encoder(output); ubjson::ubjson_stream_reader reader(is, encoder); std::error_code ec; reader.read(ec); CHECK(ec == ubjson::ubjson_errc::unknown_type); //-V521 }*/ } TEST_CASE("Fuzz target: fuzz_cbor_encoder") { // Fuzz target: fuzz_cbor_encoder // Issue: failed_throw // Resolution: change assert to illegal_chunked_string error code /* SECTION("issue 21902") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-fuzz_cbor_encoder-5665976638242816"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 try { std::vector buf; cbor::cbor_bytes_encoder encoder(buf); cbor::cbor_stream_reader reader(is, encoder); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); CHECK(ec == cbor::cbor_errc::illegal_chunked_string); //-V521 } catch (const std::exception& e) { std::cout << e.what() << "" << '\n'; } } */ // Fuzz target: fuzz_cbor_encoder // Issue: Integer-overflow SECTION("issue 42538003") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_cbor_encoder-4729089884225536"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 try { std::vector buf; cbor::cbor_bytes_encoder encoder(buf); cbor::cbor_stream_reader reader(is, encoder); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); CHECK_FALSE(ec); //-V521 } catch (const std::exception& e) { std::cout << e.what() << "" << '\n'; } } // Fuzz target: fuzz_csv // Issue: abort SECTION("Issue 406331596") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_csv-4925110364733440"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 json_decoder visitor; auto options = csv::csv_options{} .assume_header(true) .mapping_kind(csv::csv_mapping_kind::n_rows); csv::csv_stream_reader reader(is,visitor,options); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); CHECK_FALSE(ec); //std::cout << visitor.get_result() << "" << '\n'; } #endif // Fuzz target: fuzz_msgpack_encoder // Issue: Integer-overflow SECTION("Issue 388873483") { std::string pathname = "fuzz_regression/input/clusterfuzz-testcase-minimized-fuzz_msgpack_encoder-5091553277706240"; std::ifstream is(pathname, std::ios_base::in | std::ios_base::binary); CHECK(is); //-V521 std::vector buf; msgpack::msgpack_bytes_encoder visitor(buf); msgpack::msgpack_stream_reader reader(is,visitor); std::error_code ec; REQUIRE_NOTHROW(reader.read(ec)); } } jsoncons-1.3.2/test/jmespath/000077500000000000000000000000001477700171100161505ustar00rootroot00000000000000jsoncons-1.3.2/test/jmespath/input/000077500000000000000000000000001477700171100173075ustar00rootroot00000000000000jsoncons-1.3.2/test/jmespath/input/compliance/000077500000000000000000000000001477700171100214215ustar00rootroot00000000000000jsoncons-1.3.2/test/jmespath/input/compliance/basic.json000066400000000000000000000037671477700171100234120ustar00rootroot00000000000000[{ "given": {"foo": {"bar": {"baz": "correct"}}}, "cases": [ { "expression": "foo", "result": {"bar": {"baz": "correct"}} }, { "expression": "foo.bar", "result": {"baz": "correct"} }, { "expression": "foo.bar.baz", "result": "correct" }, { "expression": "foo\n.\nbar\n.baz", "result": "correct" }, { "expression": "foo.bar.baz.bad", "result": null }, { "expression": "foo.bar.bad", "result": null }, { "expression": "foo.bad", "result": null }, { "expression": "bad", "result": null }, { "expression": "bad.morebad.morebad", "result": null } ] }, { "given": {"foo": {"bar": ["one", "two", "three"]}}, "cases": [ { "expression": "foo", "result": {"bar": ["one", "two", "three"]} }, { "expression": "foo.bar", "result": ["one", "two", "three"] } ] }, { "given": ["one", "two", "three"], "cases": [ { "expression": "one", "result": null }, { "expression": "two", "result": null }, { "expression": "three", "result": null }, { "expression": "one.two", "result": null } ] }, { "given": {"foo": {"1": ["one", "two", "three"], "-1": "bar"}}, "cases": [ { "expression": "foo.\"1\"", "result": ["one", "two", "three"] }, { "expression": "foo.\"1\"[0]", "result": "one" }, { "expression": "foo.\"-1\"", "result": "bar" } ] } ] jsoncons-1.3.2/test/jmespath/input/compliance/benchmarks.json000066400000000000000000000115741477700171100244410ustar00rootroot00000000000000[ { "given": { "long_name_for_a_field": true, "a": { "b": { "c": { "d": { "e": { "f": { "g": { "h": { "i": { "j": { "k": { "l": { "m": { "n": { "o": { "p": true } } } } } } } } } } } } } } }, "b": true, "c": { "d": true } }, "cases": [ { "comment": "simple field", "expression": "b", "bench": "full" }, { "comment": "simple subexpression", "expression": "c.d", "bench": "full" }, { "comment": "deep field selection no match", "expression": "a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s", "bench": "full" }, { "comment": "deep field selection", "expression": "a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p", "bench": "full" }, { "comment": "simple or", "expression": "not_there || b", "bench": "full" } ] }, { "given": { "a":0,"b":1,"c":2,"d":3,"e":4,"f":5,"g":6,"h":7,"i":8,"j":9,"k":10, "l":11,"m":12,"n":13,"o":14,"p":15,"q":16,"r":17,"s":18,"t":19,"u":20, "v":21,"w":22,"x":23,"y":24,"z":25 }, "cases": [ { "comment": "deep ands", "expression": "a && b && c && d && e && f && g && h && i && j && k && l && m && n && o && p && q && r && s && t && u && v && w && x && y && z", "bench": "full" }, { "comment": "deep ors", "expression": "z || y || x || w || v || u || t || s || r || q || p || o || n || m || l || k || j || i || h || g || f || e || d || c || b || a", "bench": "full" }, { "comment": "lots of summing", "expression": "sum([z, y, x, w, v, u, t, s, r, q, p, o, n, m, l, k, j, i, h, g, f, e, d, c, b, a])", "bench": "full" }, { "comment": "lots of function application", "expression": "sum([z, sum([y, sum([x, sum([w, sum([v, sum([u, sum([t, sum([s, sum([r, sum([q, sum([p, sum([o, sum([n, sum([m, sum([l, sum([k, sum([j, sum([i, sum([h, sum([g, sum([f, sum([e, sum([d, sum([c, sum([b, a])])])])])])])])])])])])])])])])])])])])])])])])])", "bench": "full" }, { "comment": "lots of multi list", "expression": "[z, y, x, w, v, u, t, s, r, q, p, o, n, m, l, k, j, i, h, g, f, e, d, c, b, a]", "bench": "full" } ] }, { "given": {}, "cases": [ { "comment": "field 50", "expression": "j49.j48.j47.j46.j45.j44.j43.j42.j41.j40.j39.j38.j37.j36.j35.j34.j33.j32.j31.j30.j29.j28.j27.j26.j25.j24.j23.j22.j21.j20.j19.j18.j17.j16.j15.j14.j13.j12.j11.j10.j9.j8.j7.j6.j5.j4.j3.j2.j1.j0", "bench": "parse" }, { "comment": "pipe 50", "expression": "j49|j48|j47|j46|j45|j44|j43|j42|j41|j40|j39|j38|j37|j36|j35|j34|j33|j32|j31|j30|j29|j28|j27|j26|j25|j24|j23|j22|j21|j20|j19|j18|j17|j16|j15|j14|j13|j12|j11|j10|j9|j8|j7|j6|j5|j4|j3|j2|j1|j0", "bench": "parse" }, { "comment": "index 50", "expression": "[49][48][47][46][45][44][43][42][41][40][39][38][37][36][35][34][33][32][31][30][29][28][27][26][25][24][23][22][21][20][19][18][17][16][15][14][13][12][11][10][9][8][7][6][5][4][3][2][1][0]", "bench": "parse" }, { "comment": "long raw string literal", "expression": "'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz'", "bench": "parse" }, { "comment": "deep projection 104", "expression": "a[*].b[*].c[*].d[*].e[*].f[*].g[*].h[*].i[*].j[*].k[*].l[*].m[*].n[*].o[*].p[*].q[*].r[*].s[*].t[*].u[*].v[*].w[*].x[*].y[*].z[*].a[*].b[*].c[*].d[*].e[*].f[*].g[*].h[*].i[*].j[*].k[*].l[*].m[*].n[*].o[*].p[*].q[*].r[*].s[*].t[*].u[*].v[*].w[*].x[*].y[*].z[*].a[*].b[*].c[*].d[*].e[*].f[*].g[*].h[*].i[*].j[*].k[*].l[*].m[*].n[*].o[*].p[*].q[*].r[*].s[*].t[*].u[*].v[*].w[*].x[*].y[*].z[*].a[*].b[*].c[*].d[*].e[*].f[*].g[*].h[*].i[*].j[*].k[*].l[*].m[*].n[*].o[*].p[*].q[*].r[*].s[*].t[*].u[*].v[*].w[*].x[*].y[*].z[*]", "bench": "parse" }, { "comment": "filter projection", "expression": "foo[?bar > baz][?qux > baz]", "bench": "parse" } ] } ] jsoncons-1.3.2/test/jmespath/input/compliance/boolean.json000066400000000000000000000123771477700171100237450ustar00rootroot00000000000000[ { "given": { "outer": { "foo": "foo", "bar": "bar", "baz": "baz" } }, "cases": [ { "expression": "outer.foo || outer.bar", "result": "foo" }, { "expression": "outer.foo||outer.bar", "result": "foo" }, { "expression": "outer.bar || outer.baz", "result": "bar" }, { "expression": "outer.bar||outer.baz", "result": "bar" }, { "expression": "outer.bad || outer.foo", "result": "foo" }, { "expression": "outer.bad||outer.foo", "result": "foo" }, { "expression": "outer.foo || outer.bad", "result": "foo" }, { "expression": "outer.foo||outer.bad", "result": "foo" }, { "expression": "outer.bad || outer.alsobad", "result": null }, { "expression": "outer.bad||outer.alsobad", "result": null } ] }, { "given": { "outer": { "foo": "foo", "bool": false, "empty_list": [], "empty_string": "" } }, "cases": [ { "expression": "outer.empty_string || outer.foo", "result": "foo" }, { "expression": "outer.nokey || outer.bool || outer.empty_list || outer.empty_string || outer.foo", "result": "foo" } ] }, { "given": { "True": true, "False": false, "Number": 5, "EmptyList": [], "Zero": 0 }, "cases": [ { "expression": "True && False", "result": false }, { "expression": "False && True", "result": false }, { "expression": "True && True", "result": true }, { "expression": "False && False", "result": false }, { "expression": "True && Number", "result": 5 }, { "expression": "Number && True", "result": true }, { "expression": "Number && False", "result": false }, { "expression": "Number && EmptyList", "result": [] }, { "expression": "Number && True", "result": true }, { "expression": "EmptyList && True", "result": [] }, { "expression": "EmptyList && False", "result": [] }, { "expression": "True || False", "result": true }, { "expression": "True || True", "result": true }, { "expression": "False || True", "result": true }, { "expression": "False || False", "result": false }, { "expression": "Number || EmptyList", "result": 5 }, { "expression": "Number || True", "result": 5 }, { "expression": "Number || True && False", "result": 5 }, { "expression": "(Number || True) && False", "result": false }, { "expression": "Number || (True && False)", "result": 5 }, { "expression": "!True", "result": false }, { "expression": "!False", "result": true }, { "expression": "!Number", "result": false }, { "expression": "!EmptyList", "result": true }, { "expression": "True && !False", "result": true }, { "expression": "True && !EmptyList", "result": true }, { "expression": "!False && !EmptyList", "result": true }, { "expression": "!(True && False)", "result": true }, { "expression": "!Zero", "result": false }, { "expression": "!!Zero", "result": true } ] }, { "given": { "one": 1, "two": 2, "three": 3, "emptylist": [], "boolvalue": false }, "cases": [ { "expression": "one < two", "result": true }, { "expression": "one <= two", "result": true }, { "expression": "one == one", "result": true }, { "expression": "one == two", "result": false }, { "expression": "one > two", "result": false }, { "expression": "one >= two", "result": false }, { "expression": "one != two", "result": true }, { "expression": "emptylist < one", "result": null }, { "expression": "emptylist < nullvalue", "result": null }, { "expression": "emptylist < boolvalue", "result": null }, { "expression": "one < boolvalue", "result": null }, { "expression": "one < two && three > one", "result": true }, { "expression": "one < two || three > one", "result": true }, { "expression": "one < two || three < one", "result": true }, { "expression": "two < one || three < one", "result": false } ] } ] jsoncons-1.3.2/test/jmespath/input/compliance/current.json000066400000000000000000000011161477700171100237750ustar00rootroot00000000000000[ { "given": { "foo": [{"name": "a"}, {"name": "b"}], "bar": {"baz": "qux"} }, "cases": [ { "expression": "@", "result": { "foo": [{"name": "a"}, {"name": "b"}], "bar": {"baz": "qux"} } }, { "expression": "@.bar", "result": {"baz": "qux"} }, { "expression": "@.foo[0]", "result": {"name": "a"} } ] } ] jsoncons-1.3.2/test/jmespath/input/compliance/escape.json000066400000000000000000000021201477700171100235470ustar00rootroot00000000000000[{ "given": { "foo.bar": "dot", "foo bar": "space", "foo\nbar": "newline", "foo\"bar": "doublequote", "c:\\\\windows\\path": "windows", "/unix/path": "unix", "\"\"\"": "threequotes", "bar": {"baz": "qux"} }, "cases": [ { "expression": "\"foo.bar\"", "result": "dot" }, { "expression": "\"foo bar\"", "result": "space" }, { "expression": "\"foo\\nbar\"", "result": "newline" }, { "expression": "\"foo\\\"bar\"", "result": "doublequote" }, { "expression": "\"c:\\\\\\\\windows\\\\path\"", "result": "windows" }, { "expression": "\"/unix/path\"", "result": "unix" }, { "expression": "\"\\\"\\\"\\\"\"", "result": "threequotes" }, { "expression": "\"bar\".\"baz\"", "result": "qux" } ] }] jsoncons-1.3.2/test/jmespath/input/compliance/filters.json000066400000000000000000000313221477700171100237650ustar00rootroot00000000000000[ { "given": {"foo": [{"name": "a"}, {"name": "b"}]}, "cases": [ { "comment": "Matching a literal", "expression": "foo[?name == 'a']", "result": [{"name": "a"}] } ] }, { "given": {"foo": [0, 1], "bar": [2, 3]}, "cases": [ { "comment": "Matching a literal", "expression": "*[?[0] == `0`]", "result": [[], []] } ] }, { "given": {"foo": [{"first": "foo", "last": "bar"}, {"first": "foo", "last": "foo"}, {"first": "foo", "last": "baz"}]}, "cases": [ { "comment": "Matching an expression", "expression": "foo[?first == last]", "result": [{"first": "foo", "last": "foo"}] }, { "comment": "Verify projection created from filter", "expression": "foo[?first == last].first", "result": ["foo"] } ] }, { "given": {"foo": [{"age": 20}, {"age": 25}, {"age": 30}]}, "cases": [ { "comment": "Greater than with a number", "expression": "foo[?age > `25`]", "result": [{"age": 30}] }, { "expression": "foo[?age >= `25`]", "result": [{"age": 25}, {"age": 30}] }, { "comment": "Greater than with a number", "expression": "foo[?age > `30`]", "result": [] }, { "comment": "Greater than with a number", "expression": "foo[?age < `25`]", "result": [{"age": 20}] }, { "comment": "Greater than with a number", "expression": "foo[?age <= `25`]", "result": [{"age": 20}, {"age": 25}] }, { "comment": "Greater than with a number", "expression": "foo[?age < `20`]", "result": [] }, { "expression": "foo[?age == `20`]", "result": [{"age": 20}] }, { "expression": "foo[?age != `20`]", "result": [{"age": 25}, {"age": 30}] } ] }, { "given": {"foo": [{"top": {"name": "a"}}, {"top": {"name": "b"}}]}, "cases": [ { "comment": "Filter with subexpression", "expression": "foo[?top.name == 'a']", "result": [{"top": {"name": "a"}}] } ] }, { "given": {"foo": [{"top": {"first": "foo", "last": "bar"}}, {"top": {"first": "foo", "last": "foo"}}, {"top": {"first": "foo", "last": "baz"}}]}, "cases": [ { "comment": "Matching an expression", "expression": "foo[?top.first == top.last]", "result": [{"top": {"first": "foo", "last": "foo"}}] }, { "comment": "Matching a JSON array", "expression": "foo[?top == `{\"first\": \"foo\", \"last\": \"bar\"}`]", "result": [{"top": {"first": "foo", "last": "bar"}}] } ] }, { "given": {"foo": [ {"key": true}, {"key": false}, {"key": 0}, {"key": 1}, {"key": [0]}, {"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}} ]}, "cases": [ { "expression": "foo[?key == `true`]", "result": [{"key": true}] }, { "expression": "foo[?key == `false`]", "result": [{"key": false}] }, { "expression": "foo[?key == `0`]", "result": [{"key": 0}] }, { "expression": "foo[?key == `1`]", "result": [{"key": 1}] }, { "expression": "foo[?key == `[0]`]", "result": [{"key": [0]}] }, { "expression": "foo[?key == `{\"bar\": [0]}`]", "result": [{"key": {"bar": [0]}}] }, { "expression": "foo[?key == `null`]", "result": [{"key": null}] }, { "expression": "foo[?key == `[1]`]", "result": [{"key": [1]}] }, { "expression": "foo[?key == `{\"a\":2}`]", "result": [{"key": {"a":2}}] }, { "expression": "foo[?`true` == key]", "result": [{"key": true}] }, { "expression": "foo[?`false` == key]", "result": [{"key": false}] }, { "expression": "foo[?`0` == key]", "result": [{"key": 0}] }, { "expression": "foo[?`1` == key]", "result": [{"key": 1}] }, { "expression": "foo[?`[0]` == key]", "result": [{"key": [0]}] }, { "expression": "foo[?`{\"bar\": [0]}` == key]", "result": [{"key": {"bar": [0]}}] }, { "expression": "foo[?`null` == key]", "result": [{"key": null}] }, { "expression": "foo[?`[1]` == key]", "result": [{"key": [1]}] }, { "expression": "foo[?`{\"a\":2}` == key]", "result": [{"key": {"a":2}}] }, { "expression": "foo[?key != `true`]", "result": [{"key": false}, {"key": 0}, {"key": 1}, {"key": [0]}, {"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}] }, { "expression": "foo[?key != `false`]", "result": [{"key": true}, {"key": 0}, {"key": 1}, {"key": [0]}, {"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}] }, { "expression": "foo[?key != `0`]", "result": [{"key": true}, {"key": false}, {"key": 1}, {"key": [0]}, {"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}] }, { "expression": "foo[?key != `1`]", "result": [{"key": true}, {"key": false}, {"key": 0}, {"key": [0]}, {"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}] }, { "expression": "foo[?key != `null`]", "result": [{"key": true}, {"key": false}, {"key": 0}, {"key": 1}, {"key": [0]}, {"key": {"bar": [0]}}, {"key": [1]}, {"key": {"a":2}}] }, { "expression": "foo[?key != `[1]`]", "result": [{"key": true}, {"key": false}, {"key": 0}, {"key": 1}, {"key": [0]}, {"key": {"bar": [0]}}, {"key": null}, {"key": {"a":2}}] }, { "expression": "foo[?key != `{\"a\":2}`]", "result": [{"key": true}, {"key": false}, {"key": 0}, {"key": 1}, {"key": [0]}, {"key": {"bar": [0]}}, {"key": null}, {"key": [1]}] }, { "expression": "foo[?`true` != key]", "result": [{"key": false}, {"key": 0}, {"key": 1}, {"key": [0]}, {"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}] }, { "expression": "foo[?`false` != key]", "result": [{"key": true}, {"key": 0}, {"key": 1}, {"key": [0]}, {"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}] }, { "expression": "foo[?`0` != key]", "result": [{"key": true}, {"key": false}, {"key": 1}, {"key": [0]}, {"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}] }, { "expression": "foo[?`1` != key]", "result": [{"key": true}, {"key": false}, {"key": 0}, {"key": [0]}, {"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}] }, { "expression": "foo[?`null` != key]", "result": [{"key": true}, {"key": false}, {"key": 0}, {"key": 1}, {"key": [0]}, {"key": {"bar": [0]}}, {"key": [1]}, {"key": {"a":2}}] }, { "expression": "foo[?`[1]` != key]", "result": [{"key": true}, {"key": false}, {"key": 0}, {"key": 1}, {"key": [0]}, {"key": {"bar": [0]}}, {"key": null}, {"key": {"a":2}}] }, { "expression": "foo[?`{\"a\":2}` != key]", "result": [{"key": true}, {"key": false}, {"key": 0}, {"key": 1}, {"key": [0]}, {"key": {"bar": [0]}}, {"key": null}, {"key": [1]}] } ] }, { "given": {"reservations": [ {"instances": [ {"foo": 1, "bar": 2}, {"foo": 1, "bar": 3}, {"foo": 1, "bar": 2}, {"foo": 2, "bar": 1}]}]}, "cases": [ { "expression": "reservations[].instances[?bar==`1`]", "result": [[{"foo": 2, "bar": 1}]] }, { "expression": "reservations[*].instances[?bar==`1`]", "result": [[{"foo": 2, "bar": 1}]] }, { "expression": "reservations[].instances[?bar==`1`][]", "result": [{"foo": 2, "bar": 1}] } ] }, { "given": { "baz": "other", "foo": [ {"bar": 1}, {"bar": 2}, {"bar": 3}, {"bar": 4}, {"bar": 1, "baz": 2} ] }, "cases": [ { "expression": "foo[?bar==`1`].bar[0]", "result": [] } ] }, { "given": { "foo": [ {"a": 1, "b": {"c": "x"}}, {"a": 1, "b": {"c": "y"}}, {"a": 1, "b": {"c": "z"}}, {"a": 2, "b": {"c": "z"}}, {"a": 1, "baz": 2} ] }, "cases": [ { "expression": "foo[?a==`1`].b.c", "result": ["x", "y", "z"] } ] }, { "given": {"foo": [{"name": "a"}, {"name": "b"}, {"name": "c"}]}, "cases": [ { "comment": "Filter with or expression", "expression": "foo[?name == 'a' || name == 'b']", "result": [{"name": "a"}, {"name": "b"}] }, { "expression": "foo[?name == 'a' || name == 'e']", "result": [{"name": "a"}] }, { "expression": "foo[?name == 'a' || name == 'b' || name == 'c']", "result": [{"name": "a"}, {"name": "b"}, {"name": "c"}] } ] }, { "given": {"foo": [{"a": 1, "b": 2}, {"a": 1, "b": 3}]}, "cases": [ { "comment": "Filter with and expression", "expression": "foo[?a == `1` && b == `2`]", "result": [{"a": 1, "b": 2}] }, { "expression": "foo[?a == `1` && b == `4`]", "result": [] } ] }, { "given": {"foo": [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4}]}, "cases": [ { "comment": "Filter with Or and And expressions", "expression": "foo[?c == `3` || a == `1` && b == `4`]", "result": [{"a": 1, "b": 2, "c": 3}] }, { "expression": "foo[?b == `2` || a == `3` && b == `4`]", "result": [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4}] }, { "expression": "foo[?a == `3` && b == `4` || b == `2`]", "result": [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4}] }, { "expression": "foo[?(a == `3` && b == `4`) || b == `2`]", "result": [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4}] }, { "expression": "foo[?((a == `3` && b == `4`)) || b == `2`]", "result": [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4}] }, { "expression": "foo[?a == `3` && (b == `4` || b == `2`)]", "result": [{"a": 3, "b": 4}] }, { "expression": "foo[?a == `3` && ((b == `4` || b == `2`))]", "result": [{"a": 3, "b": 4}] } ] }, { "given": {"foo": [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4}]}, "cases": [ { "comment": "Verify precedence of or/and expressions", "expression": "foo[?a == `1` || b ==`2` && c == `5`]", "result": [{"a": 1, "b": 2, "c": 3}] }, { "comment": "Parentheses can alter precedence", "expression": "foo[?(a == `1` || b ==`2`) && c == `5`]", "result": [] }, { "comment": "Not expressions combined with and/or", "expression": "foo[?!(a == `1` || b ==`2`)]", "result": [{"a": 3, "b": 4}] } ] }, { "given": { "foo": [ {"key": true}, {"key": false}, {"key": []}, {"key": {}}, {"key": [0]}, {"key": {"a": "b"}}, {"key": 0}, {"key": 1}, {"key": null}, {"notkey": true} ] }, "cases": [ { "comment": "Unary filter expression", "expression": "foo[?key]", "result": [ {"key": true}, {"key": [0]}, {"key": {"a": "b"}}, {"key": 0}, {"key": 1} ] }, { "comment": "Unary not filter expression", "expression": "foo[?!key]", "result": [ {"key": false}, {"key": []}, {"key": {}}, {"key": null}, {"notkey": true} ] }, { "comment": "Equality with null RHS", "expression": "foo[?key == `null`]", "result": [ {"key": null}, {"notkey": true} ] } ] }, { "given": { "foo": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] }, "cases": [ { "comment": "Using @ in a filter expression", "expression": "foo[?@ < `5`]", "result": [0, 1, 2, 3, 4] }, { "comment": "Using @ in a filter expression", "expression": "foo[?`5` > @]", "result": [0, 1, 2, 3, 4] }, { "comment": "Using @ in a filter expression", "expression": "foo[?@ == @]", "result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] } ] } ] jsoncons-1.3.2/test/jmespath/input/compliance/functions.json000066400000000000000000000432571477700171100243370ustar00rootroot00000000000000[{ "given": { "foo": -1, "zero": 0, "numbers": [-1, 3, 4, 5], "array": [-1, 3, 4, 5, "a", "100"], "strings": ["a", "b", "c"], "decimals": [1.01, 1.2, -1.5], "str": "Str", "false": false, "empty_list": [], "empty_hash": {}, "objects": {"foo": "bar", "bar": "baz"}, "null_key": null }, "cases": [ { "expression": "abs(foo)", "result": 1 }, { "expression": "abs(foo)", "result": 1 }, { "expression": "abs(str)", "error": "invalid-type" }, { "expression": "abs(array[1])", "result": 3 }, { "expression": "abs(array[1])", "result": 3 }, { "expression": "abs(`false`)", "error": "invalid-type" }, { "expression": "abs(`-24`)", "result": 24 }, { "expression": "abs(`-24`)", "result": 24 }, { "expression": "abs(`1`, `2`)", "error": "invalid-arity" }, { "expression": "abs()", "error": "invalid-arity" }, { "expression": "unknown_function(`1`, `2`)", "error": "unknown-function" }, { "expression": "avg(numbers)", "result": 2.75 }, { "expression": "avg(array)", "error": "invalid-type" }, { "expression": "avg('abc')", "error": "invalid-type" }, { "expression": "avg(foo)", "error": "invalid-type" }, { "expression": "avg(@)", "error": "invalid-type" }, { "expression": "avg(strings)", "error": "invalid-type" }, { "expression": "avg(empty_list)", "result": null }, { "expression": "ceil(`1.2`)", "result": 2 }, { "expression": "ceil(decimals[0])", "result": 2 }, { "expression": "ceil(decimals[1])", "result": 2 }, { "expression": "ceil(decimals[2])", "result": -1 }, { "expression": "ceil('string')", "error": "invalid-type" }, { "expression": "contains('abc', 'a')", "result": true }, { "expression": "contains('abc', 'd')", "result": false }, { "expression": "contains(`false`, 'd')", "error": "invalid-type" }, { "expression": "contains(strings, 'a')", "result": true }, { "expression": "contains(decimals, `1.2`)", "result": true }, { "expression": "contains(decimals, `false`)", "result": false }, { "expression": "ends_with(str, 'r')", "result": true }, { "expression": "ends_with(str, 'tr')", "result": true }, { "expression": "ends_with(str, 'Str')", "result": true }, { "expression": "ends_with(str, 'SStr')", "result": false }, { "expression": "ends_with(str, 'foo')", "result": false }, { "expression": "ends_with(str, `0`)", "error": "invalid-type" }, { "expression": "floor(`1.2`)", "result": 1 }, { "expression": "floor('string')", "error": "invalid-type" }, { "expression": "floor(decimals[0])", "result": 1 }, { "expression": "floor(foo)", "result": -1 }, { "expression": "floor(str)", "error": "invalid-type" }, { "expression": "length('abc')", "result": 3 }, { "expression": "length('✓foo')", "result": 4 }, { "expression": "length('')", "result": 0 }, { "expression": "length(@)", "result": 12 }, { "expression": "length(strings[0])", "result": 1 }, { "expression": "length(str)", "result": 3 }, { "expression": "length(array)", "result": 6 }, { "expression": "length(objects)", "result": 2 }, { "expression": "length(`false`)", "error": "invalid-type" }, { "expression": "length(foo)", "error": "invalid-type" }, { "expression": "length(strings[0])", "result": 1 }, { "expression": "max(numbers)", "result": 5 }, { "expression": "max(decimals)", "result": 1.2 }, { "expression": "max(strings)", "result": "c" }, { "expression": "max(abc)", "error": "invalid-type" }, { "expression": "max(array)", "error": "invalid-type" }, { "expression": "max(decimals)", "result": 1.2 }, { "expression": "max(empty_list)", "result": null }, { "expression": "merge(`{}`)", "result": {} }, { "expression": "merge(`{}`, `{}`)", "result": {} }, { "expression": "merge(`{\"a\": 1}`, `{\"b\": 2}`)", "result": {"a": 1, "b": 2} }, { "expression": "merge(`{\"a\": 1}`, `{\"a\": 2}`)", "result": {"a": 2} }, { "expression": "merge(`{\"a\": 1, \"b\": 2}`, `{\"a\": 2, \"c\": 3}`, `{\"d\": 4}`)", "result": {"a": 2, "b": 2, "c": 3, "d": 4} }, { "expression": "min(numbers)", "result": -1 }, { "expression": "min(decimals)", "result": -1.5 }, { "expression": "min(abc)", "error": "invalid-type" }, { "expression": "min(array)", "error": "invalid-type" }, { "expression": "min(empty_list)", "result": null }, { "expression": "min(decimals)", "result": -1.5 }, { "expression": "min(strings)", "result": "a" }, { "expression": "type('abc')", "result": "string" }, { "expression": "type(`1.0`)", "result": "number" }, { "expression": "type(`2`)", "result": "number" }, { "expression": "type(`true`)", "result": "boolean" }, { "expression": "type(`false`)", "result": "boolean" }, { "expression": "type(`null`)", "result": "null" }, { "expression": "type(`[0]`)", "result": "array" }, { "expression": "type(`{\"a\": \"b\"}`)", "result": "object" }, { "expression": "type(@)", "result": "object" }, { "expression": "sort(keys(objects))", "result": ["bar", "foo"] }, { "expression": "keys(foo)", "error": "invalid-type" }, { "expression": "keys(strings)", "error": "invalid-type" }, { "expression": "keys(`false`)", "error": "invalid-type" }, { "expression": "sort(values(objects))", "result": ["bar", "baz"] }, { "expression": "keys(empty_hash)", "result": [] }, { "expression": "values(foo)", "error": "invalid-type" }, { "expression": "join(', ', strings)", "result": "a, b, c" }, { "expression": "join(', ', strings)", "result": "a, b, c" }, { "expression": "join(',', `[\"a\", \"b\"]`)", "result": "a,b" }, { "expression": "join(',', `[\"a\", 0]`)", "error": "invalid-type" }, { "expression": "join(', ', str)", "error": "invalid-type" }, { "expression": "join('|', strings)", "result": "a|b|c" }, { "expression": "join(`2`, strings)", "error": "invalid-type" }, { "expression": "join('|', decimals)", "error": "invalid-type" }, { "expression": "join('|', decimals[].to_string(@))", "result": "1.01|1.2|-1.5" }, { "expression": "join('|', empty_list)", "result": "" }, { "expression": "reverse(numbers)", "result": [5, 4, 3, -1] }, { "expression": "reverse(array)", "result": ["100", "a", 5, 4, 3, -1] }, { "expression": "reverse(`[]`)", "result": [] }, { "expression": "reverse('')", "result": "" }, { "expression": "reverse('hello world')", "result": "dlrow olleh" }, { "expression": "starts_with(str, 'S')", "result": true }, { "expression": "starts_with(str, 'St')", "result": true }, { "expression": "starts_with(str, 'Str')", "result": true }, { "expression": "starts_with(str, 'String')", "result": false }, { "expression": "starts_with(str, `0`)", "error": "invalid-type" }, { "expression": "sum(numbers)", "result": 11 }, { "expression": "sum(decimals)", "result": 0.71 }, { "expression": "sum(array)", "error": "invalid-type" }, { "expression": "sum(array[].to_number(@))", "result": 111 }, { "expression": "sum(`[]`)", "result": 0 }, { "expression": "to_array('foo')", "result": ["foo"] }, { "expression": "to_array(`0`)", "result": [0] }, { "expression": "to_array(objects)", "result": [{"foo": "bar", "bar": "baz"}] }, { "expression": "to_array(`[1, 2, 3]`)", "result": [1, 2, 3] }, { "expression": "to_array(false)", "result": [false] }, { "expression": "to_string('foo')", "result": "foo" }, { "expression": "to_string(`1.2`)", "result": "1.2" }, { "expression": "to_string(`[0, 1]`)", "result": "[0,1]" }, { "expression": "to_number('1.0')", "result": 1.0 }, { "expression": "to_number('1.1')", "result": 1.1 }, { "expression": "to_number('4')", "result": 4 }, { "expression": "to_number('notanumber')", "result": null }, { "expression": "to_number(`false`)", "result": null }, { "expression": "to_number(`null`)", "result": null }, { "expression": "to_number(`[0]`)", "result": null }, { "expression": "to_number(`{\"foo\": 0}`)", "result": null }, { "expression": "\"to_string\"(`1.0`)", "error": "syntax" }, { "expression": "sort(numbers)", "result": [-1, 3, 4, 5] }, { "expression": "sort(strings)", "result": ["a", "b", "c"] }, { "expression": "sort(decimals)", "result": [-1.5, 1.01, 1.2] }, { "expression": "sort(array)", "error": "invalid-type" }, { "expression": "sort(abc)", "error": "invalid-type" }, { "expression": "sort(empty_list)", "result": [] }, { "expression": "sort(@)", "error": "invalid-type" }, { "expression": "not_null(unknown_key, str)", "result": "Str" }, { "expression": "not_null(unknown_key, foo.bar, empty_list, str)", "result": [] }, { "expression": "not_null(unknown_key, null_key, empty_list, str)", "result": [] }, { "expression": "not_null(all, expressions, are_null)", "result": null }, { "expression": "not_null()", "result": null }, { "comment": "function projection on single arg function", "expression": "numbers[].to_string(@)", "result": ["-1", "3", "4", "5"] }, { "comment": "function projection on single arg function", "expression": "array[].to_number(@)", "result": [-1, 3, 4, 5, 100] } ] }, { "given": { "foo": [ {"b": "b", "a": "a"}, {"c": "c", "b": "b"}, {"d": "d", "c": "c"}, {"e": "e", "d": "d"}, {"f": "f", "e": "e"} ] }, "cases": [ { "comment": "function projection on variadic function", "expression": "foo[].not_null(f, e, d, c, b, a)", "result": ["b", "c", "d", "e", "f"] } ] }, { "given": { "people": [ {"age": 20, "age_str": "20", "bool": true, "name": "a", "extra": "foo"}, {"age": 40, "age_str": "40", "bool": false, "name": "b", "extra": "bar"}, {"age": 30, "age_str": "30", "bool": true, "name": "c"}, {"age": 50, "age_str": "50", "bool": false, "name": "d"}, {"age": 10, "age_str": "10", "bool": true, "name": 3} ] }, "cases": [ { "comment": "sort by field expression", "expression": "sort_by(people, &age)", "result": [ {"age": 10, "age_str": "10", "bool": true, "name": 3}, {"age": 20, "age_str": "20", "bool": true, "name": "a", "extra": "foo"}, {"age": 30, "age_str": "30", "bool": true, "name": "c"}, {"age": 40, "age_str": "40", "bool": false, "name": "b", "extra": "bar"}, {"age": 50, "age_str": "50", "bool": false, "name": "d"} ] }, { "expression": "sort_by(people, &age_str)", "result": [ {"age": 10, "age_str": "10", "bool": true, "name": 3}, {"age": 20, "age_str": "20", "bool": true, "name": "a", "extra": "foo"}, {"age": 30, "age_str": "30", "bool": true, "name": "c"}, {"age": 40, "age_str": "40", "bool": false, "name": "b", "extra": "bar"}, {"age": 50, "age_str": "50", "bool": false, "name": "d"} ] }, { "comment": "sort by function expression", "expression": "sort_by(people, &to_number(age_str))", "result": [ {"age": 10, "age_str": "10", "bool": true, "name": 3}, {"age": 20, "age_str": "20", "bool": true, "name": "a", "extra": "foo"}, {"age": 30, "age_str": "30", "bool": true, "name": "c"}, {"age": 40, "age_str": "40", "bool": false, "name": "b", "extra": "bar"}, {"age": 50, "age_str": "50", "bool": false, "name": "d"} ] }, { "comment": "function projection on sort_by function", "expression": "sort_by(people, &age)[].name", "result": [3, "a", "c", "b", "d"] }, { "expression": "sort_by(people, &extra)", "error": "invalid-type" }, { "expression": "sort_by(people, &bool)", "error": "invalid-type" }, { "expression": "sort_by(people, &name)", "error": "invalid-type" }, { "expression": "sort_by(people, name)", "error": "invalid-type" }, { "expression": "sort_by(people, &age)[].extra", "result": ["foo", "bar"] }, { "expression": "sort_by(`[]`, &age)", "result": [] }, { "expression": "max_by(people, &age)", "result": {"age": 50, "age_str": "50", "bool": false, "name": "d"} }, { "expression": "max_by(people, &age_str)", "result": {"age": 50, "age_str": "50", "bool": false, "name": "d"} }, { "expression": "max_by(people, &bool)", "error": "invalid-type" }, { "expression": "max_by(people, &extra)", "error": "invalid-type" }, { "expression": "max_by(people, &to_number(age_str))", "result": {"age": 50, "age_str": "50", "bool": false, "name": "d"} }, { "expression": "min_by(people, &age)", "result": {"age": 10, "age_str": "10", "bool": true, "name": 3} }, { "expression": "min_by(people, &age_str)", "result": {"age": 10, "age_str": "10", "bool": true, "name": 3} }, { "expression": "min_by(people, &bool)", "error": "invalid-type" }, { "expression": "min_by(people, &extra)", "error": "invalid-type" }, { "expression": "min_by(people, &to_number(age_str))", "result": {"age": 10, "age_str": "10", "bool": true, "name": 3} } ] }, { "given": { "people": [ {"age": 10, "order": "1"}, {"age": 10, "order": "2"}, {"age": 10, "order": "3"}, {"age": 10, "order": "4"}, {"age": 10, "order": "5"}, {"age": 10, "order": "6"}, {"age": 10, "order": "7"}, {"age": 10, "order": "8"}, {"age": 10, "order": "9"}, {"age": 10, "order": "10"}, {"age": 10, "order": "11"} ] }, "cases": [ { "comment": "stable sort order", "expression": "sort_by(people, &age)", "result": [ {"age": 10, "order": "1"}, {"age": 10, "order": "2"}, {"age": 10, "order": "3"}, {"age": 10, "order": "4"}, {"age": 10, "order": "5"}, {"age": 10, "order": "6"}, {"age": 10, "order": "7"}, {"age": 10, "order": "8"}, {"age": 10, "order": "9"}, {"age": 10, "order": "10"}, {"age": 10, "order": "11"} ] } ] }, { "given": { "people": [ {"a": 10, "b": 1, "c": "z"}, {"a": 10, "b": 2, "c": null}, {"a": 10, "b": 3}, {"a": 10, "b": 4, "c": "z"}, {"a": 10, "b": 5, "c": null}, {"a": 10, "b": 6}, {"a": 10, "b": 7, "c": "z"}, {"a": 10, "b": 8, "c": null}, {"a": 10, "b": 9} ], "empty": [] }, "cases": [ { "expression": "map(&a, people)", "result": [10, 10, 10, 10, 10, 10, 10, 10, 10] }, { "expression": "map(&c, people)", "result": ["z", null, null, "z", null, null, "z", null, null] }, { "expression": "map(&a, badkey)", "error": "invalid-type" }, { "expression": "map(&foo, empty)", "result": [] } ] }, { "given": { "array": [ { "foo": {"bar": "yes1"} }, { "foo": {"bar": "yes2"} }, { "foo1": {"bar": "no"} } ]}, "cases": [ { "expression": "map(&foo.bar, array)", "result": ["yes1", "yes2", null] }, { "expression": "map(&foo1.bar, array)", "result": [null, null, "no"] }, { "expression": "map(&foo.bar.baz, array)", "result": [null, null, null] } ] }, { "given": { "array": [[1, 2, 3, [4]], [5, 6, 7, [8, 9]]] }, "cases": [ { "expression": "map(&[], array)", "result": [[1, 2, 3, 4], [5, 6, 7, 8, 9]] } ] } ] jsoncons-1.3.2/test/jmespath/input/compliance/identifiers.json000066400000000000000000000602321477700171100246240ustar00rootroot00000000000000[ { "given": { "__L": true }, "cases": [ { "expression": "__L", "result": true } ] }, { "given": { "!\r": true }, "cases": [ { "expression": "\"!\\r\"", "result": true } ] }, { "given": { "Y_1623": true }, "cases": [ { "expression": "Y_1623", "result": true } ] }, { "given": { "x": true }, "cases": [ { "expression": "x", "result": true } ] }, { "given": { "\tF\uCebb": true }, "cases": [ { "expression": "\"\\tF\\uCebb\"", "result": true } ] }, { "given": { " \t": true }, "cases": [ { "expression": "\" \\t\"", "result": true } ] }, { "given": { " ": true }, "cases": [ { "expression": "\" \"", "result": true } ] }, { "given": { "v2": true }, "cases": [ { "expression": "v2", "result": true } ] }, { "given": { "\t": true }, "cases": [ { "expression": "\"\\t\"", "result": true } ] }, { "given": { "_X": true }, "cases": [ { "expression": "_X", "result": true } ] }, { "given": { "\t4\ud9da\udd15": true }, "cases": [ { "expression": "\"\\t4\\ud9da\\udd15\"", "result": true } ] }, { "given": { "v24_W": true }, "cases": [ { "expression": "v24_W", "result": true } ] }, { "given": { "H": true }, "cases": [ { "expression": "\"H\"", "result": true } ] }, { "given": { "\f": true }, "cases": [ { "expression": "\"\\f\"", "result": true } ] }, { "given": { "E4": true }, "cases": [ { "expression": "\"E4\"", "result": true } ] }, { "given": { "!": true }, "cases": [ { "expression": "\"!\"", "result": true } ] }, { "given": { "tM": true }, "cases": [ { "expression": "tM", "result": true } ] }, { "given": { " [": true }, "cases": [ { "expression": "\" [\"", "result": true } ] }, { "given": { "R!": true }, "cases": [ { "expression": "\"R!\"", "result": true } ] }, { "given": { "_6W": true }, "cases": [ { "expression": "_6W", "result": true } ] }, { "given": { "\uaBA1\r": true }, "cases": [ { "expression": "\"\\uaBA1\\r\"", "result": true } ] }, { "given": { "tL7": true }, "cases": [ { "expression": "tL7", "result": true } ] }, { "given": { "<": true }, "cases": [ { "expression": "\">\"", "result": true } ] }, { "given": { "hvu": true }, "cases": [ { "expression": "hvu", "result": true } ] }, { "given": { "; !": true }, "cases": [ { "expression": "\"; !\"", "result": true } ] }, { "given": { "hU": true }, "cases": [ { "expression": "hU", "result": true } ] }, { "given": { "!I\n\/": true }, "cases": [ { "expression": "\"!I\\n\\/\"", "result": true } ] }, { "given": { "\uEEbF": true }, "cases": [ { "expression": "\"\\uEEbF\"", "result": true } ] }, { "given": { "U)\t": true }, "cases": [ { "expression": "\"U)\\t\"", "result": true } ] }, { "given": { "fa0_9": true }, "cases": [ { "expression": "fa0_9", "result": true } ] }, { "given": { "/": true }, "cases": [ { "expression": "\"/\"", "result": true } ] }, { "given": { "Gy": true }, "cases": [ { "expression": "Gy", "result": true } ] }, { "given": { "\b": true }, "cases": [ { "expression": "\"\\b\"", "result": true } ] }, { "given": { "<": true }, "cases": [ { "expression": "\"<\"", "result": true } ] }, { "given": { "\t": true }, "cases": [ { "expression": "\"\\t\"", "result": true } ] }, { "given": { "\t&\\\r": true }, "cases": [ { "expression": "\"\\t&\\\\\\r\"", "result": true } ] }, { "given": { "#": true }, "cases": [ { "expression": "\"#\"", "result": true } ] }, { "given": { "B__": true }, "cases": [ { "expression": "B__", "result": true } ] }, { "given": { "\nS \n": true }, "cases": [ { "expression": "\"\\nS \\n\"", "result": true } ] }, { "given": { "Bp": true }, "cases": [ { "expression": "Bp", "result": true } ] }, { "given": { ",\t;": true }, "cases": [ { "expression": "\",\\t;\"", "result": true } ] }, { "given": { "B_q": true }, "cases": [ { "expression": "B_q", "result": true } ] }, { "given": { "\/+\t\n\b!Z": true }, "cases": [ { "expression": "\"\\/+\\t\\n\\b!Z\"", "result": true } ] }, { "given": { "\udadd\udfc7\\ueFAc": true }, "cases": [ { "expression": "\"\udadd\udfc7\\\\ueFAc\"", "result": true } ] }, { "given": { ":\f": true }, "cases": [ { "expression": "\":\\f\"", "result": true } ] }, { "given": { "\/": true }, "cases": [ { "expression": "\"\\/\"", "result": true } ] }, { "given": { "_BW_6Hg_Gl": true }, "cases": [ { "expression": "_BW_6Hg_Gl", "result": true } ] }, { "given": { "\udbcf\udc02": true }, "cases": [ { "expression": "\"\udbcf\udc02\"", "result": true } ] }, { "given": { "zs1DC": true }, "cases": [ { "expression": "zs1DC", "result": true } ] }, { "given": { "__434": true }, "cases": [ { "expression": "__434", "result": true } ] }, { "given": { "\udb94\udd41": true }, "cases": [ { "expression": "\"\udb94\udd41\"", "result": true } ] }, { "given": { "Z_5": true }, "cases": [ { "expression": "Z_5", "result": true } ] }, { "given": { "z_M_": true }, "cases": [ { "expression": "z_M_", "result": true } ] }, { "given": { "YU_2": true }, "cases": [ { "expression": "YU_2", "result": true } ] }, { "given": { "_0": true }, "cases": [ { "expression": "_0", "result": true } ] }, { "given": { "\b+": true }, "cases": [ { "expression": "\"\\b+\"", "result": true } ] }, { "given": { "\"": true }, "cases": [ { "expression": "\"\\\"\"", "result": true } ] }, { "given": { "D7": true }, "cases": [ { "expression": "D7", "result": true } ] }, { "given": { "_62L": true }, "cases": [ { "expression": "_62L", "result": true } ] }, { "given": { "\tK\t": true }, "cases": [ { "expression": "\"\\tK\\t\"", "result": true } ] }, { "given": { "\n\\\f": true }, "cases": [ { "expression": "\"\\n\\\\\\f\"", "result": true } ] }, { "given": { "I_": true }, "cases": [ { "expression": "I_", "result": true } ] }, { "given": { "W_a0_": true }, "cases": [ { "expression": "W_a0_", "result": true } ] }, { "given": { "BQ": true }, "cases": [ { "expression": "BQ", "result": true } ] }, { "given": { "\tX$\uABBb": true }, "cases": [ { "expression": "\"\\tX$\\uABBb\"", "result": true } ] }, { "given": { "Z9": true }, "cases": [ { "expression": "Z9", "result": true } ] }, { "given": { "\b%\"\uda38\udd0f": true }, "cases": [ { "expression": "\"\\b%\\\"\uda38\udd0f\"", "result": true } ] }, { "given": { "_F": true }, "cases": [ { "expression": "_F", "result": true } ] }, { "given": { "!,": true }, "cases": [ { "expression": "\"!,\"", "result": true } ] }, { "given": { "\"!": true }, "cases": [ { "expression": "\"\\\"!\"", "result": true } ] }, { "given": { "Hh": true }, "cases": [ { "expression": "Hh", "result": true } ] }, { "given": { "&": true }, "cases": [ { "expression": "\"&\"", "result": true } ] }, { "given": { "9\r\\R": true }, "cases": [ { "expression": "\"9\\r\\\\R\"", "result": true } ] }, { "given": { "M_k": true }, "cases": [ { "expression": "M_k", "result": true } ] }, { "given": { "!\b\n\udb06\ude52\"\"": true }, "cases": [ { "expression": "\"!\\b\\n\udb06\ude52\\\"\\\"\"", "result": true } ] }, { "given": { "6": true }, "cases": [ { "expression": "\"6\"", "result": true } ] }, { "given": { "_7": true }, "cases": [ { "expression": "_7", "result": true } ] }, { "given": { "0": true }, "cases": [ { "expression": "\"0\"", "result": true } ] }, { "given": { "\\8\\": true }, "cases": [ { "expression": "\"\\\\8\\\\\"", "result": true } ] }, { "given": { "b7eo": true }, "cases": [ { "expression": "b7eo", "result": true } ] }, { "given": { "xIUo9": true }, "cases": [ { "expression": "xIUo9", "result": true } ] }, { "given": { "5": true }, "cases": [ { "expression": "\"5\"", "result": true } ] }, { "given": { "?": true }, "cases": [ { "expression": "\"?\"", "result": true } ] }, { "given": { "sU": true }, "cases": [ { "expression": "sU", "result": true } ] }, { "given": { "VH2&H\\\/": true }, "cases": [ { "expression": "\"VH2&H\\\\\\/\"", "result": true } ] }, { "given": { "_C": true }, "cases": [ { "expression": "_C", "result": true } ] }, { "given": { "_": true }, "cases": [ { "expression": "_", "result": true } ] }, { "given": { "<\t": true }, "cases": [ { "expression": "\"<\\t\"", "result": true } ] }, { "given": { "\uD834\uDD1E": true }, "cases": [ { "expression": "\"\\uD834\\uDD1E\"", "result": true } ] } ] jsoncons-1.3.2/test/jmespath/input/compliance/indices.json000066400000000000000000000211371477700171100237360ustar00rootroot00000000000000[{ "given": {"foo": {"bar": ["zero", "one", "two"]}}, "cases": [ { "expression": "foo.bar[0]", "result": "zero" }, { "expression": "foo.bar[1]", "result": "one" }, { "expression": "foo.bar[2]", "result": "two" }, { "expression": "foo.bar[3]", "result": null }, { "expression": "foo.bar[-1]", "result": "two" }, { "expression": "foo.bar[-2]", "result": "one" }, { "expression": "foo.bar[-3]", "result": "zero" }, { "expression": "foo.bar[-4]", "result": null } ] }, { "given": {"foo": [{"bar": "one"}, {"bar": "two"}, {"bar": "three"}, {"notbar": "four"}]}, "cases": [ { "expression": "foo.bar", "result": null }, { "expression": "foo[0].bar", "result": "one" }, { "expression": "foo[1].bar", "result": "two" }, { "expression": "foo[2].bar", "result": "three" }, { "expression": "foo[3].notbar", "result": "four" }, { "expression": "foo[3].bar", "result": null }, { "expression": "foo[0]", "result": {"bar": "one"} }, { "expression": "foo[1]", "result": {"bar": "two"} }, { "expression": "foo[2]", "result": {"bar": "three"} }, { "expression": "foo[3]", "result": {"notbar": "four"} }, { "expression": "foo[4]", "result": null } ] }, { "given": [ "one", "two", "three" ], "cases": [ { "expression": "[0]", "result": "one" }, { "expression": "[1]", "result": "two" }, { "expression": "[2]", "result": "three" }, { "expression": "[-1]", "result": "three" }, { "expression": "[-2]", "result": "two" }, { "expression": "[-3]", "result": "one" } ] }, { "given": {"reservations": [ {"instances": [{"foo": 1}, {"foo": 2}]} ]}, "cases": [ { "expression": "reservations[].instances[].foo", "result": [1, 2] }, { "expression": "reservations[].instances[].bar", "result": [] }, { "expression": "reservations[].notinstances[].foo", "result": [] }, { "expression": "reservations[].notinstances[].foo", "result": [] } ] }, { "given": {"reservations": [{ "instances": [ {"foo": [{"bar": 1}, {"bar": 2}, {"notbar": 3}, {"bar": 4}]}, {"foo": [{"bar": 5}, {"bar": 6}, {"notbar": [7]}, {"bar": 8}]}, {"foo": "bar"}, {"notfoo": [{"bar": 20}, {"bar": 21}, {"notbar": [7]}, {"bar": 22}]}, {"bar": [{"baz": [1]}, {"baz": [2]}, {"baz": [3]}, {"baz": [4]}]}, {"baz": [{"baz": [1, 2]}, {"baz": []}, {"baz": []}, {"baz": [3, 4]}]}, {"qux": [{"baz": []}, {"baz": [1, 2, 3]}, {"baz": [4]}, {"baz": []}]} ], "otherkey": {"foo": [{"bar": 1}, {"bar": 2}, {"notbar": 3}, {"bar": 4}]} }, { "instances": [ {"a": [{"bar": 1}, {"bar": 2}, {"notbar": 3}, {"bar": 4}]}, {"b": [{"bar": 5}, {"bar": 6}, {"notbar": [7]}, {"bar": 8}]}, {"c": "bar"}, {"notfoo": [{"bar": 23}, {"bar": 24}, {"notbar": [7]}, {"bar": 25}]}, {"qux": [{"baz": []}, {"baz": [1, 2, 3]}, {"baz": [4]}, {"baz": []}]} ], "otherkey": {"foo": [{"bar": 1}, {"bar": 2}, {"notbar": 3}, {"bar": 4}]} } ]}, "cases": [ { "expression": "reservations[].instances[].foo[].bar", "result": [1, 2, 4, 5, 6, 8] }, { "expression": "reservations[].instances[].foo[].baz", "result": [] }, { "expression": "reservations[].instances[].notfoo[].bar", "result": [20, 21, 22, 23, 24, 25] }, { "expression": "reservations[].instances[].notfoo[].notbar", "result": [[7], [7]] }, { "expression": "reservations[].notinstances[].foo", "result": [] }, { "expression": "reservations[].instances[].foo[].notbar", "result": [3, [7]] }, { "expression": "reservations[].instances[].bar[].baz", "result": [[1], [2], [3], [4]] }, { "expression": "reservations[].instances[].baz[].baz", "result": [[1, 2], [], [], [3, 4]] }, { "expression": "reservations[].instances[].qux[].baz", "result": [[], [1, 2, 3], [4], [], [], [1, 2, 3], [4], []] }, { "expression": "reservations[].instances[].qux[].baz[]", "result": [1, 2, 3, 4, 1, 2, 3, 4] } ] }, { "given": { "foo": [ [["one", "two"], ["three", "four"]], [["five", "six"], ["seven", "eight"]], [["nine"], ["ten"]] ] }, "cases": [ { "expression": "foo[]", "result": [["one", "two"], ["three", "four"], ["five", "six"], ["seven", "eight"], ["nine"], ["ten"]] }, { "expression": "foo[][0]", "result": ["one", "three", "five", "seven", "nine", "ten"] }, { "expression": "foo[][1]", "result": ["two", "four", "six", "eight"] }, { "expression": "foo[][0][0]", "result": [] }, { "expression": "foo[][2][2]", "result": [] }, { "expression": "foo[][0][0][100]", "result": [] } ] }, { "given": { "foo": [{ "bar": [ { "qux": 2, "baz": 1 }, { "qux": 4, "baz": 3 } ] }, { "bar": [ { "qux": 6, "baz": 5 }, { "qux": 8, "baz": 7 } ] } ] }, "cases": [ { "expression": "foo", "result": [{"bar": [{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3}]}, {"bar": [{"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]}] }, { "expression": "foo[]", "result": [{"bar": [{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3}]}, {"bar": [{"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]}] }, { "expression": "foo[].bar", "result": [[{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3}], [{"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]] }, { "expression": "foo[].bar[]", "result": [{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3}, {"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}] }, { "expression": "foo[].bar[].baz", "result": [1, 3, 5, 7] } ] }, { "given": { "string": "string", "hash": {"foo": "bar", "bar": "baz"}, "number": 23, "nullvalue": null }, "cases": [ { "expression": "string[]", "result": null }, { "expression": "hash[]", "result": null }, { "expression": "number[]", "result": null }, { "expression": "nullvalue[]", "result": null }, { "expression": "string[].foo", "result": null }, { "expression": "hash[].foo", "result": null }, { "expression": "number[].foo", "result": null }, { "expression": "nullvalue[].foo", "result": null }, { "expression": "nullvalue[].foo[].bar", "result": null } ] } ] jsoncons-1.3.2/test/jmespath/input/compliance/literal.json000066400000000000000000000121271477700171100237530ustar00rootroot00000000000000[ { "given": { "foo": [{"name": "a"}, {"name": "b"}], "bar": {"baz": "qux"} }, "cases": [ { "expression": "`\"foo\"`", "result": "foo" }, { "comment": "Interpret escaped unicode.", "expression": "`\"\\u03a6\"`", "result": "Φ" }, { "expression": "`\"✓\"`", "result": "✓" }, { "expression": "`[1, 2, 3]`", "result": [1, 2, 3] }, { "expression": "`{\"a\": \"b\"}`", "result": {"a": "b"} }, { "expression": "`true`", "result": true }, { "expression": "`false`", "result": false }, { "expression": "`null`", "result": null }, { "expression": "`0`", "result": 0 }, { "expression": "`1`", "result": 1 }, { "expression": "`2`", "result": 2 }, { "expression": "`3`", "result": 3 }, { "expression": "`4`", "result": 4 }, { "expression": "`5`", "result": 5 }, { "expression": "`6`", "result": 6 }, { "expression": "`7`", "result": 7 }, { "expression": "`8`", "result": 8 }, { "expression": "`9`", "result": 9 }, { "comment": "Escaping a backtick in quotes", "expression": "`\"foo\\`bar\"`", "result": "foo`bar" }, { "comment": "Double quote in literal", "expression": "`\"foo\\\"bar\"`", "result": "foo\"bar" }, { "expression": "`\"1\\`\"`", "result": "1`" }, { "comment": "Multiple literal expressions with escapes", "expression": "`\"\\\\\"`.{a:`\"b\"`}", "result": {"a": "b"} }, { "comment": "literal . identifier", "expression": "`{\"a\": \"b\"}`.a", "result": "b" }, { "comment": "literal . identifier . identifier", "expression": "`{\"a\": {\"b\": \"c\"}}`.a.b", "result": "c" }, { "comment": "literal . identifier bracket-expr", "expression": "`[0, 1, 2]`[1]", "result": 1 } ] }, { "comment": "Literals", "given": {"type": "object"}, "cases": [ { "comment": "Literal with leading whitespace", "expression": "` {\"foo\": true}`", "result": {"foo": true} }, { "comment": "Literal with trailing whitespace", "expression": "`{\"foo\": true} `", "result": {"foo": true} }, { "comment": "Literal on RHS of subexpr not allowed", "expression": "foo.`\"bar\"`", "error": "syntax" } ] }, { "comment": "Raw String Literals", "given": {}, "cases": [ { "expression": "'foo'", "result": "foo" }, { "expression": "' foo '", "result": " foo " }, { "expression": "'0'", "result": "0" }, { "expression": "'newline\n'", "result": "newline\n" }, { "expression": "'\n'", "result": "\n" }, { "expression": "'✓'", "result": "✓" }, { "expression": "'𝄞'", "result": "𝄞" }, { "expression": "' [foo] '", "result": " [foo] " }, { "expression": "'[foo]'", "result": "[foo]" }, { "comment": "Do not interpret escaped unicode.", "expression": "'\\u03a6'", "result": "\\u03a6" }, { "comment": "Can escape the single quote", "expression": "'foo\\'bar'", "result": "foo'bar" }, { "comment": "Backslash not followed by single quote is treated as any other character", "expression": "'\\z'", "result": "\\z" }, { "comment": "Backslash not followed by single quote is treated as any other character", "expression": "'\\\\'", "result": "\\\\" } ] } ] jsoncons-1.3.2/test/jmespath/input/compliance/multiselect.json000066400000000000000000000242361477700171100246550ustar00rootroot00000000000000[{ "given": { "foo": { "bar": "bar", "baz": "baz", "qux": "qux", "nested": { "one": { "a": "first", "b": "second", "c": "third" }, "two": { "a": "first", "b": "second", "c": "third" }, "three": { "a": "first", "b": "second", "c": {"inner": "third"} } } }, "bar": 1, "baz": 2, "qux\"": 3 }, "cases": [ { "expression": "foo.{bar: bar}", "result": {"bar": "bar"} }, { "expression": "foo.{\"bar\": bar}", "result": {"bar": "bar"} }, { "expression": "foo.{\"foo.bar\": bar}", "result": {"foo.bar": "bar"} }, { "expression": "foo.{bar: bar, baz: baz}", "result": {"bar": "bar", "baz": "baz"} }, { "expression": "foo.{\"bar\": bar, \"baz\": baz}", "result": {"bar": "bar", "baz": "baz"} }, { "expression": "{\"baz\": baz, \"qux\\\"\": \"qux\\\"\"}", "result": {"baz": 2, "qux\"": 3} }, { "expression": "foo.{bar:bar,baz:baz}", "result": {"bar": "bar", "baz": "baz"} }, { "expression": "foo.{bar: bar,qux: qux}", "result": {"bar": "bar", "qux": "qux"} }, { "expression": "foo.{bar: bar, noexist: noexist}", "result": {"bar": "bar", "noexist": null} }, { "expression": "foo.{noexist: noexist, alsonoexist: alsonoexist}", "result": {"noexist": null, "alsonoexist": null} }, { "expression": "foo.badkey.{nokey: nokey, alsonokey: alsonokey}", "result": null }, { "expression": "foo.nested.*.{a: a,b: b}", "result": [{"a": "first", "b": "second"}, {"a": "first", "b": "second"}, {"a": "first", "b": "second"}] }, { "expression": "foo.nested.three.{a: a, cinner: c.inner}", "result": {"a": "first", "cinner": "third"} }, { "expression": "foo.nested.three.{a: a, c: c.inner.bad.key}", "result": {"a": "first", "c": null} }, { "expression": "foo.{a: nested.one.a, b: nested.two.b}", "result": {"a": "first", "b": "second"} }, { "expression": "{bar: bar, baz: baz}", "result": {"bar": 1, "baz": 2} }, { "expression": "{bar: bar}", "result": {"bar": 1} }, { "expression": "{otherkey: bar}", "result": {"otherkey": 1} }, { "expression": "{no: no, exist: exist}", "result": {"no": null, "exist": null} }, { "expression": "foo.[bar]", "result": ["bar"] }, { "expression": "foo.[bar,baz]", "result": ["bar", "baz"] }, { "expression": "foo.[bar,qux]", "result": ["bar", "qux"] }, { "expression": "foo.[bar,noexist]", "result": ["bar", null] }, { "expression": "foo.[noexist,alsonoexist]", "result": [null, null] } ] }, { "given": { "foo": {"bar": 1, "baz": [2, 3, 4]} }, "cases": [ { "expression": "foo.{bar:bar,baz:baz}", "result": {"bar": 1, "baz": [2, 3, 4]} }, { "expression": "foo.[bar,baz[0]]", "result": [1, 2] }, { "expression": "foo.[bar,baz[1]]", "result": [1, 3] }, { "expression": "foo.[bar,baz[2]]", "result": [1, 4] }, { "expression": "foo.[bar,baz[3]]", "result": [1, null] }, { "expression": "foo.[bar[0],baz[3]]", "result": [null, null] } ] }, { "given": { "foo": {"bar": 1, "baz": 2} }, "cases": [ { "expression": "foo.{bar: bar, baz: baz}", "result": {"bar": 1, "baz": 2} }, { "expression": "foo.[bar,baz]", "result": [1, 2] } ] }, { "given": { "foo": { "bar": {"baz": [{"common": "first", "one": 1}, {"common": "second", "two": 2}]}, "ignoreme": 1, "includeme": true } }, "cases": [ { "expression": "foo.{bar: bar.baz[1],includeme: includeme}", "result": {"bar": {"common": "second", "two": 2}, "includeme": true} }, { "expression": "foo.{\"bar.baz.two\": bar.baz[1].two, includeme: includeme}", "result": {"bar.baz.two": 2, "includeme": true} }, { "expression": "foo.[includeme, bar.baz[*].common]", "result": [true, ["first", "second"]] }, { "expression": "foo.[includeme, bar.baz[*].none]", "result": [true, []] }, { "expression": "foo.[includeme, bar.baz[].common]", "result": [true, ["first", "second"]] } ] }, { "given": { "reservations": [{ "instances": [ {"id": "id1", "name": "first"}, {"id": "id2", "name": "second"} ]}, { "instances": [ {"id": "id3", "name": "third"}, {"id": "id4", "name": "fourth"} ]} ]}, "cases": [ { "expression": "reservations[*].instances[*].{id: id, name: name}", "result": [[{"id": "id1", "name": "first"}, {"id": "id2", "name": "second"}], [{"id": "id3", "name": "third"}, {"id": "id4", "name": "fourth"}]] }, { "expression": "reservations[].instances[].{id: id, name: name}", "result": [{"id": "id1", "name": "first"}, {"id": "id2", "name": "second"}, {"id": "id3", "name": "third"}, {"id": "id4", "name": "fourth"}] }, { "expression": "reservations[].instances[].[id, name]", "result": [["id1", "first"], ["id2", "second"], ["id3", "third"], ["id4", "fourth"]] } ] }, { "given": { "foo": [{ "bar": [ { "qux": 2, "baz": 1 }, { "qux": 4, "baz": 3 } ] }, { "bar": [ { "qux": 6, "baz": 5 }, { "qux": 8, "baz": 7 } ] } ] }, "cases": [ { "expression": "foo", "result": [{"bar": [{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3}]}, {"bar": [{"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]}] }, { "expression": "foo[]", "result": [{"bar": [{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3}]}, {"bar": [{"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]}] }, { "expression": "foo[].bar", "result": [[{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3}], [{"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]] }, { "expression": "foo[].bar[]", "result": [{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3}, {"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}] }, { "expression": "foo[].bar[].[baz, qux]", "result": [[1, 2], [3, 4], [5, 6], [7, 8]] }, { "expression": "foo[].bar[].[baz]", "result": [[1], [3], [5], [7]] }, { "expression": "foo[].bar[].[baz, qux][]", "result": [1, 2, 3, 4, 5, 6, 7, 8] } ] }, { "given": { "foo": { "baz": [ { "bar": "abc" }, { "bar": "def" } ], "qux": ["zero"] } }, "cases": [ { "expression": "foo.[baz[*].bar, qux[0]]", "result": [["abc", "def"], "zero"] } ] }, { "given": { "foo": { "baz": [ { "bar": "a", "bam": "b", "boo": "c" }, { "bar": "d", "bam": "e", "boo": "f" } ], "qux": ["zero"] } }, "cases": [ { "expression": "foo.[baz[*].[bar, boo], qux[0]]", "result": [[["a", "c" ], ["d", "f" ]], "zero"] } ] }, { "given": { "foo": { "baz": [ { "bar": "a", "bam": "b", "boo": "c" }, { "bar": "d", "bam": "e", "boo": "f" } ], "qux": ["zero"] } }, "cases": [ { "expression": "foo.[baz[*].not_there || baz[*].bar, qux[0]]", "result": [["a", "d"], "zero"] } ] }, { "given": {"type": "object"}, "cases": [ { "comment": "Nested multiselect", "expression": "[[*],*]", "result": [null, ["object"]] } ] }, { "given": [], "cases": [ { "comment": "Nested multiselect", "expression": "[[*]]", "result": [[]] }, { "comment": "Select on null", "expression": "missing.{foo: bar}", "result": null } ] } ] jsoncons-1.3.2/test/jmespath/input/compliance/pipe.json000066400000000000000000000044511477700171100232550ustar00rootroot00000000000000[{ "given": { "foo": { "bar": { "baz": "subkey" }, "other": { "baz": "subkey" }, "other2": { "baz": "subkey" }, "other3": { "notbaz": ["a", "b", "c"] }, "other4": { "notbaz": ["a", "b", "c"] } } }, "cases": [ { "expression": "foo.*.baz | [0]", "result": "subkey" }, { "expression": "foo.*.baz | [1]", "result": "subkey" }, { "expression": "foo.*.baz | [2]", "result": "subkey" }, { "expression": "foo.bar.* | [0]", "result": "subkey" }, { "expression": "foo.*.notbaz | [*]", "result": [["a", "b", "c"], ["a", "b", "c"]] }, { "expression": "{\"a\": foo.bar, \"b\": foo.other} | *.baz", "result": ["subkey", "subkey"] } ] }, { "given": { "foo": { "bar": { "baz": "one" }, "other": { "baz": "two" }, "other2": { "baz": "three" }, "other3": { "notbaz": ["a", "b", "c"] }, "other4": { "notbaz": ["d", "e", "f"] } } }, "cases": [ { "expression": "foo | bar", "result": {"baz": "one"} }, { "expression": "foo | bar | baz", "result": "one" }, { "expression": "foo|bar| baz", "result": "one" }, { "expression": "not_there | [0]", "result": null }, { "expression": "not_there | [0]", "result": null }, { "expression": "[foo.bar, foo.other] | [0]", "result": {"baz": "one"} }, { "expression": "{\"a\": foo.bar, \"b\": foo.other} | a", "result": {"baz": "one"} }, { "expression": "{\"a\": foo.bar, \"b\": foo.other} | b", "result": {"baz": "two"} }, { "expression": "foo.bam || foo.bar | baz", "result": "one" }, { "expression": "foo | not_there || bar", "result": {"baz": "one"} } ] }, { "given": { "foo": [{ "bar": [{ "baz": "one" }, { "baz": "two" }] }, { "bar": [{ "baz": "three" }, { "baz": "four" }] }] }, "cases": [ { "expression": "foo[*].bar[*] | [0][0]", "result": {"baz": "one"} } ] }] jsoncons-1.3.2/test/jmespath/input/compliance/slice.json000066400000000000000000000070671477700171100234250ustar00rootroot00000000000000[{ "given": { "foo": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "bar": { "baz": 1 } }, "cases": [ { "expression": "bar[0:10]", "result": null }, { "expression": "foo[0:10:1]", "result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] }, { "expression": "foo[0:10]", "result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] }, { "expression": "foo[0:10:]", "result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] }, { "expression": "foo[0::1]", "result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] }, { "expression": "foo[0::]", "result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] }, { "expression": "foo[0:]", "result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] }, { "expression": "foo[:10:1]", "result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] }, { "expression": "foo[::1]", "result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] }, { "expression": "foo[:10:]", "result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] }, { "expression": "foo[::]", "result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] }, { "expression": "foo[:]", "result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] }, { "expression": "foo[1:9]", "result": [1, 2, 3, 4, 5, 6, 7, 8] }, { "expression": "foo[0:10:2]", "result": [0, 2, 4, 6, 8] }, { "expression": "foo[5:]", "result": [5, 6, 7, 8, 9] }, { "expression": "foo[5::2]", "result": [5, 7, 9] }, { "expression": "foo[::2]", "result": [0, 2, 4, 6, 8] }, { "expression": "foo[::-1]", "result": [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] }, { "expression": "foo[1::2]", "result": [1, 3, 5, 7, 9] }, { "expression": "foo[10:0:-1]", "result": [9, 8, 7, 6, 5, 4, 3, 2, 1] }, { "expression": "foo[10:5:-1]", "result": [9, 8, 7, 6] }, { "expression": "foo[8:2:-2]", "result": [8, 6, 4] }, { "expression": "foo[0:20]", "result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] }, { "expression": "foo[10:-20:-1]", "result": [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] }, { "expression": "foo[10:-20]", "result": [] }, { "expression": "foo[-4:-1]", "result": [6, 7, 8] }, { "expression": "foo[:-5:-1]", "result": [9, 8, 7, 6] }, { "expression": "foo[8:2:0]", "error": "invalid-value" }, { "expression": "foo[8:2:0:1]", "error": "syntax" }, { "expression": "foo[8:2&]", "error": "syntax" }, { "expression": "foo[2:a:3]", "error": "syntax" } ] }, { "given": { "foo": [{"a": 1}, {"a": 2}, {"a": 3}], "bar": [{"a": {"b": 1}}, {"a": {"b": 2}}, {"a": {"b": 3}}], "baz": 50 }, "cases": [ { "expression": "foo[:2].a", "result": [1, 2] }, { "expression": "foo[:2].b", "result": [] }, { "expression": "foo[:2].a.b", "result": [] }, { "expression": "bar[::-1].a.b", "result": [3, 2, 1] }, { "expression": "bar[:2].a.b", "result": [1, 2] }, { "expression": "baz[:2].a", "result": null } ] }, { "given": [{"a": 1}, {"a": 2}, {"a": 3}], "cases": [ { "expression": "[:]", "result": [{"a": 1}, {"a": 2}, {"a": 3}] }, { "expression": "[:2].a", "result": [1, 2] }, { "expression": "[::-1].a", "result": [3, 2, 1] }, { "expression": "[:2].b", "result": [] } ] }] jsoncons-1.3.2/test/jmespath/input/compliance/syntax.json000066400000000000000000000347151477700171100236540ustar00rootroot00000000000000[{ "comment": "Dot syntax", "given": {"type": "object"}, "cases": [ { "expression": "foo.bar", "result": null }, { "expression": "foo.1", "error": "syntax" }, { "expression": "foo.-11", "error": "syntax" }, { "expression": "foo.", "error": "syntax" }, { "expression": ".foo", "error": "syntax" }, { "expression": "foo..bar", "error": "syntax" }, { "expression": "foo.bar.", "error": "syntax" }, { "expression": "foo[.]", "error": "syntax" } ] }, { "comment": "Simple token errors", "given": {"type": "object"}, "cases": [ { "expression": ".", "error": "syntax" }, { "expression": ":", "error": "syntax" }, { "expression": ",", "error": "syntax" }, { "expression": "]", "error": "syntax" }, { "expression": "[", "error": "syntax" }, { "expression": "}", "error": "syntax" }, { "expression": "{", "error": "syntax" }, { "expression": ")", "error": "syntax" }, { "expression": "(", "error": "syntax" }, { "expression": "((&", "error": "syntax" }, { "expression": "a[", "error": "syntax" }, { "expression": "a]", "error": "syntax" }, { "expression": "a][", "error": "syntax" }, { "expression": "!", "error": "syntax" }, { "expression": "@=", "error": "syntax" }, { "expression": "@``", "error": "syntax" } ] }, { "comment": "Boolean syntax errors", "given": {"type": "object"}, "cases": [ { "expression": "![!(!", "error": "syntax" } ] }, { "comment": "Paren syntax errors", "given": {}, "cases": [ { "comment": "missing closing paren", "expression": "(@", "error": "syntax" } ] }, { "comment": "Function syntax errors", "given": {}, "cases": [ { "comment": "invalid start of function", "expression": "@(foo)", "error": "syntax" }, { "comment": "function names cannot be quoted", "expression": "\"foo\"(bar)", "error": "syntax" } ] }, { "comment": "Wildcard syntax", "given": {"type": "object"}, "cases": [ { "expression": "*", "result": ["object"] }, { "expression": "*.*", "result": [] }, { "expression": "*.foo", "result": [] }, { "expression": "*[0]", "result": [] }, { "expression": ".*", "error": "syntax" }, { "expression": "*foo", "error": "syntax" }, { "expression": "*0", "error": "syntax" }, { "expression": "foo[*]bar", "error": "syntax" }, { "expression": "foo[*]*", "error": "syntax" } ] }, { "comment": "Flatten syntax", "given": {"type": "object"}, "cases": [ { "expression": "[]", "result": null } ] }, { "comment": "Simple bracket syntax", "given": {"type": "object"}, "cases": [ { "expression": "[0]", "result": null }, { "expression": "[*]", "result": null }, { "expression": "*.[0]", "error": "syntax" }, { "expression": "*.[\"0\"]", "result": [[null]] }, { "expression": "[*].bar", "result": null }, { "expression": "[*][0]", "result": null }, { "expression": "foo[#]", "error": "syntax" }, { "comment": "missing rbracket for led wildcard index", "expression": "led[*", "error": "syntax" } ] }, { "comment": "slice syntax", "given": {}, "cases": [ { "comment": "slice expected colon or rbracket", "expression": "[:@]", "error": "syntax" }, { "comment": "slice has too many colons", "expression": "[:::]", "error": "syntax" }, { "comment": "slice expected number", "expression": "[:@:]", "error": "syntax" }, { "comment": "slice expected number of colon", "expression": "[:1@]", "error": "syntax" } ] }, { "comment": "Multi-select list syntax", "given": {"type": "object"}, "cases": [ { "expression": "foo[0]", "result": null }, { "comment": "Valid multi-select of a list", "expression": "foo[0, 1]", "error": "syntax" }, { "expression": "foo.[0]", "error": "syntax" }, { "expression": "foo.[*]", "result": null }, { "comment": "Multi-select of a list with trailing comma", "expression": "foo[0, ]", "error": "syntax" }, { "comment": "Multi-select of a list with trailing comma and no close", "expression": "foo[0,", "error": "syntax" }, { "comment": "Multi-select of a list with trailing comma and no close", "expression": "foo.[a", "error": "syntax" }, { "comment": "Multi-select of a list with extra comma", "expression": "foo[0,, 1]", "error": "syntax" }, { "comment": "Multi-select of a list using an identifier index", "expression": "foo[abc]", "error": "syntax" }, { "comment": "Multi-select of a list using identifier indices", "expression": "foo[abc, def]", "error": "syntax" }, { "comment": "Multi-select of a list using an identifier index", "expression": "foo[abc, 1]", "error": "syntax" }, { "comment": "Multi-select of a list using an identifier index with trailing comma", "expression": "foo[abc, ]", "error": "syntax" }, { "comment": "Valid multi-select of a hash using an identifier index", "expression": "foo.[abc]", "result": null }, { "comment": "Valid multi-select of a hash", "expression": "foo.[abc, def]", "result": null }, { "comment": "Multi-select of a hash using a numeric index", "expression": "foo.[abc, 1]", "error": "syntax" }, { "comment": "Multi-select of a hash with a trailing comma", "expression": "foo.[abc, ]", "error": "syntax" }, { "comment": "Multi-select of a hash with extra commas", "expression": "foo.[abc,, def]", "error": "syntax" }, { "comment": "Multi-select of a hash using number indices", "expression": "foo.[0, 1]", "error": "syntax" } ] }, { "comment": "Multi-select hash syntax", "given": {"type": "object"}, "cases": [ { "comment": "No key or value", "expression": "a{}", "error": "syntax" }, { "comment": "No closing token", "expression": "a{", "error": "syntax" }, { "comment": "Not a key value pair", "expression": "a{foo}", "error": "syntax" }, { "comment": "Missing value and closing character", "expression": "a{foo:", "error": "syntax" }, { "comment": "Missing closing character", "expression": "a{foo: 0", "error": "syntax" }, { "comment": "Missing value", "expression": "a{foo:}", "error": "syntax" }, { "comment": "Trailing comma and no closing character", "expression": "a{foo: 0, ", "error": "syntax" }, { "comment": "Missing value with trailing comma", "expression": "a{foo: ,}", "error": "syntax" }, { "comment": "Accessing Array using an identifier", "expression": "a{foo: bar}", "error": "syntax" }, { "expression": "a{foo: 0}", "error": "syntax" }, { "comment": "Missing key-value pair", "expression": "a.{}", "error": "syntax" }, { "comment": "Not a key-value pair", "expression": "a.{foo}", "error": "syntax" }, { "comment": "Valid multi-select hash extraction", "expression": "a.{foo: bar}", "result": null }, { "comment": "Valid multi-select hash extraction", "expression": "a.{foo: bar, baz: bam}", "result": null }, { "comment": "Trailing comma", "expression": "a.{foo: bar, }", "error": "syntax" }, { "comment": "Missing key in second key-value pair", "expression": "a.{foo: bar, baz}", "error": "syntax" }, { "comment": "Missing value in second key-value pair", "expression": "a.{foo: bar, baz:}", "error": "syntax" }, { "comment": "Trailing comma", "expression": "a.{foo: bar, baz: bam, }", "error": "syntax" }, { "comment": "Nested multi select", "expression": "{\"\\\\\":{\" \":*}}", "result": {"\\": {" ": ["object"]}} }, { "comment": "Missing closing } after a valid nud", "expression": "{a: @", "error": "syntax" } ] }, { "comment": "Or expressions", "given": {"type": "object"}, "cases": [ { "expression": "foo || bar", "result": null }, { "expression": "foo ||", "error": "syntax" }, { "expression": "foo.|| bar", "error": "syntax" }, { "expression": " || foo", "error": "syntax" }, { "expression": "foo || || foo", "error": "syntax" }, { "expression": "foo.[a || b]", "result": null }, { "expression": "foo.[a ||]", "error": "syntax" }, { "expression": "\"foo", "error": "syntax" } ] }, { "comment": "Filter expressions", "given": {"type": "object"}, "cases": [ { "expression": "foo[?bar==`\"baz\"`]", "result": null }, { "expression": "foo[? bar == `\"baz\"` ]", "result": null }, { "expression": "foo[ ?bar==`\"baz\"`]", "error": "syntax" }, { "expression": "foo[?bar==]", "error": "syntax" }, { "expression": "foo[?==]", "error": "syntax" }, { "expression": "foo[?==bar]", "error": "syntax" }, { "expression": "foo[?bar==baz?]", "error": "syntax" }, { "expression": "foo[?a.b.c==d.e.f]", "result": null }, { "expression": "foo[?bar==`[0, 1, 2]`]", "result": null }, { "expression": "foo[?bar==`[\"a\", \"b\", \"c\"]`]", "result": null }, { "comment": "Literal char not escaped", "expression": "foo[?bar==`[\"foo`bar\"]`]", "error": "syntax" }, { "comment": "Literal char escaped", "expression": "foo[?bar==`[\"foo\\`bar\"]`]", "result": null }, { "comment": "Unknown comparator", "expression": "foo[?bar<>baz]", "error": "syntax" }, { "comment": "Unknown comparator", "expression": "foo[?bar^baz]", "error": "syntax" }, { "expression": "foo[bar==baz]", "error": "syntax" }, { "comment": "Quoted identifier in filter expression no spaces", "expression": "[?\"\\\\\">`\"foo\"`]", "result": null }, { "comment": "Quoted identifier in filter expression with spaces", "expression": "[?\"\\\\\" > `\"foo\"`]", "result": null } ] }, { "comment": "Filter expression errors", "given": {"type": "object"}, "cases": [ { "expression": "bar.`\"anything\"`", "error": "syntax" }, { "expression": "bar.baz.noexists.`\"literal\"`", "error": "syntax" }, { "comment": "Literal wildcard projection", "expression": "foo[*].`\"literal\"`", "error": "syntax" }, { "expression": "foo[*].name.`\"literal\"`", "error": "syntax" }, { "expression": "foo[].name.`\"literal\"`", "error": "syntax" }, { "expression": "foo[].name.`\"literal\"`.`\"subliteral\"`", "error": "syntax" }, { "comment": "Projecting a literal onto an empty list", "expression": "foo[*].name.noexist.`\"literal\"`", "error": "syntax" }, { "expression": "foo[].name.noexist.`\"literal\"`", "error": "syntax" }, { "expression": "twolen[*].`\"foo\"`", "error": "syntax" }, { "comment": "Two level projection of a literal", "expression": "twolen[*].threelen[*].`\"bar\"`", "error": "syntax" }, { "comment": "Two level flattened projection of a literal", "expression": "twolen[].threelen[].`\"bar\"`", "error": "syntax" }, { "comment": "expects closing ]", "expression": "foo[? @ | @", "error": "syntax" } ] }, { "comment": "Identifiers", "given": {"type": "object"}, "cases": [ { "expression": "foo", "result": null }, { "expression": "\"foo\"", "result": null }, { "expression": "\"\\\\\"", "result": null }, { "expression": "\"\\u\"", "error": "syntax" } ] }, { "comment": "Combined syntax", "given": [], "cases": [ { "expression": "*||*|*|*", "result": null }, { "expression": "*[]||[*]", "result": [] }, { "expression": "[*.*]", "result": [null] } ] } ] jsoncons-1.3.2/test/jmespath/input/compliance/test.json000066400000000000000000000003401477700171100232700ustar00rootroot00000000000000[ { "given": {"reservations": [ {"instances": [{"foo": 1}, {"foo": 2}]} ]}, "cases": [ { "expression": "reservations[].instances[].foo", "result": [1, 2] } ] } ] jsoncons-1.3.2/test/jmespath/input/compliance/unicode.json000066400000000000000000000014731477700171100237470ustar00rootroot00000000000000[ { "given": {"foo": [{"✓": "✓"}, {"✓": "✗"}]}, "cases": [ { "expression": "foo[].\"✓\"", "result": ["✓", "✗"] } ] }, { "given": {"☯": true}, "cases": [ { "expression": "\"☯\"", "result": true } ] }, { "given": {"♪♫•*¨*•.¸¸❤¸¸.•*¨*•♫♪": true}, "cases": [ { "expression": "\"♪♫•*¨*•.¸¸❤¸¸.•*¨*•♫♪\"", "result": true } ] }, { "given": {"☃": true}, "cases": [ { "expression": "\"☃\"", "result": true } ] } ] jsoncons-1.3.2/test/jmespath/input/compliance/wildcard.json000066400000000000000000000243311477700171100241100ustar00rootroot00000000000000[{ "given": { "foo": { "bar": { "baz": "val" }, "other": { "baz": "val" }, "other2": { "baz": "val" }, "other3": { "notbaz": ["a", "b", "c"] }, "other4": { "notbaz": ["a", "b", "c"] }, "other5": { "other": { "a": 1, "b": 1, "c": 1 } } } }, "cases": [ { "expression": "foo.*.baz", "result": ["val", "val", "val"] }, { "expression": "foo.bar.*", "result": ["val"] }, { "expression": "foo.*.notbaz", "result": [["a", "b", "c"], ["a", "b", "c"]] }, { "expression": "foo.*.notbaz[0]", "result": ["a", "a"] }, { "expression": "foo.*.notbaz[-1]", "result": ["c", "c"] } ] }, { "given": { "foo": { "first-1": { "second-1": "val" }, "first-2": { "second-1": "val" }, "first-3": { "second-1": "val" } } }, "cases": [ { "expression": "foo.*", "result": [{"second-1": "val"}, {"second-1": "val"}, {"second-1": "val"}] }, { "expression": "foo.*.*", "result": [["val"], ["val"], ["val"]] }, { "expression": "foo.*.*.*", "result": [[], [], []] }, { "expression": "foo.*.*.*.*", "result": [[], [], []] } ] }, { "given": { "foo": { "bar": "one" }, "other": { "bar": "one" }, "nomatch": { "notbar": "three" } }, "cases": [ { "expression": "*.bar", "result": ["one", "one"] } ] }, { "given": { "top1": { "sub1": {"foo": "one"} }, "top2": { "sub1": {"foo": "one"} } }, "cases": [ { "expression": "*", "result": [{"sub1": {"foo": "one"}}, {"sub1": {"foo": "one"}}] }, { "expression": "*.sub1", "result": [{"foo": "one"}, {"foo": "one"}] }, { "expression": "*.*", "result": [[{"foo": "one"}], [{"foo": "one"}]] }, { "expression": "*.*.foo[]", "result": ["one", "one"] }, { "expression": "*.sub1.foo", "result": ["one", "one"] } ] }, { "given": {"foo": [{"bar": "one"}, {"bar": "two"}, {"bar": "three"}, {"notbar": "four"}]}, "cases": [ { "expression": "foo[*].bar", "result": ["one", "two", "three"] }, { "expression": "foo[*].notbar", "result": ["four"] } ] }, { "given": [{"bar": "one"}, {"bar": "two"}, {"bar": "three"}, {"notbar": "four"}], "cases": [ { "expression": "[*]", "result": [{"bar": "one"}, {"bar": "two"}, {"bar": "three"}, {"notbar": "four"}] }, { "expression": "[*].bar", "result": ["one", "two", "three"] }, { "expression": "[*].notbar", "result": ["four"] } ] }, { "given": { "foo": { "bar": [ {"baz": ["one", "two", "three"]}, {"baz": ["four", "five", "six"]}, {"baz": ["seven", "eight", "nine"]} ] } }, "cases": [ { "expression": "foo.bar[*].baz", "result": [["one", "two", "three"], ["four", "five", "six"], ["seven", "eight", "nine"]] }, { "expression": "foo.bar[*].baz[0]", "result": ["one", "four", "seven"] }, { "expression": "foo.bar[*].baz[1]", "result": ["two", "five", "eight"] }, { "expression": "foo.bar[*].baz[2]", "result": ["three", "six", "nine"] }, { "expression": "foo.bar[*].baz[3]", "result": [] } ] }, { "given": { "foo": { "bar": [["one", "two"], ["three", "four"]] } }, "cases": [ { "expression": "foo.bar[*]", "result": [["one", "two"], ["three", "four"]] }, { "expression": "foo.bar[0]", "result": ["one", "two"] }, { "expression": "foo.bar[0][0]", "result": "one" }, { "expression": "foo.bar[0][0][0]", "result": null }, { "expression": "foo.bar[0][0][0][0]", "result": null }, { "expression": "foo[0][0]", "result": null } ] }, { "given": { "foo": [ {"bar": [{"kind": "basic"}, {"kind": "intermediate"}]}, {"bar": [{"kind": "advanced"}, {"kind": "expert"}]}, {"bar": "string"} ] }, "cases": [ { "expression": "foo[*].bar[*].kind", "result": [["basic", "intermediate"], ["advanced", "expert"]] }, { "expression": "foo[*].bar[0].kind", "result": ["basic", "advanced"] } ] }, { "given": { "foo": [ {"bar": {"kind": "basic"}}, {"bar": {"kind": "intermediate"}}, {"bar": {"kind": "advanced"}}, {"bar": {"kind": "expert"}}, {"bar": "string"} ] }, "cases": [ { "expression": "foo[*].bar.kind", "result": ["basic", "intermediate", "advanced", "expert"] } ] }, { "given": { "foo": [{"bar": ["one", "two"]}, {"bar": ["three", "four"]}, {"bar": ["five"]}] }, "cases": [ { "expression": "foo[*].bar[0]", "result": ["one", "three", "five"] }, { "expression": "foo[*].bar[1]", "result": ["two", "four"] }, { "expression": "foo[*].bar[2]", "result": [] } ] }, { "given": { "foo": [{"bar": []}, {"bar": []}, {"bar": []}] }, "cases": [ { "expression": "foo[*].bar[0]", "result": [] } ] }, { "given": { "foo": [["one", "two"], ["three", "four"], ["five"]] }, "cases": [ { "expression": "foo[*][0]", "result": ["one", "three", "five"] }, { "expression": "foo[*][1]", "result": ["two", "four"] } ] }, { "given": { "foo": [ [ ["one", "two"], ["three", "four"] ], [ ["five", "six"], ["seven", "eight"] ], [ ["nine"], ["ten"] ] ] }, "cases": [ { "expression": "foo[*][0]", "result": [["one", "two"], ["five", "six"], ["nine"]] }, { "expression": "foo[*][1]", "result": [["three", "four"], ["seven", "eight"], ["ten"]] }, { "expression": "foo[*][0][0]", "result": ["one", "five", "nine"] }, { "expression": "foo[*][1][0]", "result": ["three", "seven", "ten"] }, { "expression": "foo[*][0][1]", "result": ["two", "six"] }, { "expression": "foo[*][1][1]", "result": ["four", "eight"] }, { "expression": "foo[*][2]", "result": [] }, { "expression": "foo[*][2][2]", "result": [] }, { "expression": "bar[*]", "result": null }, { "expression": "bar[*].baz[*]", "result": null } ] }, { "given": { "string": "string", "hash": {"foo": "bar", "bar": "baz"}, "number": 23, "nullvalue": null }, "cases": [ { "expression": "string[*]", "result": null }, { "expression": "hash[*]", "result": null }, { "expression": "number[*]", "result": null }, { "expression": "nullvalue[*]", "result": null }, { "expression": "string[*].foo", "result": null }, { "expression": "hash[*].foo", "result": null }, { "expression": "number[*].foo", "result": null }, { "expression": "nullvalue[*].foo", "result": null }, { "expression": "nullvalue[*].foo[*].bar", "result": null } ] }, { "given": { "string": "string", "hash": {"foo": "val", "bar": "val"}, "number": 23, "array": [1, 2, 3], "nullvalue": null }, "cases": [ { "expression": "string.*", "result": null }, { "expression": "hash.*", "result": ["val", "val"] }, { "expression": "number.*", "result": null }, { "expression": "array.*", "result": null }, { "expression": "nullvalue.*", "result": null } ] }, { "given": { "a": [0, 1, 2], "b": [0, 1, 2] }, "cases": [ { "expression": "*[0]", "result": [0, 0] } ] } ] jsoncons-1.3.2/test/jmespath/input/examples/000077500000000000000000000000001477700171100211255ustar00rootroot00000000000000jsoncons-1.3.2/test/jmespath/input/examples/jmespath-examples.json000066400000000000000000000265671477700171100254670ustar00rootroot00000000000000[ // From jmespath.org tutorial { "given" : {"a": "foo", "b": "bar", "c": "baz"}, "cases" : [ { "comment" : "Select a value with an identifier", "expression" : "a", "result" : "foo" } ] }, { "given" : {"a": {"b": {"c": {"d": "value"}}}}, "cases" : [ { "comment" : "Select nested values in json object with subexpression", "expression" : "a.b.c.d", "result" : "value" } ] }, { "given" : {"a": {"b": {"c": {"d": "value"}}}}, "cases" : [ { "comment" : "Select nested values in json object with subexpression, key does not exist", "expression" : "b.c.d.e", "result" : null } ] }, { "given" : ["a", "b", "c", "d", "e", "f"], "cases" : [ { "comment" : "Index expression", "expression" : "[1]", "result" : "b" } ] }, { "given" : ["a", "b", "c", "d", "e", "f"], "cases" : [ { "comment" : "Index expression larger than list", "expression" : "[6]", "result" : null } ] }, { "given" : ["a", "b", "c", "d", "e", "f"], "cases" : [ { "comment" : "Negative index", "expression" : "[-2]", "result" : "e" } ] }, { "given" : {"a": {"b": {"c": [{"d": [0, [1, 2]]},{"d": [3, 4]}]}}}, "cases" : [ { "comment" : "Combine identifiers, sub expressions, and index expressions", "expression" : "a.b.c[0].d[1][0]", "result" : 1 } ] }, { "given" : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "cases" : [ { "comment" : "Slicing", "expression" : "[0:5]", "result" : [0,1,2,3,4] } ] }, { "given" : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "cases" : [ { "comment" : "Slicing", "expression" : "[5:10]", "result" : [5,6,7,8,9] } ] }, { "given" : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "cases" : [ { "comment" : "Slicing - omit start value", "expression" : "[:5]", "result" : [0,1,2,3,4] } ] }, { "given" : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "cases" : [ { "comment" : "Slicing - omit end value", "expression" : "[5:]", "result" : [5,6,7,8,9] } ] }, { "given" : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "cases" : [ { "comment" : "Slicing - select only even elements", "expression" : "[::2]", "result" : [0,2,4,6,8] } ] }, { "given" : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "cases" : [ { "comment" : "Slicing - create in reverse order", "expression" : "[::-1]", "result" : [9,8,7,6,5,4,3,2,1,0] } ] }, { "given" : {"people": [{"first": "James", "last": "d"},{"first": "Jacob", "last": "e"},{"first": "Jayden", "last": "f"},{"missing": "different"}],"foo": {"bar": "baz"}}, "cases" : [ { "comment" : "List Projection", "expression" : "people[*].first", "result" : ["James","Jacob","Jayden"] } ] }, { "given" : {"people": [{"first": "James", "last": "d"},{"first": "Jacob", "last": "e"},{"first": "Jayden", "last": "f"},{"missing": "different"}],"foo": {"bar": "baz"}}, "cases" : [ { "comment" : "Slice Projection", "expression" : "people[:2].first", "result" : ["James","Jacob"] } ] }, { "given" : {"ops": {"functionA": {"numArgs": 2},"functionB": {"numArgs": 3},"functionC": {"variadic": true}}}, "cases" : [ { "comment" : "Object Projection", "expression" : "ops.*.numArgs", "result" : [2,3] } ] }, { "given" : {"reservations": [{"instances": [{"state": "running"},{"state": "stopped"}]},{"instances": [{"state": "terminated"},{"state": "runnning"}]}]}, "cases" : [ { "comment" : "More than one List Projection", "expression" : "reservations[*].instances[*].state", "result" : [["running","stopped"],["terminated","runnning"]] } ] }, { "given" : {"reservations": [{"instances": [{"state": "running"},{"state": "stopped"}]},{"instances": [{"state": "terminated"},{"state": "runnning"}]}]}, "cases" : [ { "comment" : "Flatten Projection using []", "expression" : "reservations[].instances[].state", "result" : ["running","stopped","terminated","runnning"] } ] }, { "given" : [[0, 1],2,[3],4,[5, [6, 7]]], "cases" : [ { "comment" : "Flatten Projection using [] to flatten a list", "expression" : "[]", "result" : [0,1,2,3,4,5,[6,7]] } ] }, { "given" : {"machines": [{"name": "a", "state": "running"},{"name": "b", "state": "stopped"},{"name": "b", "state": "running"}]}, "cases" : [ { "comment" :"Comparison ==", "expression" : "machines[?state=='running'].name", "result" : ["a","b"] } ] }, { "given" : {"people": [{"first": "James", "last": "d"},{"first": "Jacob", "last": "e"},{"first": "Jayden", "last": "f"},{"missing": "different"}],"foo": {"bar": "baz"}}, "cases" : [ { "comment" : "Pipe", "expression" : "people[*].first | [0]", "result" : "James" } ] }, { "given" : {"people": [{"name": "a","state": {"name": "up"}},{"name": "b","state": {"name": "down"}},{"name": "c","state": {"name": "up"}}]}, "cases" : [ { "comment" : "Multiselect List", "expression" : "people[].[name,state.name]", "result" : [["a","up"],["b","down"],["c","up"]] } ] }, { "given" : {"people": [{"name": "a","state": {"name": "up"}},{"name": "b","state": {"name": "down"}},{"name": "c","state": {"name": "up"}}]}, "cases" : [ { "comment" : "Multi select hash", "expression" : "people[].{Name: name, State: state.name}", "result" : [{"Name": "a","State": "up"},{"Name": "b","State": "down"},{"Name": "c","State": "up"}] } ] // From jmespath.org examples }, { "given" : {"people": [{"age": 20,"other": "foo","name": "Bob"},{"age": 25,"other": "bar","name": "Fred"},{"age": 30,"other": "baz","name": "George"}]}, "cases" : [ { "comment" : "Filters and Multiselect Lists", "expression" : "people[?age > `20`].[name, age]", "result" : [["Fred",25],["George",30]] } ] }, { "given" : {"people": [{"age": 20,"other": "foo","name": "Bob"},{"age": 25,"other": "bar","name": "Fred"},{"age": 30,"other": "baz","name": "George"}]}, "cases" : [ { "comment" : "Filters and Multiselect Hashes", "expression" : "people[?age > `20`].{name: name, age: age}", "result" : [{"name": "Fred","age": 25},{"name": "George","age": 30}] } ] }, { "given" : {"people": [{"age": 20,"tags": ["a", "b", "c"],"name": "Bob"},{"age": 25,"tags": ["d", "e", "f"],"name": "Fred"},{"age": 30,"tags": ["g", "h", "i"],"name": "George"}]}, "cases" : [ { "comment" : "Filters and Multiselect Hashes", "expression" : "people[*].{name: name, tags: tags[0]}", "result" : [{"name": "Bob","tags": "a"},{"name": "Fred","tags": "d"},{"name": "George","tags": "g"}] } ] }, { "given" : {"reservations": [{"instances": [{"type": "small","state": {"name": "running"},"tags": [{"Key": "Name","Values": ["Web"]},{"Key": "version","Values": ["1"]}]},{"type": "large","state": {"name": "stopped"},"tags": [{"Key": "Name","Values": ["Web"]},{"Key": "version","Values": ["1"]}]}]}, {"instances": [{"type": "medium","state": {"name": "terminated"},"tags": [{"Key": "Name","Values": ["Web"]},{"Key": "version","Values": ["1"]}]},{"type": "xlarge","state": {"name": "running"},"tags": [{"Key": "Name","Values": ["DB"]},{"Key": "version","Values": ["1"]}]}]}]}, "cases" : [ { "comment" : "Working with Nested Data", "expression" : "reservations[].instances[].[tags[?Key=='Name'].Values[] | [0], type, state.name]", "result" : [["Web","small","running"],["Web","large","stopped"],["Web","medium","terminated"],["DB","xlarge","running"]] } ] }, { "given" : {"people": [{"general": {"id": 100,"age": 20,"other": "foo","name": "Bob"},"history": {"first_login": "2014-01-01","last_login": "2014-01-02"}},{"general": {"id": 101,"age": 30,"other": "bar","name": "Bill"},"history": {"first_login": "2014-05-01","last_login": "2014-05-02"}}]}, "cases" : [ { "comment" : "Filtering and Selecting Nested Data", "expression" : "people[?general.id==`100`].general | [0]", "result" : {"id": 100,"age": 20,"other": "foo","name": "Bob"} } ] }, { "given" : {"Contents": [{"Date": "2014-12-21T05:18:08.000Z","Key": "logs/bb","Size": 303},{"Date": "2014-12-20T05:19:10.000Z","Key": "logs/aa","Size": 308},{"Date": "2014-12-20T05:19:12.000Z","Key": "logs/qux","Size": 297},{"Date": "2014-11-20T05:22:23.000Z","Key": "logs/baz","Size": 329},{"Date": "2014-12-20T05:25:24.000Z","Key": "logs/bar","Size": 604},{"Date": "2014-12-20T05:27:12.000Z","Key": "logs/foo","Size": 647}]}, "cases" : [ { "comment" : "Using Functions", "expression" : "sort_by(Contents, &Date)[*].{Key: Key, Size: Size}", "result" : [{"Key": "logs/baz","Size": 329},{"Key": "logs/aa","Size": 308},{"Key": "logs/qux","Size": 297},{"Key": "logs/bar","Size": 604},{"Key": "logs/foo","Size": 647},{"Key": "logs/bb","Size": 303}] } ] }, { "given" : {"locations": [{"name": "Seattle", "state": "WA"},{"name": "New York", "state": "NY"},{"name": "Bellevue", "state": "WA"},{"name": "Olympia", "state": "WA"}]}, "cases" : [ { "comment" : "Pipe", "expression" : "locations[?state == 'WA'].name | sort(@)[-2:] | {WashingtonCities: join(', ', @)}", "result" : {"WashingtonCities": "Olympia, Seattle"} } ] } ] jsoncons-1.3.2/test/jmespath/input/issues/000077500000000000000000000000001477700171100206225ustar00rootroot00000000000000jsoncons-1.3.2/test/jmespath/input/issues/issues.json000066400000000000000000000014121477700171100230260ustar00rootroot00000000000000[ // From jmespath.org tutorial { "given" : [{ "name" : "foo", "datasets" : [ { "name" : "bar", "tissues" : [ { "label" : "baz" }] } ] }, { "name" : "foo1", "datasets" : [ { "name" : "bar1", "tissues" : [ { "label" : "baz1" }] } ] }], "cases" : [ { "comment" : "Select a value with an identifier", "expression" : "[].{collection: name,dataset: datasets[].name,tissue: datasets[].tissue[*].label}", "result" : [ { "collection": "foo", "dataset": ["bar"], "tissue": [] }, { "collection": "foo1", "dataset": ["bar1"], "tissue": [] } ] } ] } ] jsoncons-1.3.2/test/jmespath/input/test.json000066400000000000000000000000051477700171100211540ustar00rootroot00000000000000[ ] jsoncons-1.3.2/test/jmespath/src/000077500000000000000000000000001477700171100167375ustar00rootroot00000000000000jsoncons-1.3.2/test/jmespath/src/jmespath_custom_function_tests.cpp000066400000000000000000000172761477700171100260140ustar00rootroot00000000000000// Copyright 2013-2024 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include #include #include // std::unordered_set #include namespace jmespath = jsoncons::jmespath; // When adding custom functions, they are generally placed in their own project's source code and namespace. namespace myspace { template class my_custom_functions : public jmespath::custom_functions { using reference = const Json&; using pointer = const Json*; static thread_local size_t current_index; public: my_custom_functions() { this->register_function("current_date_time", // function name 0, // number of arguments [](const jsoncons::span>, jmespath::eval_context&, std::error_code&) -> Json { auto now = std::chrono::system_clock::now(); auto milliseconds = std::chrono::duration_cast(now.time_since_epoch()); return Json{milliseconds.count()}; } ); this->register_function("current_index", // function name 0, // number of arguments [](const jsoncons::span>, jmespath::eval_context&, std::error_code&) -> Json { return Json{current_index}; } ); this->register_function("generate_array", // function name 4, // number of arguments [](const jsoncons::span> params, jmespath::eval_context& context, std::error_code& ec) -> Json { JSONCONS_ASSERT(4 == params.size()); if (!(params[0].is_value() && params[2].is_expression())) { ec = jmespath::jmespath_errc::invalid_argument; return context.null_value(); } reference ctx = params[0].value(); reference countValue = get_value(ctx, context, params[1]); const auto& expr = params[2].expression(); const auto& argDefault = params[3]; if (!countValue.is_number()) { ec = jmespath::jmespath_errc::invalid_argument; return context.null_value(); } Json result{jsoncons::json_array_arg}; std::size_t count = countValue.template as(); for (size_t i = 0; i < count; i++) { current_index = i; std::error_code ec2; reference ele = expr.evaluate(ctx, context, ec2); if (ele.is_null()) { auto defaultVal = get_value(ctx, context, argDefault); result.emplace_back(std::move(defaultVal)); } else { result.emplace_back(ele); } } current_index = 0; return result; } ); this->register_function("add", // function name 2, // number of arguments [](jsoncons::span> params, jmespath::eval_context& context, std::error_code& ec) -> Json { JSONCONS_ASSERT(2 == params.size()); if (!(params[0].is_value() && params[1].is_value())) { ec = jmespath::jmespath_errc::invalid_argument; return context.null_value(); } reference arg0 = params[0].value(); reference arg1 = params[1].value(); if (!(arg0.is_number() && arg1.is_number())) { ec = jmespath::jmespath_errc::invalid_argument; return context.null_value(); } if (arg0.template is() && arg1.template is()) { int64_t v = arg0.template as() + arg1.template as(); return Json(v); } else { double v = arg0.template as() + arg1.template as(); return Json(v); } } ); } static reference get_value(reference ctx, jmespath::eval_context& context, const jmespath::parameter& param) { if (param.is_expression()) { const auto& expr = param.expression(); std::error_code ec; return expr.evaluate(ctx, context, ec); } else { return param.value(); } } }; template thread_local size_t my_custom_functions::current_index = 0; } // namespace myspace using json = jsoncons::json; TEST_CASE("jmespath custom function test") { SECTION("test 1") { std::string jtext = R"( { "devices": [ { "position": 1, "id": "id-xxx", "state": 1 }, { "position": 5, "id": "id-yyy", "state": 1 }, { "position": 9, "id": "id-mmm", "state": 2 } ] } )"; auto expected = json::parse(R"( [ { "id": "id-xxx", "position": 1, "state": 1 }, { "id": "", "position": 2, "state": 0 }, { "id": "", "position": 3, "state": 0 }, { "id": "", "position": 4, "state": 0 }, { "id": "id-yyy", "position": 5, "state": 1 }, { "id": "", "position": 6, "state": 0 }, { "id": "", "position": 7, "state": 0 }, { "id": "", "position": 8, "state": 0 }, { "id": "id-mmm", "position": 9, "state": 2 }, { "id": "", "position": 10, "state": 0 }, { "id": "", "position": 11, "state": 0 }, { "id": "", "position": 12, "state": 0 }, { "id": "", "position": 13, "state": 0 }, { "id": "", "position": 14, "state": 0 }, { "id": "", "position": 15, "state": 0 }, { "id": "", "position": 16, "state": 0 } ] )"); auto expr = jmespath::make_expression("generate_array(devices, `16`, &[?position==add(current_index(), `1`)] | [0], &{id: '', state: `0`, position: add(current_index(), `1`)})", myspace::my_custom_functions{}); auto doc = json::parse(jtext); auto result = expr.evaluate(doc); CHECK(expected == result); } } jsoncons-1.3.2/test/jmespath/src/jmespath_expression_tests.cpp000066400000000000000000000104431477700171100247610ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include using jsoncons::json; using jsoncons::ojson; namespace jmespath = jsoncons::jmespath; TEST_CASE("jmespath_expression tests") { SECTION("Test 1") { std::string jtext = R"( { "people": [ { "age": 20, "other": "foo", "name": "Bob" }, { "age": 25, "other": "bar", "name": "Fred" }, { "age": 30, "other": "baz", "name": "George" } ] } )"; auto expr = jmespath::make_expression("sum(people[].age)"); json doc = json::parse(jtext); json result = expr.evaluate(doc); CHECK(result == json(75.0)); } SECTION("Test 2") { std::string jtext = R"( { "group": { "value": 1 }, "array": [ {"value": 2} ] } )"; json doc = json::parse(jtext); auto expr1 = jmespath::make_expression("group.value"); json result1 = expr1.evaluate(doc); CHECK(json(1) == result1); auto expr2 = jmespath::make_expression("array[0].value"); json result2 = expr2.evaluate(doc); CHECK(json(2) == result2); auto expr3 = jmespath::make_expression("nullable.value"); json result3 = expr3.evaluate(doc); CHECK(result3 == json::null()); } } TEST_CASE("jmespath issue") { SECTION("issue 1") { std::string jtext = R"( { "locations": [ {"name": "Seattle", "state": "WA"}, {"name": "New York", "state": "NY"}, {"name": "Bellevue", "state": "WA"}, {"name": "Olympia", "state": "WA"} ] } )"; std::string expr = R"( { name: locations[].name, state: locations[].state } )"; auto doc = ojson::parse(jtext); auto result = jmespath::search(doc, expr); //std::cout << pretty_print(result) << "\n\n"; } SECTION("parentheses issue") { auto doc = jsoncons::json::parse(R"( {"foo" : [[0, 1], [2, 3], [4, 5]]} )"); auto expected = jsoncons::json::parse(R"([0, 1])"); std::string query = R"((foo[*])[0])"; auto expr = jmespath::make_expression(query); jsoncons::json result = expr.evaluate(doc); //std::cout << pretty_print(result) << "\n"; CHECK(expected == result); } } TEST_CASE("jmespath issue 605") { SECTION("function with 1 arg") { std::string query = R"( to_array("gw:GWallInfo"."gw:DocumentStatistics"."gw:ContentGroups"."gw:ContentGroup" || "gw:DocumentStatistics"."gw:ContentGroups"."gw:ContentGroup") )"; auto expr = jsoncons::jmespath::make_expression(query); json j; j["gw:DocumentStatistics"]["gw:ContentGroups"]["gw:ContentGroup"] = 9; auto result = expr.evaluate(j); REQUIRE(result.is_array()); REQUIRE_FALSE(result.empty()); CHECK(9 == result[0]); //std::cout << pretty_print(result) << "\n\n"; } SECTION("function with 2 args") { std::string query = R"(starts_with(B || A,null || 'a'))"; auto expr = jsoncons::jmespath::make_expression(query); json j; j["A"] = "ab"; //auto result = jsoncons::jmespath::search(j, expr); auto result = expr.evaluate(j); //std::cout << result << "\n"; CHECK(result.as()); } SECTION("function with 2 args (2)") { std::string query = R"(starts_with(A || B,null || 'a'))"; auto expr = jsoncons::jmespath::make_expression(query); json j; j["A"] = "ab"; //auto result = jsoncons::jmespath::search(j, expr); auto result = expr.evaluate(j); //std::cout << result << "\n"; CHECK(result.as()); } } jsoncons-1.3.2/test/jmespath/src/jmespath_let_tests.cpp000066400000000000000000000215071477700171100233510ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include namespace jmespath = jsoncons::jmespath; TEST_CASE("jmespath let tests") { SECTION("Test 1") { auto doc = jsoncons::json::parse(R"({"foo": "bar"})"); auto expected = jsoncons::json::parse(R"("bar")"); std::string query = R"(let $foo = foo in $foo)"; auto expr = jmespath::make_expression(query); jsoncons::json result = expr.evaluate(doc); CHECK(expected == result); } SECTION("Test 2") { auto doc = jsoncons::json::parse(R"({"foo": {"bar": "baz"}})"); auto expected = jsoncons::json::parse(R"("baz")"); std::string query = R"(let $foo = foo.bar in $foo)"; auto expr = jmespath::make_expression(query); jsoncons::json result = expr.evaluate(doc); CHECK(expected == result); } SECTION("Test 3") { auto doc = jsoncons::json::parse(R"({"foo": "bar"})"); auto expected = jsoncons::json::parse(R"(["bar", "bar"])"); std::string query = R"(let $foo = foo in [$foo, $foo])"; auto expr = jmespath::make_expression(query); jsoncons::json result = expr.evaluate(doc); CHECK(expected == result); } SECTION("Nested bindings") { auto doc = jsoncons::json::parse(R"({"a": "topval", "b": [{"a": "inner1"}, {"a": "inner2"}]})"); auto expected = jsoncons::json::parse(R"( [["inner1", "topval", "shadow"], ["inner2", "topval", "shadow"]])"); std::string query = R"(let $a = a in b[*].[a, $a, let $a = 'shadow' in $a])"; auto expr = jmespath::make_expression(query); jsoncons::json result = expr.evaluate(doc); CHECK(expected == result); } } TEST_CASE("jmespath let as valid identifiers") { auto doc = jsoncons::json::parse(R"( { "let" : { "let" : "let-val", "in" : "in-val" } } )"); SECTION("test 1") { auto expected = jsoncons::json::parse(R"( { "in": { "in": "in-val", "let": "let-val" }, "let": { "in": "in-val", "let": "let-val" } } )"); std::string query = R"(let $let = let in {let: let, in: $let})"; auto expr = jmespath::make_expression(query); jsoncons::json result = expr.evaluate(doc); //std::cout << pretty_print(result) << "\n"; CHECK(expected == result); } SECTION("test 2") { auto expected = jsoncons::json::parse(R"( { "in": "let", "let": { "in": "in-val", "let": "let-val" } } )"); std::string query = R"(let $let = 'let' in { let: let, in: $let })"; auto expr = jmespath::make_expression(query); jsoncons::json result = expr.evaluate(doc); //std::cout << pretty_print(result) << "\n"; CHECK(expected == result); } SECTION("test 3") { auto expected = jsoncons::json::parse(R"( { "in": "let", "let": "let" } )"); std::string query = R"(let $let = 'let' in { let: 'let', in: $let })"; auto expr = jmespath::make_expression(query); jsoncons::json result = expr.evaluate(doc); //std::cout << pretty_print(result) << "\n"; CHECK(expected == result); } } TEST_CASE("jmespath let projection stop") { auto doc = jsoncons::json::parse(R"( {"foo" : [[0, 1], [2, 3], [4, 5]]} )"); SECTION("test 1") { auto expected = jsoncons::json::parse(R"( [0, 1] )"); std::string query = R"(let $foo = foo[*] in $foo[0])"; auto expr = jmespath::make_expression(query); jsoncons::json result = expr.evaluate(doc); //std::cout << pretty_print(result) << "\n"; CHECK(expected == result); } } TEST_CASE("jmespath let motivation section") { SECTION("test 1") { auto doc = jsoncons::json::parse(R"( [ {"home_state": "WA", "states": [ {"name": "WA", "cities": ["Seattle", "Bellevue", "Olympia"]}, {"name": "CA", "cities": ["Los Angeles", "San Francisco"]}, {"name": "NY", "cities": ["New York City", "Albany"]} ] }, {"home_state": "NY", "states": [ {"name": "WA", "cities": ["Seattle", "Bellevue", "Olympia"]}, {"name": "CA", "cities": ["Los Angeles", "San Francisco"]}, {"name": "NY", "cities": ["New York City", "Albany"]} ] } ] )"); auto expected = jsoncons::json::parse(R"( [ [ "Seattle", "Bellevue", "Olympia" ], [ "New York City", "Albany" ] ] )"); std::string query = R"([*].[let $home_state = home_state in states[? name == $home_state].cities[]][])"; auto expr = jmespath::make_expression(query); jsoncons::json result = expr.evaluate(doc); //std::cout << pretty_print(result) << "\n"; CHECK(expected == result); } SECTION("test 2") { auto doc = jsoncons::json::parse(R"( {"imageDetails": [ { "repositoryName": "org/first-repo", "imageTags": ["latest", "v1.0", "v1.2"], "imageDigest": "sha256:abcd" }, { "repositoryName": "org/second-repo", "imageTags": ["v2.0", "v2.2"], "imageDigest": "sha256:efgh" } ]} )"); auto expected = jsoncons::json::parse(R"( [ ["latest","sha256:abcd","org/first-repo"], ["v1.0","sha256:abcd","org/first-repo"], ["v1.2","sha256:abcd","org/first-repo"], ["v2.0","sha256:efgh","org/second-repo"], ["v2.2","sha256:efgh","org/second-repo"] ] )"); std::string query = R"(imageDetails[].[ let $repo = repositoryName, $digest = imageDigest in imageTags[].[@, $digest, $repo] ][][])"; auto expr = jmespath::make_expression(query); jsoncons::json result = expr.evaluate(doc); //std::cout << pretty_print(result) << "\n"; CHECK(expected == result); } } TEST_CASE("jmespath let errors") { jsoncons::json doc{jsoncons::json_object_arg}; SECTION("test 1") { std::error_code ec; std::string query = R"($noexist)"; auto expr = jmespath::make_expression(query, ec); CHECK_FALSE(ec); expr.evaluate(doc, ec); CHECK(ec == jmespath::jmespath_errc::undefined_variable); } SECTION("test 2") { std::error_code ec; std::string query = R"([let $scope = 'foo' in [$scope], $scope])"; auto expr = jmespath::make_expression(query, ec); CHECK_FALSE(ec); expr.evaluate(doc, ec); CHECK(ec == jmespath::jmespath_errc::undefined_variable); } SECTION("test 3") { std::error_code ec; std::string query = R"(foo.$bar)"; auto expr = jmespath::make_expression(query, ec); CHECK(ec == jmespath::jmespath_errc::expected_identifier); } SECTION("test 4") { std::error_code ec; std::string query = R"($noexist)"; auto expr = jmespath::make_expression(query, ec); CHECK_FALSE(ec); auto expected = jsoncons::json::parse(R"("foo")"); auto result = expr.evaluate(doc, {{"noexist", "foo"}}, ec); CHECK_FALSE(ec); CHECK(expected == result); //std::cout << result << "\n"; } SECTION("test 5") { std::error_code ec; std::string query = R"([let $scope = 'foo' in [$scope], $scope])"; auto expr = jmespath::make_expression(query, ec); CHECK_FALSE(ec); auto expected = jsoncons::json::parse(R"([["foo"],"foo"])"); auto result = expr.evaluate(doc, { {"scope", "foo"} }, ec); CHECK_FALSE(ec); CHECK(expected == result); //std::cout << result << "\n"; } } TEST_CASE("jmespath let params") { SECTION("test 1") { auto doc = jsoncons::json::parse(R"( { "results": [ { "name": "test1", "uuid": "33bb9554-c616-42e6-a9c6-88d3bba4221c" }, { "name": "test2", "uuid": "acde070d-8c4c-4f0d-9d8a-162843c10333" } ] } )"); auto expr = jmespath::make_expression("results[*].[name, uuid, $hostname]"); auto result = expr.evaluate(doc, { {"hostname", "localhost"} }); auto options = jsoncons::json_options{} .array_array_line_splits(jsoncons::line_split_kind::same_line); std::cout << pretty_print(result) << "\n"; } } jsoncons-1.3.2/test/jmespath/src/jmespath_tests.cpp000066400000000000000000000111111477700171100224730ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include #include // std::unordered_set #include #include using namespace jsoncons; void jmespath_tests(const std::string& fpath) { std::fstream is(fpath); REQUIRE(is); //-V521 json tests = json::parse(is); for (const auto& test_group : tests.array_range()) { const json& root = test_group["given"]; for (const auto& test_case : test_group["cases"].array_range()) { std::string expr = test_case["expression"].as(); //std::cout << (fpath + "-" + expr) << "\n"; try { json actual = jmespath::search(root, expr); if (test_case.contains("result")) { const json& expected = test_case["result"]; if (actual != expected) { if (test_case.contains("comment")) { std::cout << "\n" << test_case["comment"] << "\n"; } std::cout << "Input:\n" << pretty_print(root) << "\n\n"; std::cout << "Expression: " << expr << "\n\n"; std::cout << "Actual: " << pretty_print(actual) << "\n\n"; std::cout << "Expected: " << pretty_print(expected) << "\n\n"; } CHECK(expected == actual); //-V521 } else if (test_case.contains("error")) { if (test_case.contains("comment")) { std::cout << "Comment: " << test_case["comment"] << "\n"; } std::cout << "Error: " << test_case["error"] << "\n\n"; std::cout << "Input:\n" << pretty_print(root) << "\n\n"; std::cout << "Expression: " << expr << "\n\n"; std::cout << "Actual: " << pretty_print(actual) << "\n\n"; CHECK(false); //-V521 } } catch (const std::exception& e) { if (test_case.contains("result")) { const json& expected = test_case["result"]; std::cout << e.what() << "\n"; if (test_case.contains("comment")) { std::cout << "Comment: " << test_case["comment"] << "\n\n"; } std::cout << "Input\n" << pretty_print(root) << "\n\n"; std::cout << "Expression: " << expr << "\n\n"; std::cout << "Expected: " << expected << "\n\n"; CHECK(false); //-V521 } } } } } TEST_CASE("jmespath-tests") { SECTION("Examples and tutorials") { jmespath_tests("./jmespath/input/examples/jmespath-examples.json"); } SECTION("Issues") { jmespath_tests("./jmespath/input/issues/issues.json"); } SECTION("compliance") { jmespath_tests("./jmespath/input/compliance/syntax.json"); // OK jmespath_tests("./jmespath/input/compliance/basic.json"); // OK jmespath_tests("./jmespath/input/compliance/boolean.json"); // OK jmespath_tests("./jmespath/input/compliance/current.json"); // OK jmespath_tests("./jmespath/input/compliance/escape.json"); // OK jmespath_tests("./jmespath/input/compliance/filters.json"); // OK jmespath_tests("./jmespath/input/compliance/identifiers.json"); // OK jmespath_tests("./jmespath/input/compliance/indices.json"); // OK jmespath_tests("./jmespath/input/compliance/literal.json"); // OK jmespath_tests("./jmespath/input/compliance/multiselect.json"); // OK jmespath_tests("./jmespath/input/compliance/pipe.json"); // OK jmespath_tests("./jmespath/input/compliance/slice.json"); // OK jmespath_tests("./jmespath/input/compliance/unicode.json"); // OK jmespath_tests("./jmespath/input/compliance/wildcard.json"); // OK jmespath_tests("./jmespath/input/compliance/benchmarks.json"); // OK jmespath_tests("./jmespath/input/compliance/functions.json"); // OK } } jsoncons-1.3.2/test/jsonpatch/000077500000000000000000000000001477700171100163265ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonpatch/input/000077500000000000000000000000001477700171100174655ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonpatch/input/compliance/000077500000000000000000000000001477700171100215775ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonpatch/input/compliance/fail.json000066400000000000000000000040051477700171100234040ustar00rootroot00000000000000[ { "given": { "foo": "bar"}, "cases": [ { "comment" : "add -> add -> add -> fail", "patch": [ { "op": "add", "path": "/baz", "value": "qux" }, { "op": "add", "path": "/foo", "value": [ "bar", "baz" ] }, { "op": "add", "path": "/baz/bat", "value": "qux" } // nonexistent target ], "error" : "fail" } ] }, { "given": { "baz": "boo", "foo": [ "bar", "qux", "baz" ] }, "cases": [ { "comment" : "add -> remove -> remove -> fail", "patch": [ { "op": "add", "path": "/baz", "value": "qux" }, { "op": "remove", "path": "/foo/2" }, { "op": "remove", "path": "/foo/2" } // nonexistent target ], "error" : "fail" } ] }, { "given": { "baz": ["boo"], "foo": [ "bar", "qux", "baz" ] }, "cases": [ { "comment" : "add -> add -> fail", "patch": [ { "op": "add", "path": "/baz/-", "value": "xyz" }, { "op": "add", "path": "/baz/3", "value": "wxy" } ], "error" : "fail" }, { "comment" : "add -> move -> copy -> replace -> remove -> fail", "patch": [ { "op": "add", "path": "/baz/-", "value": "xyz" }, { "op": "move", "from": "/foo/1", "path" : "/baz/-" }, { "op": "copy", "from": "/baz/0", "path" : "/foo/-" }, { "op": "replace", "path": "/foo/2", "value" : "qux" }, { "op": "remove", "path": "/foo/3" } // nonexistent target ], "error" : "fail" } ] } ] jsoncons-1.3.2/test/jsonpatch/input/compliance/rfc6902-examples.json000066400000000000000000000162271477700171100254110ustar00rootroot00000000000000[ { "source" : "https://tools.ietf.org/html/rfc6902 Appendix A", "given": { "foo": "bar"}, "cases": [ { "comment" : "Adding an object member", "patch": [ { "op": "add", "path": "/baz", "value": "qux" } ], "result": {"baz":"qux","foo":"bar"} } ] }, { "source" : "https://tools.ietf.org/html/rfc6902 Appendix A", "given": { "foo": [ "bar", "baz" ] }, "cases": [ { "comment" : "Adding an array element", "patch": [ { "op": "add", "path": "/foo/1", "value": "qux" } ], "result": { "foo": [ "bar", "qux", "baz" ] } } ] }, { "source" : "https://tools.ietf.org/html/rfc6902 Appendix A", "given": { "baz": "qux", "foo": "bar" }, "cases": [ { "comment" : "Removing an object member", "patch": [ { "op": "remove", "path": "/baz" } ], "result": { "foo": "bar" } } ] }, { "source" : "https://tools.ietf.org/html/rfc6902 Appendix A", "given": { "foo": [ "bar", "qux", "baz" ] }, "cases": [ { "comment" : "Removing an array element", "patch": [ { "op": "remove", "path": "/foo/1" } ], "result": { "foo": [ "bar", "baz" ] } } ] }, { "source" : "https://tools.ietf.org/html/rfc6902 Appendix A", "given": { "baz": "qux", "foo": "bar" }, "cases": [ { "comment" : "Replacing a value", "patch": [ { "op": "replace", "path": "/baz", "value": "boo" } ], "result": { "baz": "boo", "foo": "bar" } } ] }, { "source" : "https://tools.ietf.org/html/rfc6902 Appendix A", "given": { "foo": { "bar": "baz", "waldo": "fred" }, "qux": { "corge": "grault" } }, "cases": [ { "comment" : "Moving a value", "patch": [ { "op": "move", "from": "/foo/waldo", "path": "/qux/thud" } ], "result": { "foo": { "bar": "baz" }, "qux": { "corge": "grault", "thud": "fred" } } } ] }, { "source" : "https://tools.ietf.org/html/rfc6902 Appendix A", "given": { "foo": [ "all", "grass", "cows", "eat" ] }, "cases": [ { "comment" : "Moving an array element", "patch": [ { "op": "move", "from": "/foo/1", "path": "/foo/3" } ], "result": { "foo": [ "all", "cows", "eat", "grass" ] } } ] }, { "source" : "https://tools.ietf.org/html/rfc6902 Appendix A", "given": { "baz": "qux", "foo": [ "a", 2, "c" ] }, "cases": [ { "comment" : "Testing a value: success", "patch": [ { "op": "test", "path": "/baz", "value": "qux" }, { "op": "test", "path": "/foo/1", "value": 2 } ], "result": {"baz":"qux","foo":["a",2,"c"]} } ] }, { "source" : "https://tools.ietf.org/html/rfc6902 Appendix A", "given": { "baz": "qux" }, "cases": [ { "comment" : "Testing a value: error", "patch": [ { "op": "test", "path": "/baz", "value": "bar" } ], "error": "path error" } ] }, { "source" : "https://tools.ietf.org/html/rfc6902 Appendix A", "given": { "foo": "bar" }, "cases": [ { "comment" : "Adding a nested member object", "patch": [ { "op": "add", "path": "/child", "value": { "grandchild": { } } } ], "result": { "foo": "bar", "child": { "grandchild": { } } } } ] }, { "source" : "https://tools.ietf.org/html/rfc6902 Appendix A", "given": { "foo": "bar" }, "cases": [ { "comment" : "Ignoring unrecognized elements", "patch": [ { "op": "add", "path": "/baz", "value": "qux", "xyz": 123 } ], "result": { "foo": "bar", "baz": "qux" } } ] }, { "source" : "https://tools.ietf.org/html/rfc6902 Appendix A", "given": { "foo": "bar" }, "cases": [ { "comment" : "Adding to a nonexistent target", "patch": [ { "op": "add", "path": "/baz/bat", "value": "qux" } ], "error": "nonexistent target" } ] }, { "source" : "https://tools.ietf.org/html/rfc6902 Appendix A", "given": { "/": 9, "~1": 10 }, "cases": [ { "comment" : " ~ escape ordering", "patch": [ {"op": "test", "path": "/~01", "value": 10} ], "result": { "/": 9, "~1": 10 } } ] }, { "source" : "https://tools.ietf.org/html/rfc6902 Appendix A", "given": { "/": 9, "~1": 10 }, "cases": [ { "comment" : "Comparing strings and numbers", "patch": [ {"op": "test", "path": "/~01", "value": "10"} ], "error" : "The document value is numeric, whereas the value being tested for is a string." } ] }, { "source" : "https://tools.ietf.org/html/rfc6902 Appendix A", "given": { "foo": ["bar"] }, "cases": [ { "comment" : "Adding an array value", "patch": [ { "op": "add", "path": "/foo/-", "value": ["abc", "def"] } ], "result": { "foo": ["bar", ["abc", "def"]] } } ] } ] jsoncons-1.3.2/test/jsonpatch/input/compliance/test.json000066400000000000000000000020071477700171100234500ustar00rootroot00000000000000[ { "given": { "baz": ["boo"], "foo": [ "bar", "qux", "baz" ] }, "cases": [ { "comment" : "add -> add -> fail", "patch": [ { "op": "add", "path": "/baz/-", "value": "xyz" }, { "op": "add", "path": "/baz/3", "value": "wxy" } ], "error" : "fail" }, { "comment" : "add -> move -> copy -> replace -> remove -> fail", "patch": [ { "op": "add", "path": "/baz/-", "value": "xyz" }, { "op": "move", "from": "/foo/1", "path" : "/baz/-" }, { "op": "copy", "from": "/baz/0", "path" : "/foo/-" }, { "op": "replace", "path": "/foo/2", "value" : "qux" }, { "op": "remove", "path": "/foo/3" } // nonexistent target ], "error" : "fail" } ] } ] jsoncons-1.3.2/test/jsonpatch/src/000077500000000000000000000000001477700171100171155ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonpatch/src/jsonpatch_test_suite.cpp000066400000000000000000000057101477700171100240650ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include #include #include // std::unordered_set #include #include using namespace jsoncons; void jsonpatch_tests(const std::string& fpath) { std::fstream is(fpath); if (!is) { std::cerr << "Cannot open " << fpath << "\n"; exit(1); } json tests = json::parse(is); for (const auto& test_group : tests.array_range()) { for (const auto& test_case : test_group["cases"].array_range()) { const json& patch = test_case["patch"]; if (test_case.contains("result")) { json target = test_group.at("given"); std::error_code ec; jsonpatch::apply_patch(target, patch, ec); const json& expected = test_case["result"]; if (target != expected) { if (test_case.contains("comment")) { std::cout << "\n" << test_case["comment"] << "\n"; } std::cout << "Input: " << pretty_print(test_group.at("given")) << "\n\n"; std::cout << "Patch: " << pretty_print(patch) << "\n\n"; std::cout << "Target: " << pretty_print(target) << "\n\n"; std::cout << "Expected: " << pretty_print(expected) << "\n\n"; } CHECK(expected == target); //-V521 } else if (test_case.contains("error")) { json target = test_group.at("given"); std::error_code ec; jsonpatch::apply_patch(target, patch, ec); CHECK(ec); const json& expected = test_group.at("given"); if (target != expected) { if (test_case.contains("comment")) { std::cout << "\n" << test_case["comment"] << "\n"; } std::cout << "Input: " << pretty_print(test_group.at("given")) << "\n\n"; std::cout << "Patch: " << pretty_print(patch) << "\n\n"; std::cout << "Target: " << pretty_print(target) << "\n\n"; std::cout << "Expected: " << pretty_print(expected) << "\n\n"; } CHECK(expected == target); //-V521 } } } } TEST_CASE("jsonpatch tests") { SECTION("compliance") { jsonpatch_tests("./jsonpatch/input/compliance/rfc6902-examples.json"); //jsonpatch_tests("./jsonpatch/input/compliance/test.json"); } } jsoncons-1.3.2/test/jsonpatch/src/jsonpatch_tests.cpp000066400000000000000000000112751477700171100230420ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include using jsoncons::json; using jsoncons::json_options; using jsoncons::ojson; namespace jsonpatch = jsoncons::jsonpatch; using namespace jsoncons::literals; template void check_patch(Json& target, const Json& patch, const std::error_code& expected_ec, const Json& expected) { std::error_code ec; jsonpatch::apply_patch(target, patch, ec); if (ec != expected_ec || expected != target) { std::cout << "target:\n" << target << '\n'; } CHECK(ec == expected_ec); //-V521 CHECK(expected == target); //-V521 } TEST_CASE("testing_a_value_success") { json target = R"( { "baz": "qux", "foo": [ "a", 2, "c" ] } )"_json; json patch = R"( [ { "op": "test", "path": "/baz", "value": "qux" }, { "op": "test", "path": "/foo/1", "value": 2 } ] )"_json; json expected = target; check_patch(target,patch,std::error_code(),expected); } TEST_CASE("testing_a_value_error") { json target = R"( { "baz": "qux" } )"_json; json patch = R"( [ { "op": "test", "path": "/baz", "value": "bar" } ] )"_json; json expected = target; check_patch(target,patch,jsonpatch::jsonpatch_errc::test_failed,expected); } TEST_CASE("comparing_strings_and_numbers") { json target = R"( { "/": 9, "~1": 10 } )"_json; json patch = R"( [ {"op": "test", "path": "/~01", "value": "10"} ] )"_json; json expected = target; check_patch(target,patch,jsonpatch::jsonpatch_errc::test_failed,expected); } TEST_CASE("test_add_add") { json target = R"( { "foo": "bar"} )"_json; json patch = R"( [ { "op": "add", "path": "/baz", "value": "qux" }, { "op": "add", "path": "/foo", "value": [ "bar", "baz" ] } ] )"_json; json expected = R"( { "baz":"qux", "foo": [ "bar", "baz" ]} )"_json; check_patch(target,patch,std::error_code(),expected); } TEST_CASE("test_diff1") { json source = R"( {"/": 9, "~1": 10, "foo": "bar"} )"_json; json target = R"( { "baz":"qux", "foo": [ "bar", "baz" ]} )"_json; auto patch = jsonpatch::from_diff(source, target); check_patch(source,patch,std::error_code(),target); } TEST_CASE("test_diff2") { json source = R"( { "/": 3, "foo": "bar" } )"_json; json target = R"( { "/": 9, "~1": 10 } )"_json; auto patch = jsonpatch::from_diff(source, target); check_patch(source,patch,std::error_code(),target); } TEST_CASE("add_when_new_items_in_target_array1") { json source = R"( {"/": 9, "foo": [ "bar"]} )"_json; json target = R"( { "baz":"qux", "foo": [ "bar", "baz" ]} )"_json; json patch = jsoncons::jsonpatch::from_diff(source, target); check_patch(source,patch,std::error_code(),target); } TEST_CASE("add_when_new_items_in_target_array2") { json source = R"( {"/": 9, "foo": [ "bar", "bar"]} )"_json; json target = R"( { "baz":"qux", "foo": [ "bar", "baz" ]} )"_json; json patch = jsoncons::jsonpatch::from_diff(source, target); check_patch(source,patch,std::error_code(),target); } TEST_CASE("jsonpatch - remove two items from array") { json source = json::parse(R"( { "names" : [ "a", "b", "c", "d" ] } )"); json target = json::parse(R"( { "names" : [ "a", "b" ] } )"); json patch = jsoncons::jsonpatch::from_diff(source, target); check_patch(source,patch,std::error_code(),target); } TEST_CASE("from diff with null and lossless number") { ojson expected_patch = ojson::parse( R"([{"op":"replace","path":"/hello","value":null},{"op":"replace","path":"/hello2","value":"123.4"}])" ); auto options = json_options{} .lossless_number(true) .bignum_format(jsoncons::bignum_format_kind::raw) .byte_string_format(jsoncons::byte_string_chars_format::base64); const char* json1 = "{\"hello\":123.4, \"hello2\":null}"; const char* json2 = "{\"hello\":null, \"hello2\":123.4 }"; ojson j1 = ojson::parse(json1, options); ojson j2 = ojson::parse(json2, options); ojson patch = jsonpatch::from_diff(j1, j2); CHECK(expected_patch == patch); check_patch(j1,patch,std::error_code(),j2); } jsoncons-1.3.2/test/jsonpath/000077500000000000000000000000001477700171100161635ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonpath/input/000077500000000000000000000000001477700171100173225ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonpath/input/test.json000066400000000000000000000004731477700171100212000ustar00rootroot00000000000000[ { "given" : [[1, 2, 3], [1], [2, 3], 1, 2], "cases" : [ { "comment" : "Filter expression with equals array for array slice with range 1", "expression" : "$[?(@[0:1]==[1])]", "result" : [[1,2,3],[1]] } ] } ] jsoncons-1.3.2/test/jsonpath/input/test_data/000077500000000000000000000000001477700171100212725ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonpath/input/test_data/dot-notation.json000066400000000000000000000124421477700171100246070ustar00rootroot00000000000000[ { "given" : {"key": "value"}, "cases" : [ { "comment" : "dot notation", "expression" : "$.key", "result" : ["value"] } ] }, { "given" : { "one": {"key": "value"}, "two": {"some": "more", "key": "other value"}, "two.some": "42" }, "cases" : [ { "comment" : "dot notation", "expression" : "$.two.some", "result" : ["more"] } ] }, { "given" : { "key": "value", "\"key\"": 42 }, "cases" : [ { "comment" : "Dot notation with double quotes", "expression" : "$.\"key\"", "result" : ["value"] }, { "comment" : "Dot notation with single quotes", "expression" : "$.'key'", "result" : ["value"] } ] }, { "given" : { "key": "value", "\"key\"": 42 }, "cases" : [ { "comment" : "Dot notation with double quotes", "expression" : "$.\"key\"", "result" : ["value"] }, { "comment" : "Dot notation with single quotes", "expression" : "$.'key'", "result" : ["value"] } ] }, { "given" : { "屬性": "value" }, "cases" : [ { "comment" : "Dot notation with non ASCII key", "expression" : "$.屬性", "result" : ["value"] } ] }, { "given" : {"a": "first", "2": "second", "b": "third"}, "cases" : [ { "comment" : "Dot notation with number on object", "expression" : "$.2", "result" : ["second"] } ] }, { "given": { "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ], "bicycle": { "color": "red", "price": 19.95 } } }, "cases" : [ { "comment" : "Select the first (indexed 0) book", "expression" : "$.store.book.0.title", "result" : ["Sayings of the Century"] }, { "comment" : "Select the first (indexed 0) book", "expression" : "$ . store . book . 0 . title", "result" : ["Sayings of the Century"] }, { "comment" : "Select the first (indexed 0) book", "expression" : "$.'store'.'book'.0.'title'", "result" : ["Sayings of the Century"] }, { "comment" : "Select the first (indexed 0) book", "expression" : "$ . 'store' . 'book' . 0 . 'title'", "result" : ["Sayings of the Century"] }, { "comment" : "Select the first (indexed 0) book", "expression" : "$.\"store\".\"book\".0.\"title\"", "result" : ["Sayings of the Century"] }, { "comment" : "Select the first (indexed 0) book", "expression" : "$ . \"store\" . \"book\" . 0 . \"title\"", "result" : ["Sayings of the Century"] } ] }, { "source:" : "https://cburgmer.github.io/json-path-comparison/", "given": {"key-dash": "value"}, "cases": [ { "comment" : "Dot notation with dash", "expression" : "$.key-dash", "error" : true }, { "comment" : "Dot notation with dash", "expression" : "$.'key-dash'", "result" : ["value"] }, { "comment" : "Dot notation with dash", "expression" : "$.\"key-dash\"", "result" : ["value"] } ] } ] jsoncons-1.3.2/test/jsonpath/input/test_data/expressions.json000066400000000000000000000050471477700171100245550ustar00rootroot00000000000000[ { "source" : "https://cburgmer.github.io/json-path-comparison/", "given": ["first", "second", "third", "forth", "fifth"], "cases": [ { "comment" : "Dot notation after filter expression", "expression": "$[(@.length-1)]", "result": ["fifth"] }, { "comment" : "Dot notation after filter expression", "expression": "$[(@.length - 1)]", "result": ["fifth"] }, { "comment" : "Dot notation after filter expression", "expression": "$[(@.length - 1),(@.length - 2)]", "result": ["fifth","forth"] } ] }, { "source" : "https://github.com/danielaparker/jsoncons/issues/338", "given": { "version": "EC_v1", "data": { "paymentData": { "CCX": { "CCN": "3569990010095841", "CVV": "737", "DDMM": "0420" }, "eciIndicator": "5" }, "paymentDataList": [ { "CCN": "3569990010095840", "CVV": "737", "DDMM": "0420" }, { "CCN": "3569990010095841", "CVV": "737", "DDMM": "0421" }, { "CCN": "3569990010095842", "CVV": "737", "DDMM": "0422" }, { "CCN": "3569990010095843", "CVV": "737", "DDMM": "0423" }, { "CCN": "3569990010095844", "CVV": "737", "DDMM": "0424" } ] } } , "cases": [ { "comment" : "Normalized paths with expression", "expression": "$.data.paymentDataList[0,(@.length-1)].DDMM", "path": [ "$['data']['paymentDataList'][0]['DDMM']", "$['data']['paymentDataList'][4]['DDMM']" ] } ] } ] jsoncons-1.3.2/test/jsonpath/input/test_data/filters.json000066400000000000000000001300221477700171100236330ustar00rootroot00000000000000[ { "given": [{"name": "John Smith"}, {"name": null}], "cases": [ { "comment" : "Filter expression without enclosing parentheses", "expression": "$[?@.name == 'John Smith']", "result": [{"name": "John Smith"}] } ] }, { "given" : [{"key": 0}, {"key": 42}, {"key": -1}, {"key": 41}, {"key": 43}, {"key": 42.0001}, {"key": 41.9999}, {"key": 100}, {"some": "value"}], "cases" : [ { "source" : "https://github.com/cburgmer/json-path-comparison", "comment" : "Filter less than", "expression" : "$[?(@.key<42)]", "result" : [{"key": 0}, {"key": -1}, {"key": 41}, {"key": 41.9999}] } ] }, { "source" : "https://cburgmer.github.io/json-path-comparison/", "given": [{"id": 2}], "cases": [ { "comment" : "Filter expression after recursive descent", "expression": "$..[?(@.id==2)]", "result": [{"id":2}] } ] }, { "source" : "https://cburgmer.github.io/json-path-comparison/", "given": {"id": 2, "more": [{"id": 2}, {"more": {"id": 2}}, {"id": {"id": 2}}, [{"id": 2}]]}, "cases": [ { "comment" : "Filter expression after recursive descent", "expression": "$..[?(@.id==2)]", "result": [ { "id": 2 }, { "id": 2 }, { "id": 2 }, { "id": 2 } ] } ] }, { "given": [{"name": "John Smith"}, {"name": null}], "cases": [ { "comment" : "Filter expression", "expression": "$[?(@.name == 'John Smith')]", "result": [{"name": "John Smith"}] }, { "comment" : "Filter expression", "expression": "$[?(@.name)]", "result": [{"name": "John Smith"}] }, { "comment" : "Filter expression", "expression": "$[?(!@.name)]", "result": [{"name": null}] } ] }, { "source" : "https://cburgmer.github.io/json-path-comparison/", "given": [ { "complext": { "one": [ { "name": "first", "id": 1 }, { "name": "next", "id": 2 }, { "name": "another", "id": 3 }, { "name": "more", "id": 4 } ], "more": { "name": "next to last", "id": 5 } } }, { "name": "last", "id": 6 } ], "cases": [ { "comment" : "Filter expression after dot notation with wildcard after recursive descent", "expression": "$..*[?(@.id>2)]", "result": [{"id":5,"name":"next to last"},{"id":3,"name":"another"},{"id":4,"name": "more"}] } ] }, { "source" : "https://cburgmer.github.io/json-path-comparison/", "given": [{"id": 42, "name": "forty-two"}, {"id": 1, "name": "one"}], "cases": [ { "comment" : "Filter expression with ==", "expression": "$[?(@.id==42)]", "result": [{"id": 42, "name": "forty-two"}] }, { "comment" : "Dot notation after filter expression", "expression": "$[?(@.id==42)].name", "result": ["forty-two"] } ] }, { "source" : "https://cburgmer.github.io/json-path-comparison/", "given":{"key": 42, "another": {"key": 1}}, "cases": [ { "comment" : "Filter expression on object", "expression": "$[?(@.key)]", "result": [{"key":1}] } ] }, { "source" : "https://cburgmer.github.io/json-path-comparison/", "given": {"id": 2, "more": [{"id": 2}, {"more": {"id": 2}}, {"id": {"id": 2}}, [{"id": 2}]]}, "cases": [ { "comment" : "Filter expression after recursive descent", "expression": "$..[?(@.id==2)]", "result": [{"id":2},{"id":2},{"id":2},{"id":2}] } ] }, { "source" : "https://cburgmer.github.io/json-path-comparison/", "given": [{"key": 60}, {"key": 50}, {"key": 10}, {"key": -50}, {"key+50": 100}], "cases": [ { "comment" : "Filter expression with addition", "expression": "$[?(@.key+50==100)]", "result": [{"key": 50}] } ] }, { "source" : "https://cburgmer.github.io/json-path-comparison/", "given": [{"key": 42},{"key": 43},{"key": 44}], "cases": [ { "comment" : "Filter expression with boolean and operator", "expression": "$[?(@.key>42 && @.key<44)]", "result": [{"key": 43}] } ] }, { "source" : "https://cburgmer.github.io/json-path-comparison/", "given": [ {"key": 1}, {"key": 3}, {"key": "nice"}, {"key": true}, {"key": null}, {"key": false}, {"key": {}}, {"key": []}, {"key": -1}, {"key": 0}, {"key": ""} ], "cases": [ { "comment" : "Filter expression with boolean and operator and value false", "expression": "$[?(@.key>0 && false)]", "result": [] }, { "comment" : "Filter expression with boolean and operator and value true", "expression": "$[?(@.key>0 && true)]", "result": [ { "key": 1 }, { "key": 3 } ] }, { "comment" : "Filter expression with boolean or operator or value false", "expression": "$[?(@.key>0 || false)]", "result": [ { "key": 1 }, { "key": 3 } ] }, { "comment" : "Filter expression with boolean or operator or value true", "expression": "$[?(@.key>0 || true)]", "result": [ {"key": 1}, {"key": 3}, {"key": "nice"}, {"key": true}, {"key": null}, {"key": false}, {"key": {}}, {"key": []}, {"key": -1}, {"key": 0}, {"key": ""} ] } ] }, { "source" : "https://cburgmer.github.io/json-path-comparison/", "given": [ {"key": 42}, {"key": 43}, {"key": 44} ], "cases": [ { "comment" : "Filter expression with boolean or operator", "expression": "$[?(@.key>43 || @.key<43)]", "result": [{"key": 42},{"key": 44}] } ] }, { "source" : "https://cburgmer.github.io/json-path-comparison/", "given": [ {"key": 0}, {"key": 42}, {"key": -1}, {"key": 41}, {"key": 43}, {"key": 42.0001}, {"key": 41.9999}, {"key": 100}, {"some": "value"} ], "cases": [ { "comment" : "Filter expression with bracket notation", "expression": "$[?(@['key']==42)]", "result": [{"key": 42}] } ] }, { "source" : "https://cburgmer.github.io/json-path-comparison/", "given": [ {"@key": 0}, {"@key": 42}, {"key": 42}, {"@key": 43}, {"some": "value"} ], "cases": [ { "comment" : "Filter expression with bracket notation and current object literal", "expression": "$[?(@['@key']==42)]", "result": [{"@key": 42}] } ] }, { "source" : "https://cburgmer.github.io/json-path-comparison/", "given": [[2, 3], ["a"], [0, 2], [2]], "cases": [ { "comment" : "Filter expression with bracket notation with -1", "expression": "$[?(@[-1]==2)]", "result": [[0,2],[2]] } ] }, { "source" : "https://cburgmer.github.io/json-path-comparison/", "given": [["a", "b"], ["x", "y"]], "cases": [ { "comment" : "Filter expression with bracket notation with number", "expression": "$[?(@[1]=='b')]", "result": [["a","b"]] } ] }, { "source" : "https://cburgmer.github.io/json-path-comparison/", "given": {"1": ["a", "b"], "2": ["x", "y"]}, "cases": [ { "comment" : "Filter expression with bracket notation with number on object", "expression": "$[?(@[1]=='b')]", "result": [["a","b"]] } ] }, { "source" : "https://cburgmer.github.io/json-path-comparison/", "given": [ "some value", null, "value", 0, 1, -1, "", [], {}, false, true ], "cases": [ { "comment" : "Filter expression with current object", "expression": "$[?(@)]", "result": [ "some value", "value", 0, 1, -1, true ] } ] }, { "source" : "https://cburgmer.github.io/json-path-comparison/", "given": [ { "a": true }, { "a": true, "b": true }, { "a": true, "b": true, "c": true }, { "b": true, "c": true }, { "a": true, "c": true }, { "c": true }, { "b": true } ], "cases": [ { "comment" : "Filter expression with different grouped operators", "expression": "$[?(@.a && (@.b || @.c))]", "result": [ { "a": true, "b": true }, { "a": true, "b": true, "c": true }, { "a": true, "c": true } ] } ] }, { "source" : "https://cburgmer.github.io/json-path-comparison/", "given": [ { "a": true, "b": true }, { "a": true, "b": true, "c": true }, { "b": true, "c": true }, { "a": true, "c": true }, { "a": true }, { "b": true }, { "c": true }, { "d": true }, {} ], "cases": [ { "comment" : "Filter expression with different ungrouped operators", "expression": "$[?(@.a && @.b || @.c)]", "result": [ { "a": true, "b": true }, { "a": true, "b": true, "c": true }, { "b": true, "c": true }, { "a": true, "c": true }, { "c": true } ] } ] }, { "comment" : "Filter expressions with || and &&", "given": [{"id":42,"name":"forty-two"},{"id":1,"name":"one"}], "cases": [ { "comment" : "true and true", "expression": "$[?(true && true)]", "result": [{"id":42,"name":"forty-two"},{"id":1,"name":"one"}] }, { "comment" : "true and false", "expression": "$[?(true && false)]", "result": [] }, { "comment" : "true or true", "expression": "$[?(true || true)]", "result": [{"id":42,"name":"forty-two"},{"id":1,"name":"one"}] }, { "comment" : "true or false", "expression": "$[?(true || false)]", "result": [{"id":42,"name":"forty-two"},{"id":1,"name":"one"}] }, { "comment" : "(true or false) and true", "expression": "$[?((true || false) && true)]", "result": [{"id":42,"name":"forty-two"},{"id":1,"name":"one"}] }, { "comment" : "(true and false) and true", "expression": "$[?((true && false) && true)]", "result": [] } ] }, { "given" : [{"key": 60}, {"key": 50}, {"key": 10}, {"key": -50}, {"key/10": 5}], "cases" : [ { "comment" : "Filter expression with division", "expression" : "$[?(@.key/10==5)]", "result" : [{"key": 50}] } ] }, { "given" : [1, {"key": 42}, "value", null], "cases" : [ { "comment" : "Filter expression with empty expression", "expression" : "$[?()]", "error" : "syntax error" } ] }, { "given" : [ {"key": 0}, {"key": 42}, {"key": -1}, {"key": 1}, {"key": 41}, {"key": 43}, {"key": 42.0001}, {"key": 41.9999}, {"key": 100}, {"key": "some"}, {"key": "42"}, {"key": null}, {"key": 420}, {"key": ""}, {"key": {}}, {"key": []}, {"key": [42]}, {"key": {"key": 42}}, {"key": {"some": 42}}, {"some": "value"} ], "cases" : [ { "comment" : "Filter expression with equals", "expression" : "$[?(@.key==42)]", "result" : [{"key": 42}] } ] }, { "given" : [ 0, 42, -1, 41, 43, 42.0001, 41.9999, null, 100 ], "cases" : [ { "comment" : "Filter expression with equals on array of numbers", "expression" : "$[?(@==42)]", "result" : [42] } ] }, { "given" : [{"key": 42}], "cases" : [ { "comment" : "Filter expression with equals on array without match", "expression" : "$[?(@.key==43)]", "result" : [] } ] }, { "given" : { "a": {"key": 0}, "b": {"key": 42}, "c": {"key": -1}, "d": {"key": 41}, "e": {"key": 43}, "f": {"key": 42.0001}, "g": {"key": 41.9999}, "h": {"key": 100}, "i": {"some": "value"} }, "cases" : [ { "comment" : "Filter expression with equals on object", "expression" : "$[?(@.key==42)]", "result" : [{"key":42}] } ] }, { "given" : {"id": 2}, "cases" : [ { "comment" : "Filter expression with equals on object with key matching query", "expression" : "$[?(@.id==2)]", "result" : [] } ] }, { "given" : [ { "d": [ "v1", "v2" ] }, { "d": [ "a", "b" ] }, { "d": "v1" }, { "d": "v2" }, { "d": {} }, { "d": [] }, { "d": null }, { "d": -1 }, { "d": 0 }, { "d": 1 }, { "d": "['v1','v2']" }, { "d": "['v1', 'v2']" }, { "d": "v1,v2" }, { "d": "[\"v1\", \"v2\"]" }, { "d": "[\"v1\",\"v2\"]" } ], "cases" : [ { "comment" : "Filter expression with equals array", "expression" : "$[?(@.d==[\"v1\",\"v2\"])]", "result" : [{"d": ["v1", "v2"]}] } ] }, { "given" : [[1, 2, 3], [1], [2, 3], 1, 2], "cases" : [ { "comment" : "Filter expression with equals array for array slice with range 1", "expression" : "$[?(@[0:1]==[1])]", "result" : [[1,2,3],[1]] } ] }, { "given" : [[1,2], [2,3], [1], [2], [1, 2, 3], 1, 2, 3], "cases" : [ { "comment" : "Filter expression with equals array for dot notation with star", "expression" : "$[?(@.*==[1,2])]", "result" : [[1,2]] } ] }, { "given" : [ { "d": [ "v1", "v2" ] }, { "d": [ "a", "b" ] }, { "d": "v1" }, { "d": "v2" }, { "d": {} }, { "d": [] }, { "d": null }, { "d": -1 }, { "d": 0 }, { "d": 1 }, { "d": "['v1','v2']" }, { "d": "['v1', 'v2']" }, { "d": "v1,v2" }, { "d": "[\"v1\", \"v2\"]" }, { "d": "[\"v1\",\"v2\"]" } ], "cases" : [ { "comment" : "Filter expression with equals array with single quotes", "expression" : "$[?(@.d==['v1','v2'])]", "error" : "syntax error" } ] }, { "given" : [{"key": 42}, {"key": 43}, {"key": 44}], "cases" : [ { "comment" : "Filter expression with equals boolean expression value", "expression" : "$[?((@.key<44)==false)]", "result" : [{"key": 44}] } ] }, { "given" : [ { "some": "some value" }, { "key": true }, { "key": false }, { "key": null }, { "key": "value" }, { "key": "" }, { "key": 0 }, { "key": 1 }, { "key": -1 }, { "key": 42 }, { "key": {} }, { "key": [] } ], "cases" : [ { "comment" : "Filter expression with equals false", "expression" : "$[?(@.key==false)]", "result" : [{"key": false}] }, { "comment" : "Filter expression with equals null", "expression" : "$[?(@.key==null)]", "result" : [{"some": "some value"},{"key": null}] } ] }, { "given" : [{"key": 42}, {"key": 43}, {"key": 44}], "cases" : [ { "comment" : "Filter expression with equals boolean expression value", "expression" : "$[?((@.key<44)==false)]", "result" : [{"key": 44}] } ] }, { "given" : [ { "a": [{"price": 1}, {"price": 3}] }, { "a": [{"price": 11}] }, { "a": [{"price": 8}, {"price": 12}, {"price": 3}] }, { "a": [] } ], "cases" : [ { "comment" : "Filter expression with subfilter", "expression" : "$[?(@.a[?(@.price>10)])]", "result" : [{"a":[{"price":11}]},{"a":[{"price":8},{"price":12},{"price":3}]}] } ] }, { "given" : [{"key": 60}, {"key": 50}, {"key": 10}, {"key": -50}, {"key-50": -100}], "cases" : [ { "comment" : "Filter expression with subtraction", "expression" : "$[?(@.key-50==-100)]", "result" : [{"key": -50}] }, { "comment" : "Filter expression with subtraction", "expression" : "$[?(@.key - 50==-100)]", "result" : [{"key": -50}] }, { "comment" : "Filter expression with subtraction", "expression" : "$[?(@.'key-50'==-100)]", "result" : [{"key-50":-100}] } ] }, // + operator { "given" : [{"key1": 100,"key2": 100},{"key1": 105,"key2": 200}], "cases" : [ { "comment" : "set plus value", "expression" : "$[?((@.key1 + 110) == 210)]", "result" : [{"key1": 100,"key2": 100}] } ] }, { "given" : [{"key1": 100,"key2": 100},{"key1": 105,"key2": 200}], "cases" : [ { "comment" : "value plus set", "expression" : "$[?((110 + @.key1) == 210)]", "result" : [{"key1": 100,"key2": 100}] } ] }, { "given" : [{"key1": 100,"key2": 100},{"key1": 105,"key2": 200}], "cases" : [ { "comment" : "set plus set", "expression" : "$[?((@.key1 + @.key2) == 200)]", "result" : [{"key1": 100,"key2": 100}] } ] }, // < operator { "given" : [{"some": "value"}], "cases" : [ { "comment" : "Filter empty set less than value", "expression" : "$[?(@.key<42)]", "result" : [] } ] }, { "given" : [{"some": "value"}], "cases" : [ { "comment" : "Filter value less than empty set", "expression" : "$[?(42 < @.key)]", "result" : [] } ] }, { "given" : [{"some": "value"}], "cases" : [ { "comment" : "Filter empty set less than empty set", "expression" : "$[?(@.other < @.key)]", "result" : [] } ] }, { "given" : [{"key1": 0,"key2": 20}, {"key1": 10,"key2": 9}], "cases" : [ { "comment" : "Filter non-empty set less than non-empty set", "expression" : "$[?(@.key1 < @.key2)]", "result" : [{"key1": 0,"key2": 20}] } ] }, { "given" : [[1, 2, 3], [1], [2, 3], 1, 2], "cases" : [ { "comment" : "Filter expression with equals number for array slice with range 1", "expression" : "$[?(@[0:1]==1)]", "result" : [] } ] }, { "given" : [[1,2], [2,3], [1], [2], [1, 2, 3], 1, 2, 3], "cases" : [ { "comment" : "Filter expression with equals number for bracket notation with star", "expression" : "$[?(@[*]==2)]", "result" : [] }, { "comment" : "Filter expression with equals number for dot notation with star", "expression" : "$[?(@.*==2)]", "result" : [] } ] }, { "given" : [{"key": -12.3}, {"key": -0.123}, {"key": -12}, {"key": 12.3}, {"key": 2}, {"key": "-0.123e2"}], "cases" : [ { "comment" : "Filter expression with equals number with fraction", "expression" : "$[?(@.key==-0.123e2)]", "result" : [{"key": -12.3}] } ] }, { "given" : [ { "d": { "k": "v" } }, { "d": { "a": "b" } }, { "d": "k" }, { "d": "v" }, { "d": {} }, { "d": [] }, { "d": null }, { "d": -1 }, { "d": 0 }, { "d": 1 }, { "d": "[object Object]" }, { "d": "{\"k\": \"v\"}" }, { "d": "{\"k\":\"v\"}" }, "v" ], "cases" : [ { "comment" : "Filter expression with equals object", "expression" : "$[?(@.d=={\"k\":\"v\"})]", "result" : [{"d": {"k": "v"}}] } ] }, { "given" : [ {"key": "some"}, {"key": "value"}, {"key": null}, {"key": 0}, {"key": 1}, {"key": -1}, {"key": ""}, {"key": {}}, {"key": []}, {"key": "valuemore"}, {"key": "morevalue"}, {"key": ["value"]}, {"key": {"some": "value"}}, {"key": {"key": "value"}}, {"some": "value"} ], "cases" : [ { "comment" : "Filter expression with equals string", "expression" : "$[?(@.key==\"value\")]", "result" : [{"key": "value"}] } ] }, { "given" : [ {"key": "some"}, {"key": "value"}, {"key": "hi@example.com"} ], "cases" : [ { "comment" : "Filter expression with equals string with current object literal", "expression" : "$[?(@.key==\"hi@example.com\")]", "result" : [{"key": "hi@example.com"}] } ] }, { "given" : [ {"key": "some"}, {"key": "value"}, {"key": "some.value"} ], "cases" : [ { "comment" : "Filter expression with equals string with dot literal", "expression" : "$[?(@.key==\"some.value\")]", "result" : [{"key": "some.value"}] } ] }, { "given" : [ {"key": "some"}, {"key": "value"} ], "cases" : [ { "comment" : "Filter expression with equals string with single quotes", "expression" : "$[?(@.key=='value')]", "result" : [{"key": "value"}] } ] }, { "given" : [ { "some": "some value" }, { "key": true }, { "key": false }, { "key": null }, { "key": "value" }, { "key": "" }, { "key": 0 }, { "key": 1 }, { "key": -1 }, { "key": 42 }, { "key": {} }, { "key": [] } ], "cases" : [ { "comment" : "Filter expression with equals true", "expression" : "$[?(@.key==true)]", "result" : [{"key": true}] } ] }, { "given" : {"value": 42, "items": [{"key": 10}, {"key": 42}, {"key": 50}]}, "cases" : [ { "comment" : "Filter expression with equals with root reference", "expression" : "$.items[?(@.key==$.value)]", "result" : [{"key": 42}] } ] }, { "given" : [ {"key": 0}, {"key": 42}, {"key": -1}, {"key": 41}, {"key": 43}, {"key": 42.0001}, {"key": 41.9999}, {"key": 100}, {"key": "43"}, {"key": "42"}, {"key": "41"}, {"key": "value"}, {"some": "value"} ], "cases" : [ { "comment" : "Filter expression with greater than", "expression" : "$[?(@.key>42)]", "result" : [{"key":43},{"key":42.0001},{"key":100}] }, { "comment" : "Filter expression with greater than or equal", "expression" : "$[?(@.key>=42)]", "result" : [{"key":42},{"key":43},{"key":42.0001},{"key":100}] }, { "comment" : "Filter expression with greater than or equal with whitespace", "expression" : "$[?(@.key >= 42)]", "result" : [{"key":42},{"key":43},{"key":42.0001},{"key":100}] }, { "comment" : "Filter expression with greater than or equal with whitespace", "expression" : "$[?(@.key >= 42.0)]", "result" : [{"key":42},{"key":43},{"key":42.0001},{"key":100}] }, { "comment" : "Filter expression with less than", "expression" : "$[?(@.key<42)]", "result" : [{"key":0},{"key":-1},{"key":41},{"key":41.9999}] }, { "comment" : "Filter expression with less than or equal", "expression" : "$[?(@.key<=42)]", "result" : [{"key":0},{"key":42},{"key":-1},{"key":41},{"key":41.9999}] }, { "comment" : "Filter expression with negation and equals", "expression" : "$[?(!(@.key==42))]", "result" : [ {"key": 0}, {"key": -1}, {"key": 41}, {"key": 43}, {"key": 42.0001}, {"key": 41.9999}, {"key": 100}, {"key": "43"}, {"key": "42"}, {"key": "41"}, {"key": "value"}, {"some": "value"} ] }, { "comment" : "Filter expression with negation and less than", "expression" : "$[?(!(@.key<42))]", "result" : [ {"key": 42}, {"key": 43}, {"key": 42.0001}, {"key": 100}, {"key": "43"}, {"key": "42"}, {"key": "41"}, {"key": "value"}, {"some": "value"} ] }, { "comment" : "Filter expression with negation and less than", "expression" : "$[?(!(@.key<=42))]", "result" : [ {"key": 43}, {"key": 42.0001}, {"key": 100}, {"key": "43"}, {"key": "42"}, {"key": "41"}, {"key": "value"}, {"some": "value"} ] }, { "comment" : "Filter expression with negation and less than", "expression" : "$[?(@.key!=42)]", "result" : [{"key":0},{"key":-1},{"key":41},{"key":43},{"key":42.0001},{"key":41.9999}, {"key":100},{"key":"43"},{"key":"42"},{"key":"41"},{"key":"value"},{"some":"value"}] } ] }, { "given" : [{"key": 60}, {"key": 50}, {"key": 10}, {"key": -50}, {"key*2": 100}], "cases" : [ { "comment" : "Filter expression with multiplication", "expression" : "$[?(@.key*2==100)]", "result" : [{"key": 50}] } ] }, { "given" : [{"key": 60}, {"key": 50}, {"key": 10}, {"key": -50}, {"key*2": 100}], "cases" : [ { "comment" : "Filter expression with modulus", "expression" : "$[?(@.key%40==20)]", "result" : [{"key": 60}] } ] }, { "given" : [[1,2],[3,4],[5,6]], "cases" : [ { "comment" : "Filter expression with set wise comparison to scalar", "expression" : "$[?(@[*]>=4)]", "result" : [] } ] }, { "given" : {"x":[[1,2],[3,4],[5,6]],"y":[3,4,5]}, "cases" : [ { "comment" : "Filter expression with set wise comparison to set", "expression" : "$.x[?(@[*]>=$.y[*])]", "result" : [] } ] }, { "given" : {"x":[[1,2],[3,4],[5,6]],"y":[3,4,5]}, "cases" : [ { "comment" : "Filter expression with set wise comparison to set", "expression" : "$.x[?(@[*]>=$.y[*])]", "result" : [] } ] }, // > operator { "given" : [{"some": "value"}], "cases" : [ { "comment" : "Filter empty set greater than value", "expression" : "$[?(@.key>42)]", "result" : [] } ] }, { "given" : [{"some": "value"}], "cases" : [ { "comment" : "Filter value greater than empty set", "expression" : "$[?(42 > @.key)]", "result" : [] } ] }, { "given" : [{"some": "value"}], "cases" : [ { "comment" : "Filter empty set greater than empty set", "expression" : "$[?(@.other > @.key)]", "result" : [] } ] }, { "given" : [{"key1": 0,"key2": 20}, {"key1": 10,"key2": 9}], "cases" : [ { "comment" : "Filter non-empty set greater than non-empty set", "expression" : "$[?(@.key1 > @.key2)]", "result" : [{"key1": 10,"key2": 9}] } ] }, // <= operator { "given" : [{"some": "value"}], "cases" : [ { "comment" : "Filter empty set less than or equal value", "expression" : "$[?(@.key<=42)]", "result" : [] } ] }, { "given" : [{"some": "value"}], "cases" : [ { "comment" : "Filter value less than or equal empty set", "expression" : "$[?(42 <= @.key)]", "result" : [] } ] }, { "given" : [{"some": "value"}], "cases" : [ { "comment" : "Filter empty set less than or equal empty set", "expression" : "$[?(@.other <= @.key)]", "result" : [] } ] }, { "given" : [{"key1": 0,"key2": 20}, {"key1": 10,"key2": 9}], "cases" : [ { "comment" : "Filter non-empty set less than or equal non-empty set", "expression" : "$[?(@.key1 <= @.key2)]", "result" : [{"key1": 0,"key2": 20}] } ] }, // >= operator { "given" : [{"some": "value"}], "cases" : [ { "comment" : "Filter empty set greater than or equal value", "expression" : "$[?(@.key>=42)]", "result" : [] } ] }, { "given" : [{"some": "value"}], "cases" : [ { "comment" : "Filter value greater than or equal empty set", "expression" : "$[?(42 >= @.key)]", "result" : [] } ] }, { "given" : [{"some": "value"}], "cases" : [ { "comment" : "Filter empty set greater than or equal empty set", "expression" : "$[?(@.other >= @.key)]", "result" : [] } ] }, { "given" : [{"key1": 0,"key2": 20}, {"key1": 10,"key2": 9}], "cases" : [ { "comment" : "Filter non-empty set greater than or equal non-empty set", "expression" : "$[?(@.key1 >= @.key2)]", "result" : [{"key1": 10,"key2": 9}] } ] }, { "given": [ { "root": { "id" : 10, "second": [ { "names": [ 2 ], "complex": [ { "names": [ 1 ], "panels": [ { "result": [ 1 ] }, { "result": [ 1, 2, 3, 4 ] }, { "result": [ 1 ] } ] } ] } ] } }, { "root": { "id" : 20, "second": [ { "names": [ 2 ], "complex": [ { "names": [ 1 ], "panels": [ { "result": [ 1 ] }, { "result": [ 1, 2, 3, 4 ] }, { "result": [ 1 ] } ] } ] } ] } } ], "cases": [ { "expression": "$..[?(@.result.length == 4)]", "result": [{"result":[1,2,3,4]},{"result":[1,2,3,4]}] }, { "expression": "$..[?(@.id == 10)]..[?(@.result.length == 4)]", "result": [{"result":[1,2,3,4]}] }, { "expression": "$..[?(@.result.length == 4)][?(@[0] == 3 || @[1] == 3 || @[2] == 3 || @[3] == 3)]", "result": [[1,2,3,4],[1,2,3,4]] } ] }, { "given": { "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ], "bicycle": { "color": "red", "price": 19.95 } } }, "cases": [ { "comment" : "==number", "expression": "$..book[?(@.price==8.99)].price", "result": [8.99] }, { "comment" : "==number", "expression": "$..book[?@.price==8.99].price", "result": [8.99] } ] }, { "given" : [{"key1" : {"a" : {"a" : 2}}, "key2" : 1},{"key1" : {"a" : {"a" : 1}}, "key2" : 2}], "cases" : [ { "comment" : "Union of filters followed by multiple identifiers", "expression" : "$[?(@.key2 == 1),?(@.key2 == 2)].key1.a.a", "result" : [2,1] } ] } ] jsoncons-1.3.2/test/jsonpath/input/test_data/functions.json000066400000000000000000000422631477700171100242040ustar00rootroot00000000000000[ { "given": { "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ], "bicycle": { "color": "red", "price": 19.95 } } }, "cases": [ { "comment" : "length", "expression": "length($.store.book[*])", "result": [4] }, { "comment" : "keys", "expression": "keys($.store.book[0])[*]", "result": ["author","category","price","title"] }, { "comment" : "sum", "expression": "sum($.store.book[*].price)", "result": [53.92] }, { "comment" : "sum in filter", "expression": "$.store.book[?(@.price > sum($.store.book[*].price) / length($.store.book[*]))].title", "result": ["The Lord of the Rings"] }, { "comment" : "avg", "expression": "avg($.store.book[*].price)", "result": [13.48] }, { "comment" : "avg in filter", "expression": "$.store.book[?(@.price > avg($.store.book[*].price))].title", "result": ["The Lord of the Rings"] }, { "comment" : "prod", "expression": "prod($.store.book[*].price)", "result": [24028.731766049998] }, { "comment" : "min", "expression": "min($.store.book[*].price)", "result": [8.95] }, { "comment" : "max", "expression": "max($.store.book[*].price)", "result": [22.99] }, { "comment" : "max in filter", "expression": "$.store.book[?(@.price < max($.store.book[*].price))].title", "result": ["Sayings of the Century","Sword of Honour","Moby Dick"] } ] }, { "given": { "books": [ { "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] }, "cases": [ { "comment" : "All titles that don't have a price", "expression": "$.books[?(!contains(keys(@),'price'))].title", "result": ["The Night Watch"] } ] }, { "source": "JMESPath test suite", "given": { "foo": -1, "zero": 0, "numbers": [-1, 3, 4, 5], "array": [-1, 3, 4, 5, "a", "100"], "strings": ["a", "b", "c"], "decimals": [1.01, 1.2, -1.5], "str": "Str", "false": false, "empty_list": [], "empty_hash": {}, "objects": {"foo": "bar", "bar": "baz"}, "null_key": null }, "cases": [ { "expression": "ceil(1.2)", "result": [2] }, { "expression": "ceil(1.2*2)", "result": [3] }, { "expression": "ceil($.decimals[0])", "result": [2] }, { "expression": "ceil($.decimals[1])", "result": [2] }, { "expression": "to_number('1.0')", "result": [1.0] }, { "expression": "ceil($.decimals[2])", "result": [-1] }, { "expression": "ceil('string')", "result": [] }, { "expression": "abs($.foo)", "result": [1] }, { "expression": "abs($.str)", "result": [] }, { "expression": "abs($.array[1])", "result": [3] }, { "expression": "abs(false)", "result": [] }, { "expression": "abs(-24)", "result": [24] }, { "expression": "abs(1, 2)", "error": "invalid arity" }, { "expression": "abs()", "error": "invalid arity" }, { "expression": "unknown_function(1, 2)", "error": "unknown-function" }, { "expression": "avg($.numbers)", "result": [2.75] }, { "expression": "avg($.array)", "result": [] }, { "expression": "avg('abc')", "result": [] }, { "expression": "avg($.foo)", "result": [] //"error": "invalid-type" }, { "expression": "avg(@)", "result": [] //"error": "invalid-type" }, { "expression": "avg($.strings)", "result": [] //"error": "invalid-type" }, { "expression": "avg($.empty_list)", "result": [null] }, { "expression": "ceil(1.2)", "result": [2] }, { "expression": "ceil($.decimals[0])", "result": [2] }, { "expression": "ceil($.decimals[1])", "result": [2] }, { "expression": "ceil($.decimals[2])", "result": [-1] }, { "expression": "ceil('string')", "result": [] //"error": "invalid-type" }, { "expression": "contains('abc', 'a')", "result": [true] }, { "expression": "contains('abc', 'd')", "result": [false] }, { "expression": "contains(false, 'd')", "result" : [] //"error": "invalid-type" }, { "expression": "contains($.strings, 'a')", "result": [true] }, { "expression": "contains($.decimals, 1.2)", "result": [true] }, { "expression": "contains($.decimals, false)", "result": [false] }, { "expression": "ends_with($.str, 'r')", "result": [true] }, { "expression": "ends_with($.str, 'tr')", "result": [true] }, { "expression": "ends_with($.str, 'Str')", "result": [true] }, { "expression": "ends_with($.str, 'SStr')", "result": [false] }, { "expression": "ends_with($.str, 'foo')", "result": [false] }, { "expression": "ends_with($.str, 0)", "result": [] //"error": "invalid-type" }, { "expression": "floor(1.2)", "result" : [1] }, { "expression": "floor('string')", "result" : [] //"error": "invalid-type" }, { "expression": "floor($.decimals[0])", "result": [1] }, { "expression": "floor($.foo)", "result": [-1] }, { "expression": "floor($.str)", "result": [] //"error": "invalid-type" }, { "expression": "length('abc')", "result": [3] }, { "expression": "length('✓foo')", "result": [4] }, { "expression": "length('')", "result": [0] }, { "expression": "length(@)", "result": [12] }, { "expression": "length($.strings[0])", "result": [1] }, { "expression": "length($.str)", "result": [3] }, { "expression": "length($.array)", "result": [6] }, { "expression": "length($.objects)", "result": [2] }, { "expression": "length(false)", "result": [] //"error": "invalid-type" }, { "expression": "length($.foo)", "result": [] //"error": "invalid-type" }, { "expression": "length($.strings[0])", "result": [1] }, { "expression": "max($.numbers)", "result": [5] }, { "expression": "max($.decimals)", "result": [1.2] }, { "expression": "max($.strings)", "result": ["c"] }, { "expression": "max($.abc)", "result": [] //"error": "invalid-type" }, { "expression": "max($.array)", "result": [] //"error": "invalid-type" }, { "expression": "max($.decimals)", "result": [1.2] }, { "expression": "max($.empty_list)", "result": [null] }/*, { "expression": "merge(`{}`)", "result": {} }, { "expression": "merge(`{}`, `{}`)", "result": {} }, { "expression": "merge(`{\"a\": 1}`, `{\"b\": 2}`)", "result": {"a": 1, "b": 2} }, { "expression": "merge(`{\"a\": 1}`, `{\"a\": 2}`)", "result": {"a": 2} }, { "expression": "merge(`{\"a\": 1, \"b\": 2}`, `{\"a\": 2, \"c\": 3}`, `{\"d\": 4}`)", "result": {"a": 2, "b": 2, ["c"]: 3, "d": 4} }*/, { "expression": "min($.numbers)", "result": [-1] }, { "expression": "min($.decimals)", "result": [-1.5] }, { "expression": "min($.abc)", "result": [] //"error": "invalid-type" }, { "expression": "starts_with($.str, 'S')", "result": [true] }, { "expression": "starts_with($.str, 'St')", "result": [true] }, { "expression": "starts_with($.str, 'Str')", "result": [true] }, { "expression": "starts_with($.str, 'String')", "result": [false] }, { "expression": "starts_with($.str, 0)", "result" : [] //"error": "invalid-type" }, { "expression": "min($.array)", "result" : [] //"error": "invalid-type" }, { "expression": "min($.empty_list)", "result": [null] }, { "expression": "min($.decimals)", "result": [-1.5] }, { "expression": "min($.strings)", "result": ["a"] }/*, { "expression": "type('abc')", "result": ["string"] }, { "expression": "type(`1.0`)", "result": ["number"] }, { "expression": "type(`2`)", "result": ["number"] }, { "expression": "type(`true`)", "result": ["boolean"] }, { "expression": "type(false)", "result": ["boolean"] }, { "expression": "type(null)", "result": ["null"] }, { "expression": "type([0])", "result": ["array"] }, { "expression": "type(`{\"a\": \"b\"}`)", "result": ["object"] }, { "expression": "type(@)", "result": ["object"] }, { "expression": "sort(keys($.objects))", "result": ["bar", "foo"] }*/, { "expression": "keys($.foo)", "result" : [] //"error": "invalid-type" }, { "expression": "keys($.strings)", "result" : [] //"error": "invalid-type" }, { "expression": "keys(false)", "result" : [] //"error": "invalid-type" }/*, { "expression": "sort(values($.objects))", "result": ["bar", "baz"] }*/, { "expression": "keys($.empty_hash)", "result": [[]] }/*, { "expression": "values($.foo)", "error": "invalid-type" }, { "expression": "join(', ', strings)", "result": "a, b, c" }, { "expression": "join(', ', strings)", "result": "a, b, c" }, { "expression": "join(',', `[\"a\", \"b\"]`)", "result": "a,b" }, { "expression": "join(',', `[\"a\", 0]`)", "error": "invalid-type" }, { "expression": "join(', ', str)", "error": "invalid-type" }, { "expression": "join('|', strings)", "result": "a|b|c" }, { "expression": "join(`2`, strings)", "error": "invalid-type" }, { "expression": "join('|', decimals)", "error": "invalid-type" }, { "expression": "join('|', decimals[].to_string(@))", "result": "1.01|1.2|-1.5" }, { "expression": "join('|', empty_list)", "result": "" }, { "expression": "reverse($.numbers)", "result": [5, 4, 3, -1] }, { "expression": "reverse($.array)", "result": ["100", "a", 5, 4, 3, -1] }, { "expression": "reverse(`[]`)", "result": [] }, { "expression": "reverse('')", "result": "" }, { "expression": "reverse('hello world')", "result": "dlrow olleh" }*/, { "expression": "sum($.numbers)", "result": [11] }, { "expression": "sum($.decimals)", "result": [0.71] }, { "expression": "sum($.array)", "result" : [] //"error": "invalid-type" }/*, { "expression": "sum($.array[].to_number(@))", "result": 111 }*/, { "expression": "sum([])", "result": [0] }/*, { "expression": "to_array('foo')", "result": ["foo"] }, { "expression": "to_array(`0`)", "result": [0] }, { "expression": "to_array($.objects)", "result": [{"foo": "bar", "bar": "baz"}] }, { "expression": "to_array(`[1, 2, 3]`)", "result": [1, 2, 3] }, { "expression": "to_array(false)", "result": [false] }, { "expression": "to_string('foo')", "result": "foo" }, { "expression": "to_string(1.2)", "result": "1.2" }, { "expression": "to_string(`[0, 1]`)", "result": "[0,1]" }, { "expression": "to_number('1.0')", "result": 1.0 }, { "expression": "to_number('1.1')", "result": 1.1 }, { "expression": "to_number('4')", "result": [4] }, { "expression": "to_number('notanumber')", "result": [] }, { "expression": "to_number(false)", "result": [] }, { "expression": "to_number(`null`)", "result": [] }, { "expression": "to_number(`[0]`)", "result": [] }, { "expression": "to_number(`{\"foo\": 0}`)", "result": [] }, { "expression": "\"to_string\"(`1.0`)", "error": "syntax" }, { "expression": "sort($.numbers)", "result": [-1, 3, 4, 5] }, { "expression": "sort($.strings)", "result": ["a", "b", ["c"]] }, { "expression": "sort($.decimals)", "result": [-1.5, 1.01, 1.2] }, { "expression": "sort($.array)", "error": "invalid-type" }, { "expression": "sort($.abc)", "error": "invalid-type" }, { "expression": "sort($.empty_list)", "result": [] }, { "expression": "sort(@)", "error": "invalid-type" }, { "expression": "not_null($.unknown_key, str)", "result": "Str" }, { "expression": "not_null($.unknown_key, foo.bar, empty_list, str)", "result": [] }, { "expression": "not_null($.unknown_key, null_key, empty_list, str)", "result": [] }, { "expression": "not_null(all, expressions, are_null)", "result": [] }, { "expression": "not_null()", "error": "invalid-arity" } */ ] } ] jsoncons-1.3.2/test/jsonpath/input/test_data/identifiers.json000066400000000000000000000632721477700171100245040ustar00rootroot00000000000000[ { "given" : {"": 42, "''": 123, "\"\"": 222}, "cases" : [ { "source" : "https://github.com/cburgmer/json-path-comparison", "comment" : "Bracket notation with empty string", "expression" : "$['']", "result" : [42] }, { "source" : "https://github.com/cburgmer/json-path-comparison", "comment" : "Bracket notation with empty string doubled quoted", "expression" : "$[\"\"]", "result" : [42] } ] }, { "given": { "key": "value" }, "cases": [ { "expression": "$key", "error": "Require dot after $" }, { "expression": "$.key", "result": ["value"], "path" : ["$['key']"] } ] }, { "source:" : "https://github.com/jmespath/jmespath.test", "given": { "__L": true }, "cases": [ { "expression": "$.__L", "result": [true], "path" : ["$['__L']"] } ] }, { "given": { "!\r": true }, "cases": [ { "expression": "$.\"!\\r\"", "result": [true] } ] }, { "given": { "Y_1623": true }, "cases": [ { "expression": "$.Y_1623", "result": [true] } ] }, { "given": { "x": true }, "cases": [ { "expression": "$.x", "result": [true] } ] }, { "given": { "\tF\uCebb": true }, "cases": [ { "expression": "$.\"\\tF\\uCebb\"", "result": [true] } ] }, { "given": { " \t": true }, "cases": [ { "expression": "$.\" \\t\"", "result": [true] } ] }, { "given": { " ": true }, "cases": [ { "expression": "$.\" \"", "result": [true] } ] }, { "given": { "v2": true }, "cases": [ { "expression": "$.v2", "result": [true] } ] }, { "given": { "\t": true }, "cases": [ { "expression": "$.\"\\t\"", "result": [true] } ] }, { "given": { "_X": true }, "cases": [ { "expression": "$._X", "result": [true] } ] }, { "given": { "\t4\ud9da\udd15": true }, "cases": [ { "expression": "$.\"\\t4\\ud9da\\udd15\"", "result": [true] } ] }, { "given": { "v24_W": true }, "cases": [ { "expression": "$.v24_W", "result": [true] } ] }, { "given": { "H": true }, "cases": [ { "expression": "$.\"H\"", "result": [true] } ] }, { "given": { "\f": true }, "cases": [ { "expression": "$.\"\\f\"", "result": [true] } ] }, { "given": { "E4": true }, "cases": [ { "expression": "$.\"E4\"", "result": [true] } ] }, { "given": { "!": true }, "cases": [ { "expression": "$.\"!\"", "result": [true] } ] }, { "given": { "tM": true }, "cases": [ { "expression": "$.tM", "result": [true] } ] }, { "given": { " [": true }, "cases": [ { "expression": "$.\" [\"", "result": [true] } ] }, { "given": { "R!": true }, "cases": [ { "expression": "$.\"R!\"", "result": [true] } ] }, { "given": { "_6W": true }, "cases": [ { "expression": "$._6W", "result": [true] } ] }, { "given": { "\uaBA1\r": true }, "cases": [ { "expression": "$.\"\\uaBA1\\r\"", "result": [true] } ] }, { "given": { "tL7": true }, "cases": [ { "expression": "$.tL7", "result": [true] } ] }, { "given": { "<": true }, "cases": [ { "expression": "$.\">\"", "result": [true] } ] }, { "given": { "hvu": true }, "cases": [ { "expression": "$.hvu", "result": [true] } ] }, { "given": { "; !": true }, "cases": [ { "expression": "$.\"; !\"", "result": [true] } ] }, { "given": { "hU": true }, "cases": [ { "expression": "$.hU", "result": [true] } ] }, { "given": { "!I\n\/": true }, "cases": [ { "expression": "$.\"!I\\n\\/\"", "result": [true] } ] }, { "given": { "\uEEbF": true }, "cases": [ { "expression": "$.\"\\uEEbF\"", "result": [true] } ] }, { "given": { "U)\t": true }, "cases": [ { "expression": "$.\"U)\\t\"", "result": [true] } ] }, { "given": { "fa0_9": true }, "cases": [ { "expression": "$.fa0_9", "result": [true] } ] }, { "given": { "/": true }, "cases": [ { "expression": "$.\"/\"", "result": [true] } ] }, { "given": { "Gy": true }, "cases": [ { "expression": "$.Gy", "result": [true] } ] }, { "given": { "\b": true }, "cases": [ { "expression": "$.\"\\b\"", "result": [true] } ] }, { "given": { "<": true }, "cases": [ { "expression": "$.\"<\"", "result": [true] } ] }, { "given": { "\t": true }, "cases": [ { "expression": "$.\"\\t\"", "result": [true] } ] }, { "given": { "\t&\\\r": true }, "cases": [ { "expression": "$.\"\\t&\\\\\\r\"", "result": [true] } ] }, { "given": { "#": true }, "cases": [ { "expression": "$.\"#\"", "result": [true] } ] }, { "given": { "B__": true }, "cases": [ { "expression": "$.B__", "result": [true] } ] }, { "given": { "\nS \n": true }, "cases": [ { "expression": "$.\"\\nS \\n\"", "result": [true] } ] }, { "given": { "Bp": true }, "cases": [ { "expression": "$.Bp", "result": [true] } ] }, { "given": { ",\t;": true }, "cases": [ { "expression": "$.\",\\t;\"", "result": [true] } ] }, { "given": { "B_q": true }, "cases": [ { "expression": "$.B_q", "result": [true] } ] }, { "given": { "\/+\t\n\b!Z": true }, "cases": [ { "expression": "$.\"\\/+\\t\\n\\b!Z\"", "result": [true] } ] }, { "given": { "\udadd\udfc7\\ueFAc": true }, "cases": [ { "expression": "$.\"\udadd\udfc7\\\\ueFAc\"", "result": [true] } ] }, { "given": { ":\f": true }, "cases": [ { "expression": "$.\":\\f\"", "result": [true] } ] }, { "given": { "\/": true }, "cases": [ { "expression": "$.\"\\/\"", "result": [true] } ] }, { "given": { "_BW_6Hg_Gl": true }, "cases": [ { "expression": "$._BW_6Hg_Gl", "result": [true] } ] }, { "given": { "\udbcf\udc02": true }, "cases": [ { "expression": "$.\"\udbcf\udc02\"", "result": [true] } ] }, { "given": { "zs1DC": true }, "cases": [ { "expression": "$.zs1DC", "result": [true] } ] }, { "given": { "__434": true }, "cases": [ { "expression": "$.__434", "result": [true] } ] }, { "given": { "\udb94\udd41": true }, "cases": [ { "expression": "$.\"\udb94\udd41\"", "result": [true] } ] }, { "given": { "Z_5": true }, "cases": [ { "expression": "$.Z_5", "result": [true] } ] }, { "given": { "z_M_": true }, "cases": [ { "expression": "$.z_M_", "result": [true] } ] }, { "given": { "YU_2": true }, "cases": [ { "expression": "$.YU_2", "result": [true] } ] }, { "given": { "_0": true }, "cases": [ { "expression": "$._0", "result": [true] } ] }, { "given": { "\b+": true }, "cases": [ { "expression": "$.\"\\b+\"", "result": [true] } ] }, { "given": { "\"": true }, "cases": [ { "expression": "$.\"\\\"\"", "result": [true] } ] }, { "given": { "D7": true }, "cases": [ { "expression": "$.D7", "result": [true] } ] }, { "given": { "_62L": true }, "cases": [ { "expression": "$._62L", "result": [true] } ] }, { "given": { "\tK\t": true }, "cases": [ { "expression": "$.\"\\tK\\t\"", "result": [true] } ] }, { "given": { "\n\\\f": true }, "cases": [ { "expression": "$.\"\\n\\\\\\f\"", "result": [true] } ] }, { "given": { "I_": true }, "cases": [ { "expression": "$.I_", "result": [true] } ] }, { "given": { "W_a0_": true }, "cases": [ { "expression": "$.W_a0_", "result": [true] } ] }, { "given": { "BQ": true }, "cases": [ { "expression": "$.BQ", "result": [true] } ] }, { "given": { "\tX$\uABBb": true }, "cases": [ { "expression": "$.\"\\tX$\\uABBb\"", "result": [true] } ] }, { "given": { "Z9": true }, "cases": [ { "expression": "$.Z9", "result": [true] } ] }, { "given": { "\b%\"\uda38\udd0f": true }, "cases": [ { "expression": "$.\"\\b%\\\"\uda38\udd0f\"", "result": [true] } ] }, { "given": { "_F": true }, "cases": [ { "expression": "$._F", "result": [true] } ] }, { "given": { "!,": true }, "cases": [ { "expression": "$.\"!,\"", "result": [true] } ] }, { "given": { "\"!": true }, "cases": [ { "expression": "$.\"\\\"!\"", "result": [true] } ] }, { "given": { "Hh": true }, "cases": [ { "expression": "$.Hh", "result": [true] } ] }, { "given": { "&": true }, "cases": [ { "expression": "$.\"&\"", "result": [true] } ] }, { "given": { "9\r\\R": true }, "cases": [ { "expression": "$.\"9\\r\\\\R\"", "result": [true] } ] }, { "given": { "M_k": true }, "cases": [ { "expression": "$.M_k", "result": [true] } ] }, { "given": { "!\b\n\udb06\ude52\"\"": true }, "cases": [ { "expression": "$.\"!\\b\\n\udb06\ude52\\\"\\\"\"", "result": [true] } ] }, { "given": { "6": true }, "cases": [ { "expression": "$.\"6\"", "result": [true] } ] }, { "given": { "_7": true }, "cases": [ { "expression": "$._7", "result": [true] } ] }, { "given": { "0": true }, "cases": [ { "expression": "$.\"0\"", "result": [true] } ] }, { "given": { "\\8\\": true }, "cases": [ { "expression": "$.\"\\\\8\\\\\"", "result": [true] } ] }, { "given": { "b7eo": true }, "cases": [ { "expression": "$.b7eo", "result": [true] } ] }, { "given": { "xIUo9": true }, "cases": [ { "expression": "$.xIUo9", "result": [true] } ] }, { "given": { "5": true }, "cases": [ { "expression": "$.\"5\"", "result": [true] } ] }, { "given": { "?": true }, "cases": [ { "expression": "$.\"?\"", "result": [true] } ] }, { "given": { "sU": true }, "cases": [ { "expression": "$.sU", "result": [true] } ] }, { "given": { "VH2&H\\\/": true }, "cases": [ { "expression": "$.\"VH2&H\\\\\\/\"", "result": [true] } ] }, { "given": { "_C": true }, "cases": [ { "expression": "$._C", "result": [true] } ] }, { "given": { "_": true }, "cases": [ { "expression": "$._", "result": [true] } ] }, { "given": { "<\t": true }, "cases": [ { "expression": "$.\"<\\t\"", "result": [true] } ] }, { "given": { "\uD834\uDD1E": true }, "cases": [ { "expression": "$.\"\\uD834\\uDD1E\"", "result": [true] } ] } ] jsoncons-1.3.2/test/jsonpath/input/test_data/indices.json000066400000000000000000000077561477700171100236220ustar00rootroot00000000000000[ { "given" : {"foo": ["zero","one","two"]}, "cases" : [ { "comment" : "Dot followed by index", "expression" : "$.foo.1", "result" : ["one"] } ] }, { "given" : {"0": "value"}, "cases" : [ { "source" : "https://github.com/cburgmer/json-path-comparison", "comment" : "Bracket notation with number on object", "expression" : "$[0]", "result" : [] // unquoted identifier can't start with digit } ] }, { "given": {"foo": {"bar": ["zero", "one", "two"]}}, "cases": [ { "expression": "$.foo.bar[0]", "result": ["zero"], "path" : ["$['foo']['bar'][0]"] }, { "expression": "$.foo.bar[1]", "result": ["one"], "path" : ["$['foo']['bar'][1]"] }, { "expression": "$.foo.bar[2]", "result": ["two"], "path" : ["$['foo']['bar'][2]"] }, { "expression": "$.foo.bar[3]", "result": [] }, { "expression": "$.foo.bar[-1]", "result": ["two"] }, { "expression": "$.foo.bar[-2]", "result": ["one"] }, { "expression": "$.foo.bar[-3]", "result": ["zero"] }, { "expression": "$.foo.bar[-4]", "result": [] } ] }, { "given": {"foo": [{"bar": "one"}, {"bar": "two"}, {"bar": "three"}, {"notbar": "four"}]}, "cases": [ { "expression": "$.foo.bar", "result": [] }, { "expression": "$.foo[0].bar", "result": ["one"] }, { "expression": "$.foo[1].bar", "result": ["two"] }, { "expression": "$.foo[2].bar", "result": ["three"] }, { "expression": "$.foo[3].notbar", "result": ["four"] }, { "expression": "$.foo[3].bar", "result": [] }, { "expression": "$.foo[0]", "result": [{"bar": "one"}] }, { "expression": "$.foo[1]", "result": [{"bar": "two"}] }, { "expression": "$.foo[2]", "result": [{"bar": "three"}] }, { "expression": "$.foo[3]", "result": [{"notbar": "four"}] }, { "expression": "$.foo[4]", "result": [] } ] }, { "given": [ "one", "two", "three" ], "cases": [ { "expression": "$[0]", "result": ["one"] }, { "expression": "$[1]", "result": ["two"] }, { "expression": "$[2]", "result": ["three"] }, { "expression": "$[-1]", "result": ["three"] }, { "expression": "$[-2]", "result": ["two"] }, { "expression": "$[-3]", "result": ["one"] } ] }, { "source" : "https://github.com/cburgmer/json-path-comparison", "given" : ["first", "second", "third"], "cases" : [ { "comment" : "Array index last", "expression" : "$[-1]", "result" : ["third"] } ] } ] jsoncons-1.3.2/test/jsonpath/input/test_data/parent-operator.json000066400000000000000000000047401477700171100253140ustar00rootroot00000000000000[ { "given" : [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95, "bookmark": [{ "page": 40, "owner": "bob" }] }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99, "bookmarks": [ { "page": 35, "owner": "bob" }, { "page": 45, "owner": "alice" } ] }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99, "bookmarks": [ { "page": 3035, "owner": "chuck" }, { "page": 45, "owner": "dennis" } ] } ], "cases" : [ { "source" : "https://github.com/cburgmer/json-path-comparison", "comment" : "Filter expression with parent operator", "expression" : "$[*].bookmarks[?(@.page == 45)]^^", "result" : [ { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99, "bookmarks": [ { "page": 35, "owner": "bob" }, { "page": 45, "owner": "alice" } ] }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99, "bookmarks": [ { "page": 3035, "owner": "chuck" }, { "page": 45, "owner": "dennis" } ] } ] } ] } ] jsoncons-1.3.2/test/jsonpath/input/test_data/recursive-descent.json000066400000000000000000000042031477700171100256160ustar00rootroot00000000000000[ { "given" : { "object": { "key": "value", "array": [ {"key": "something"}, {"key": {"key": "russian dolls"}} ] }, "key": "top" }, "cases" : [ { "comment" : "Dot notation after recursive descent", "expression" : "$..key", "result" : ["top","value","something",{"key":"russian dolls"},"russian dolls"], "path" : ["$['key']","$['object']['key']","$['object']['array'][0]['key']","$['object']['array'][1]['key']","$['object']['array'][1]['key']['key']"] } ] }, { "given" : [ "first", { "key": [ "first nested", { "more": [ { "nested": ["deepest", "second"] }, ["more", "values"] ] } ] } ], "cases" : [ { "comment" : "Bracket notation after recursive descent", "expression" : "$..[0]", "result" : ["first","first nested",{"nested":["deepest","second"]},"deepest","more"] } ] }, { "source" : "https://github.com/cburgmer/json-path-comparison", "given" : { "key": "value", "another key": {"complex": "string", "primitives": [0, 1]}}, "cases" : [ { "comment" : "jsonpath recursive descent with *", "expression" : "$..*", "result" : [{"complex":"string","primitives":[0,1]},"value","string",[0,1],0,1] } ] }, { "given" : [[1, 2, 3], [4, 5, 6]], "cases" : [ { "comment" : "jsonpath ending with recursive descent", "expression" : "$..", "result" : [[[1,2,3],[4,5,6]],[1,2,3],[4,5,6]] } ] } ] jsoncons-1.3.2/test/jsonpath/input/test_data/regex.json000066400000000000000000000065501477700171100233050ustar00rootroot00000000000000[ /*{ "given" : [ {"name": "hullo world"}, {"name": "hello world"}, {"name": "yes hello world"}, {"name": "HELLO WORLD"}, {"name": "good bye"} ], "cases" : [ { "comment" : "Filter expression with regular expression", "expression" : "$[?(@.name=~/hello.* /)]", "result" : [ { "name": "hello world" }, { "name": "yes hello world" } ] }, { "comment" : "Filter expression with regular expression", "expression" : "$[?(@.name=~/hello.* /i)]", "result" : [ {"name": "hello world"}, {"name": "yes hello world"}, {"name": "HELLO WORLD"} ] } ] }, { "given" : { "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ], "bicycle": { "color": "red", "price": 19.95 } } }, "cases" : [ { "comment" : "Filter expression with regular expression", "expression" : "$.store.book[ ?(@.category =~ /fic.*?/)].author", "result" : ["Evelyn Waugh","Herman Melville","J. R. R. Tolkien"] }, { "comment" : "Filter expression with regular expression", "expression" : "$.store.book[ ?(@.author =~ /Evelyn.*?/)].author", "result" : ["Evelyn Waugh"] }, { "comment" : "Filter expression with regular expression", "expression" : "$.store.book[ ?(!(@.author =~ /Evelyn.*?/))].author", "result" : ["Nigel Rees","Herman Melville","J. R. R. Tolkien"] } ] },*/ { "given" : "The cat sat on the mat", "cases" : [ { "comment" : "tokenize", "expression" : "tokenize($,'\\\\s+')[*]", "result" : ["The","cat","sat","on","the","mat"] } ] } ] jsoncons-1.3.2/test/jsonpath/input/test_data/slice.json000066400000000000000000000200251477700171100232630ustar00rootroot00000000000000[ { "given" : [2, "a", 4, 5, 100, "nice"], "cases" : [ { "source" : "https://github.com/cburgmer/json-path-comparison", "comment" : "Array slice with negative start and end and range of -1", "expression" : "$[-4:-5]", "result" : [] }, { "source" : "https://github.com/cburgmer/json-path-comparison", "comment" : "Array slice with negative start and end and range of 0", "expression" : "$[-4:-4]", "result" : [] }, { "comment" : "Array slice with negative start and end and range of 1", "expression" : "$[-4:-3]", "result" : [4] }, { "source" : "https://github.com/cburgmer/json-path-comparison", "comment" : "Array slice with negative start and positive end and range of -1", "expression" : "$[-4:1]", "result" : [] } ] }, { "source" : "https://github.com/cburgmer/json-path-comparison", "given" : ["first", "second", "third", "forth", "fifth"], "cases" : [ { "comment" : "Last item", "expression" : "$[-1]", "result" : ["fifth"] }, { "comment" : "Last two items", "expression" : "$[-2:]", "result" : ["forth", "fifth"], "path" : ["$[3]", "$[4]"] }, { "comment" : "Last two items, nodups", "expression" : "$[-2:]", "result" : ["forth", "fifth"], "path" : ["$[3]", "$[4]"], "nodups" : true }, { "comment" : "All items except the last two", "expression" : "$[:-2]", "result" : ["first", "second", "third"] }, { "comment" : "All items, reversed", "expression" : "$[::-1]", "result" : ["fifth","forth","third","second","first"] }, { "comment" : "First two items, reversed", "expression" : "$[1::-1]", "result" : ["second","first"] }, { "comment" : "Last two items, reversed", "expression" : "$[:-3:-1]", "result" : ["fifth","forth"] }, { "comment" : "All items except the last two, reversed", "expression" : "$[-3::-1]", "result" : ["third","second","first"] }, { "comment" : "array index", "expression" : "$[2]", "result" : ["third"] }, { "comment" : "Array index slice start end step 0", "expression" : "$[0:3:0]", "error" : "Slice step cannot be zero at line 1 and column 8" }, { "comment" : "Array slice with negative step", "expression" : "$[3:0:-2]", "result" : ["forth","second"] }, { "comment" : "Array slice with negative step on partially overlapping array", "expression" : "$[7:3:-1]", "result" : ["fifth"] }, { "comment" : "Array slice with negative step and start greater than end", "expression" : "$[0:3:-2]", "result" : [] }, { "comment" : "Array slice with negative step and start greater than end", "expression" : "$[0:3:-2]", "result" : [] }, { "comment" : "Array slice with negative step and start greater than end", "expression" : "$[::-2]", "result" : ["fifth","third","first"] }, { "comment" : "Array slice with open end", "expression" : "$[1:]", "result" : ["second", "third", "forth", "fifth"] }, { "comment" : "Array slice with open end and negative step", "expression" : "$[3::-1]", "result" : ["forth","third","second","first"] }, { "comment" : "Array slice with open start", "expression" : "$[:2]", "result" : ["first", "second"] } ] }, { "given" : ["first", "second"], "cases" : [ { "comment" : "Array slice with open start and end", "expression" : "$[:]", "result" : ["first", "second"] }, { "comment" : "Array slice with open start and end and step empty", "expression" : "$[::]", "result" : ["first", "second"] } ] }, { "given" : ["first", "second", "third", "forth", "fifth"], "cases" : [ { "comment" : "Array slice", "expression" : "$[1:3]", "result" : ["second","third"] }, { "comment" : "Array slice on exact match", "expression" : "$[0:5]", "result" : ["first","second","third","forth","fifth"] }, { "comment" : "Array slice with large number for end", "expression" : "$[2:113667776004]", "result" : ["third","forth","fifth"] }, { "comment" : "Array slice with large number for end and negative step", "expression" : "$[2:-113667776004:-1]", "result" : ["third","second","first"] }, { "comment" : "Array slice with large number for start", "expression" : "$[-113667776004:2]", "result" : ["first","second"] }, { "comment" : "Array slice with large number for start end negative step", "expression" : "$[113667776004:2:-1]", "result" : ["fifth","forth"] } ] }, { "given" : ["first", "second", "third"], "cases" : [ { "comment" : "Array slice on non overlapping array", "expression" : "$[7:10]", "result" : [] }, { "comment" : "Array slice on partially overlapping array", "expression" : "$[1:10]", "result" : ["second","third"] } ] }, { "given" : {":": 42, "more": "string", "a": 1, "b": 2, "c": 3, "1:3": "nice"}, "cases" : [ { "comment" : "Array slice on object", "expression" : "$[1:3]", "result" : [] } ] }, { "given" : [{"key": "ey"}, {"key": "bee"}, {"key": "see"}], "cases" : [ { "comment" : "Dot notation after array slice", "expression" : "$[0:2].key", "result" : ["ey","bee"] } ] }, { "given": { "foo": [{"a": 1}, {"a": 2}, {"a": 3}], "bar": [{"a": {"b": 1}}, {"a": {"b": 2}}, {"a": {"b": 3}}], "baz": 50 }, "cases": [ { "expression": "$.foo[:2].a", "result": [1, 2] }, { "expression": "$.foo[:2].b", "result": [] }, { "expression": "$.foo[:2].a.b", "result": [] }, { "expression": "$.bar[::-1].a.b", "result": [3, 2, 1] } , { "expression": "$.bar[:2].a.b", "result": [1, 2] }, { "expression": "$.baz[:2].a", "result": [] } ] } ] jsoncons-1.3.2/test/jsonpath/input/test_data/syntax.json000066400000000000000000000027101477700171100235130ustar00rootroot00000000000000[ { "comment": "Empty string", "given": {"type": "object"}, "cases": [ { "expression": "", "error": "syntax" }, { "expression": " ", "error": "syntax" } ] }, { "comment": "Dot syntax", "given": {"type": "object"}, "cases": [ { "expression": "$.foo.bar", "result": [] }, { "expression": "foo.1", "error": "syntax" }, { "expression": "$.foo.1", "result": [] } ] }, { "comment": "Filter expression with single equal", "given": [{"key": 0},{"key": 42}], "cases": [ { "expression": "$[?(@.key=42)]", "error": "syntax" } ] }, { "comment": "Bracket notation without quotes", "given": {"key1": "value1", "key2": "value2"}, "cases": [ { "expression": "$[key1]", "error": "syntax" }, { "expression": "$['key1',key2]", "error": "syntax" } ] }, { "comment": "Identifiers", "given": {"type": "object"}, "cases": [ { "expression": "$.foo", "result": [] }, { "expression": "$.\"foo\"", "result": [] }, { "expression": "$.\"\\\\\"", "result": [] }, { "expression": "$.\"\\u\"", "error": "syntax" } ] } ] jsoncons-1.3.2/test/jsonpath/input/test_data/union.json000066400000000000000000000262761477700171100233320ustar00rootroot00000000000000[ { "given" : [{"key": "ey"}, {"key": "bee"}, {"key": "see"}], "cases" : [ { "comment" : "Dot notation after union", "expression" : "$[0,2].key", "result" : ["ey","see"], "path" : ["$[0]['key']","$[2]['key']"] } ] }, { "given" : { "one": {"key": "value"}, "two": {"k": "v"}, "three": {"some": "more", "key": "other value"} } , "cases" : [ { "comment" : "Dot notation after union with keys", "expression" : "$['one','three'].key", "result" : ["value","other value"] } ] }, { "given" : ["a"], "cases" : [ { "comment" : "Union with duplication from array", "expression" : "$[0,0]", "result" : ["a","a"] } ] }, { "given" : ["a"], "cases" : [ { "comment" : "Union with duplication from array and nodups", "expression" : "$[0,0]", "nodups" : true, "result" : ["a"] } ] }, { "given" : [{"key": 1}, {"key": 8}, {"key": 3}, {"key": 10}, {"key": 7}, {"key": 2}, {"key": 6}, {"key": 4}], "cases" : [ { "comment" : "Union with filter", "expression" : "$[?(@.key<3),?(@.key>6)]", "result" : [ { "key": 1 }, { "key": 2 }, { "key": 8 }, { "key": 10 }, { "key": 7 } ] } ] }, { "given" : {"key": "value","another": "entry"}, "cases" : [ { "comment" : "Union with keys", "expression" : "$['key','another']", "result" : ["value","entry"] }, { "comment" : "Union with keys", "expression" : "$[\"key\",\"another\"]", "result" : ["value","entry"] }, { "comment" : "Union with keys", "expression" : "$[key,another]", "error" : "syntax error" }, { "comment" : "Union with keys on object without key", "expression" : "$['missing','key']", "result" : ["value"] } ] }, { "given" : [{"c":"cc1","d":"dd1","e":"ee1"},{"c":"cc2","d":"dd2","e":"ee2"}], "cases" : [ { "comment" : "Union with keys after array slice", "expression" : "$[:]['c','d']", "result" : ["cc1","dd1","cc2","dd2"] }, { "comment" : "Union with keys after bracket notation", "expression" : "$[0]['c','d']", "result" : ["cc1","dd1"] }, { "comment" : "Union with keys after dot notation with wildcard", "expression" : "$.*['c','d']", "result" : ["cc1","dd1","cc2","dd2"] } ] }, { "given" : [{"c":"cc1","d":"dd1","e":"ee1"}, {"c": "cc2", "child": {"d": "dd2"}}, {"c": "cc3"}, {"d": "dd4"}, {"child": {"c": "cc5"}}], "cases" : [ { "comment" : "Union with keys after recursive descent", "expression" : "$..['c','d']", "result" : ["cc1","dd1","cc2","dd2","cc3","dd4","cc5"] } ] }, { "given" : [1,2,3,4,5], "cases" : [ { "comment" : "Union with numbers in decreasing order", "expression" : "$[4,1]", "result" : [5,2] } ] }, { "given" : {"a": ["string",null,true],"b": [false,"string",5.4]}, "cases" : [ { "comment" : "Union with repeated matches after dot notation with wildcard", "expression" : "$.*[0,:5]", "result" : ["string","string",null,true,false,false,"string",5.4] }, { "comment" : "Union with repeated matches after dot notation with wildcard", "expression" : "$.*[0,:5]", "nodups" : true, "result" : ["string",null,true,false,"string",5.4] } ] }, { "given" : [1,2,3,4,5], "cases" : [ { "comment" : "Union with slice and number", "expression" : "$[1:3,4]", "result" : [2,3,5] } ] }, { "given" : ["first", "second", "third"], "cases" : [ { "comment" : "Union with spaces", "expression" : "$[ 0 , 1 ]", "result" : ["first","second"] } ] }, { "given" : {"key1":"first", "key2":"second", "key3":"third"}, "cases" : [ { "comment" : "Union with spaces", "expression" : "$[ key1 , key2 ]", "error" : "syntax error" }, { "comment" : "Union with spaces", "expression" : "$[ 'key1' , 'key2' ]", "result" : ["first","second"] }, { "comment" : "Union with spaces", "expression" : "$[ \"key1\" , \"key2\" ]", "result" : ["first","second"] } ] }, { "given" : { "firstName": "John", "lastName" : "doe", "age" : 26, "address" : { "streetAddress": "naist street", "city" : "Nara", "postalCode" : "630-0192" }, "phoneNumbers": [ { "type" : "iPhone", "number": "0123-4567-8888" }, { "type" : "home", "number": "0123-4567-8910" } ] }, "cases" : [ { "comment" : "JSONPath union of multiple different paths", "expression" : "$[@.firstName,@.address.city]", "result" : ["John","Nara"] } ] }, { "given": { "foo": {"bar": 1, "baz": [2, 3, 4]} }, "cases": [ { "expression": "$.foo[@.bar,@.baz[1]]", "result": [1, 3] }, { "expression": "$.foo[@.bar,@.baz[2]]", "result": [1, 4] }, { "expression": "$.foo[@.bar,@.baz[3]]", "result": [1] } ] }, { "given": { "foo": { "bar": {"baz": [{"common": "first", "one": 1}, {"common": "second", "two": 2}]}, "ignoreme": 1, "includeme": true } }, "cases": [ { "expression": "$.foo['includeme', @.bar.baz[*].common]", "result": [true, "first", "second"] }, { "expression": "$.foo['includeme', @.bar.baz[*].none]", "result": [true] } ] }, // no duplicates { "given": { "a": [ "string", null, true ], "b": [ false, "string", 5.4 ] }, "cases": [ { "expression": "$.*[0,:5]", "result": ["string","string",null,true,false,false,"string",5.4] }, { "nodups" : true, "expression": "$.*[0,:5]", "result": [ "string", null, true, false, "string", 5.4 ] } ] }, { "given" : { "name": "John", "age" : 26, "address" : { "city" : "Nara" } }, "cases" : [ { "comment" : "JSONPath union of multiple different paths", "expression" : "$['name',@.address.city]", "result" : ["John","Nara"] }, { "comment" : "JSONPath union of multiple different paths", "expression" : "$['name',*]", "result" : ["John",{"city":"Nara"},26,"John"] }, { "comment" : "JSONPath union of multiple different paths", "expression" : "$['name',?(@.name == 'John')]", "result" : ["John"] }, { "comment" : "JSONPath union of multiple different paths", "expression" : "$['name',?(@.city == 'Nara')]", "result" : ["John",{"city":"Nara"}] } ] }, { "given": ["first", "second", "third", "forth", "fifth"], "cases": [ { "comment" : "union with expression", "expression": "$[(@.length - 1),(@.length - 2)]", "result": ["fifth","forth"] } ] }, { "given": { "books": [ {"title" : "A Wild Sheep Chase"}, {"title" : "The Night Watch"}, {"title" : "The Comedians"}, {"title" : "The Night Watch"}, {"title" : "Norwegian Wood"}, {"title" : "Infinite Jest"}, {"title" : "Kafka on the Shore"}, {"title" : "Life"}, {"title" : "The Immortal Life of Henrietta Lacks"}, {"title" : "I Am a Cat"} ] }, "cases": [ { "comment" : "union with path and no duplicates", "expression": "$['books',@['books'][0]]", "path" : ["$['books']","$['books'][0]"], "nodups" : true }, { "comment" : "union with path and no duplicates", "expression": "$[@['books'][0],'books']", "path" : ["$['books'][0]","$['books']"], "nodups" : true }, { "comment" : "union with path and no duplicates", "expression": "$['books',@['books'][0]]", "path" : ["$['books']","$['books'][0]"], "nodups" : true, "sort" : true }, { "comment" : "union with path, no duplicates, and sort", "expression": "$[@['books'][0],'books']", "path" : ["$['books']","$['books'][0]"], "nodups" : true, "sort" : true } ] } ] jsoncons-1.3.2/test/jsonpath/input/test_data/wildcard.json000066400000000000000000000063511477700171100237630ustar00rootroot00000000000000[ { "given" : [ "string", 42, { "key": "value" }, [0, 1] ], "cases" : [ { "comment" : "Bracket notation with wildcard on array", "expression" : "$[*]", "result" : [ "string", 42, { "key": "value" }, [ 0, 1 ] ] } ] }, { "given" : [{"bar": [42]}], "cases" : [ { "comment" : "Bracket notation with wildcard after dot notation after bracket notation with wildcard", "expression" : "$[*].bar[*]", "result" : [42] } ] }, { "given" : [ "string", 42, { "key": "value" }, [0, 1] ], "cases" : [ { "comment" : "Dot notation with wildcard on array", "expression" : "$.*", "result" : [ "string", 42, { "key": "value" }, [ 0, 1 ] ] } ] }, { "source" : "https://github.com/cburgmer/json-path-comparison", "given" : [40,null,42], "cases" : [ { "comment" : "Wildcard bracket notation on null value array", "expression" : "$[*]", "result" : [40,null,42] } ] }, { "source" : "https://github.com/cburgmer/json-path-comparison", "given" : { "some": "string","int": 42,"object": {"key": "value"},"array": [0, 1]}, "cases" : [ { "comment" : "Wildcard bracket notation on object", "expression" : "$[*]", "result" : [[0,1],42,{"key":"value"},"string"] } ] }, { "given" : [{"bar": [{"baz": "hello"}]}], "cases" : [ { "comment" : "Wildcard bracket notation with key on nested objects", "expression" : "$[*].bar[*].baz", "result" : ["hello"] } ] }, { "given" : ["string",42,{"key": "value"},[0, 1]], "cases" : [ { "comment" : "Wildcard dot notation on array", "expression" : "$.*", "result" : ["string",42,{"key":"value"},[0,1]] } ] }, { "source" : "https://github.com/cburgmer/json-path-comparison", "given" : { "some": "string","int": 42,"object": {"key": "value"},"array": [0, 1]}, "cases" : [ { "comment" : "Wildcard dot notation on object", "expression" : "$.*", "result" : [[0,1],42,{"key":"value"},"string"] } ] } ] jsoncons-1.3.2/test/jsonpath/src/000077500000000000000000000000001477700171100167525ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonpath/src/json_location_parser_tests.cpp000066400000000000000000000040311477700171100251130ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include using namespace jsoncons; TEST_CASE("jsonpath json_location_parser tests") { SECTION("test 1") { jsonpath::detail::json_location_parser> parser; std::error_code ec; std::vector location = parser.parse(R"($['foo'][3]["bar"])", ec); REQUIRE_FALSE(ec); CHECK(3 == location.size()); CHECK(location[0].has_name()); CHECK(location[0].name() == "foo"); CHECK(location[1].has_index()); CHECK(3 == location[1].index()); CHECK(location[2].has_name()); CHECK(location[2].name() == "bar"); } SECTION("test dot") { jsonpath::detail::json_location_parser> parser; std::error_code ec; std::vector location = parser.parse(R"($.'foo'.3.bar)", ec); REQUIRE_FALSE(ec); CHECK(3 == location.size()); CHECK(location[0].has_name()); CHECK(location[0].name() == "foo"); CHECK(location[1].has_index()); CHECK(3 == location[1].index()); CHECK(location[2].has_name()); CHECK(location[2].name() == "bar"); } SECTION("test errors") { jsonpath::detail::json_location_parser> parser; std::error_code ec; parser.parse("['foo'][3]['bar']", ec); CHECK(ec.value() == (int)jsonpath::jsonpath_errc::expected_root_or_current_node); parser.parse("$['foo'][-3]['bar']", ec); CHECK(ec.value() == (int)jsonpath::jsonpath_errc::expected_single_quote_or_digit); parser.parse("$['foo'][3a]['bar']", ec); CHECK(ec.value() == (int)jsonpath::jsonpath_errc::expected_rbracket); parser.parse("$['foo'][3]['bar'", ec); CHECK(ec.value() == (int)jsonpath::jsonpath_errc::unexpected_eof); } } jsoncons-1.3.2/test/jsonpath/src/json_location_tests.cpp000066400000000000000000000267111477700171100235500ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include using namespace jsoncons; #if 0 TEST_CASE("json_location tests") { SECTION("test 1") { jsonpath::json_location loc; loc.append("foo").append(1); CHECK(2 == loc.size()); CHECK(loc[0].has_name()); CHECK(loc[0].name() == "foo"); CHECK(loc[1].has_index()); CHECK(1 == loc[1].index()); } } TEST_CASE("json_location parse tests") { SECTION("test 1") { jsonpath::json_location loc; loc.append("foo").append(1); jsonpath::json_location loc2 = jsonpath::json_location::parse("$['foo'][1]"); CHECK(loc2 == loc); } } TEST_CASE("json_location remove tests") { std::string json_string = R"( { "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 } ] } } )"; json doc = json::parse(json_string); SECTION("store book 1") { jsonpath::json_location loc; loc.append("store").append("book").append(1); CHECK(3 == doc["store"]["book"].size()); CHECK(doc["store"]["book"][1]["author"].as() == "Evelyn Waugh"); std::size_t count = jsonpath::remove(doc, loc); CHECK(1 == count); CHECK(2 == doc["store"]["book"].size()); CHECK(doc["store"]["book"][1]["author"].as() == "Herman Melville"); } SECTION("store book 2") { jsonpath::json_location loc; loc.append("store").append("book").append(2); CHECK(3 == doc["store"]["book"].size()); CHECK(doc["store"]["book"][2]["author"].as() == "Herman Melville"); std::size_t count = jsonpath::remove(doc, loc); CHECK(1 == count); CHECK(2 == doc["store"]["book"].size()); CHECK(doc["store"]["book"][1]["author"].as() == "Evelyn Waugh"); } SECTION("store book 3") { json orig = doc; jsonpath::json_location loc; loc.append("store").append("book").append(3); CHECK(3 == doc["store"]["book"].size()); CHECK(doc["store"]["book"][2]["author"].as() == "Herman Melville"); std::size_t count = jsonpath::remove(doc, loc); CHECK(0 == count); CHECK(doc == orig); } SECTION("store") { jsonpath::json_location loc; loc.append("store"); std::size_t count = jsonpath::remove(doc, loc); CHECK(1 == count); CHECK(0 == doc.size()); } SECTION("store book") { jsonpath::json_location loc; loc.append("store").append("book"); CHECK(3 == doc["store"]["book"].size()); std::size_t count = jsonpath::remove(doc, loc); CHECK(1 == count); CHECK(0 == doc["store"]["book"].size()); } SECTION("store lost&found") { json orig = doc; jsonpath::json_location loc; loc.append("store").append("lost&found"); CHECK(1 == doc["store"].size()); std::size_t count = jsonpath::remove(doc, loc); CHECK(0 == count); CHECK(doc == orig); } SECTION("store book 2 price") { jsonpath::json_location loc; loc.append("store").append("book").append(2).append("price"); CHECK(3 == doc["store"]["book"].size()); CHECK(doc["store"]["book"][2]["author"].as() == "Herman Melville"); CHECK(doc["store"]["book"][2].contains("price")); std::size_t count = jsonpath::remove(doc, loc); CHECK(1 == count); CHECK(3 == doc["store"]["book"].size()); CHECK(doc["store"]["book"][2]["author"].as() == "Herman Melville"); CHECK_FALSE(doc["store"]["book"][2].contains("price")); } SECTION("store 0") { json orig = doc; jsonpath::json_location loc; loc.append("store").append(0); CHECK(3 == doc["store"]["book"].size()); CHECK(doc["store"]["book"][2].contains("price")); std::size_t count = jsonpath::remove(doc, loc); CHECK(0 == count); CHECK(doc == orig); } } TEST_CASE("json_location select tests") { std::string json_string = R"( { "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 } ] } } )"; json doc = json::parse(json_string); SECTION("store book 1") { jsonpath::json_location loc; loc.append("store").append("book").append(1); auto result = jsonpath::get(doc, loc); CHECK(result.second); CHECK(*result.first == doc.at("store").at("book").at(1)); } SECTION("store book 2") { jsonpath::json_location loc; loc.append("store").append("book").append(2); auto result = jsonpath::get(doc, loc); CHECK(result.second); CHECK(*result.first == doc.at("store").at("book").at(2)); } SECTION("store book 3") { jsonpath::json_location loc; loc.append("store").append("book").append(3); auto result = jsonpath::get(doc, loc); CHECK(result == nullptr); } SECTION("store") { jsonpath::json_location loc; loc.append("store"); auto result = jsonpath::get(doc, loc); CHECK(result.second); CHECK(*result.first == doc.at("store")); } SECTION("store book") { jsonpath::json_location loc; loc.append("store").append("book"); auto result = jsonpath::get(doc, loc); CHECK(result.second); CHECK(*result.first == doc.at("store").at("book")); } SECTION("store lost&found") { jsonpath::json_location loc; loc.append("store").append("lost&found"); auto result = jsonpath::get(doc, loc); CHECK(result == nullptr); } SECTION("store book 2 price") { jsonpath::json_location loc; loc.append("store").append("book").append(2).append("price"); auto result = jsonpath::get(doc, loc); CHECK(result.second); CHECK(*result.first == doc.at("store").at("book").at(2).at("price")); } SECTION("store 0") { jsonpath::json_location loc; loc.append("store").append(0); auto result = jsonpath::get(doc, loc); CHECK(result == nullptr); } } TEST_CASE("test json_location from path_node") { SECTION("test 1") { jsonpath::path_node a1{}; jsonpath::path_node a2(&a1,"foo"); jsonpath::path_node a3(&a2,"bar"); jsonpath::path_node a4(&a3,7); jsonpath::json_location location; location.append("foo").append("bar").append(7); std::string jsonpath_string = "$['foo']['bar'][7]"; CHECK((jsonpath::json_location{ a4 } == location)); CHECK((jsonpath::to_string(location) == jsonpath_string)); } } #endif TEST_CASE("json_location replace tests") { std::string json_string = R"( {"books": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour" }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 } ] } )"; json doc = json::parse(json_string); SECTION("store book 1") { jsonpath::json_location loc = jsonpath::json_location::parse("$.books[0].price"); json new_value{13.0}; //std::cout << to_string(loc) << "\n"; auto result1 = jsonpath::replace(doc, loc, new_value, false); CHECK(result1.second); bool test1 = result1.first == std::addressof(doc.at("books").at(0).at("price")); CHECK(test1); CHECK(doc.at("books").at(0).at("price") == new_value); auto result2 = jsonpath::replace(doc, loc, new_value, true); CHECK(result2.second); bool test2 = result2.first == std::addressof(doc.at("books").at(0).at("price")); CHECK(test2); //std::cout << pretty_print(doc) << "\n"; } SECTION("test 2") { jsonpath::json_location loc = jsonpath::json_location::parse("$.books[1].price"); json new_value{13.0}; //std::cout << to_string(loc) << "\n"; auto result1 = jsonpath::replace(doc, loc, new_value, false); CHECK_FALSE(result1.second); //std::cout << pretty_print(doc) << "\n"; auto result2 = jsonpath::replace(doc, loc, new_value, true); CHECK(result2.second); bool test2 = result2.first == std::addressof(doc.at("books").at(1).at("price")); CHECK(test2); CHECK(doc.at("books").at(1).at("price") == new_value); //std::cout << pretty_print(doc) << "\n"; } SECTION("test 3") { jsonpath::json_location loc = jsonpath::json_location::parse("$.books[1].kindle.price"); json new_value{13.0}; //std::cout << pretty_print(doc) << "\n"; auto result1 = jsonpath::replace(doc, loc, new_value, false); CHECK_FALSE(result1.second); //std::cout << pretty_print(doc) << "\n"; auto result2 = jsonpath::replace(doc, loc, new_value, true); CHECK(result2.second); bool test2 = result2.first == std::addressof(doc.at("books").at(1).at("kindle").at("price")); CHECK(test2); CHECK(doc.at("books").at(1).at("kindle").at("price") == new_value); //std::cout << pretty_print(doc) << "\n"; } SECTION("test 4") { jsonpath::json_location loc = jsonpath::json_location::parse("$.books[2]"); json new_value{}; //std::cout << to_string(loc) << "\n"; auto result1 = jsonpath::replace(doc, loc, new_value, false); CHECK(result1.second); bool test1 = result1.first == std::addressof(doc.at("books").at(2)); CHECK(test1); //std::cout << pretty_print(doc) << "\n"; CHECK(doc.at("books").at(2) == new_value); auto result2 = jsonpath::replace(doc, loc, new_value, true); CHECK(result2.second); bool test2 = result2.first == std::addressof(doc.at("books").at(2)); CHECK(test2); CHECK(doc.at("books").at(2) == new_value); //std::cout << pretty_print(doc) << "\n"; } SECTION("test 5") { jsonpath::json_location loc = jsonpath::json_location::parse("$.books[3]"); json new_value{}; //std::cout << to_string(loc) << "\n"; auto result1 = jsonpath::replace(doc, loc, new_value, false); CHECK_FALSE(result1.second); auto result2 = jsonpath::replace(doc, loc, new_value, true); CHECK_FALSE(result2.second); //std::cout << pretty_print(doc) << "\n"; } } jsoncons-1.3.2/test/jsonpath/src/jsonpath_custom_function_tests.cpp000066400000000000000000000040171477700171100260270ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include #include // std::unordered_set #include #include using json = jsoncons::json; namespace jsonpath = jsoncons::jsonpath; TEST_CASE("jsonpath custom function test") { json root; JSONCONS_TRY { root = json::parse(R"({ "foo": 60,"bar": 10 })"); } JSONCONS_CATCH (const jsoncons::ser_error& e) { std::cout << e.what() << '\n'; } jsonpath::custom_functions functions; functions.register_function("divide", // function name 2, // number of arguments [](jsoncons::span> params, std::error_code& ec) -> json { if (!(params[0].value().is_number() && params[1].value().is_number())) { ec = jsonpath::jsonpath_errc::invalid_type; return json::null(); } return json(params[0].value().as() / params[1].value().as()); } ); SECTION("test 1") { auto expr = jsonpath::make_expression("divide(@.foo, @.bar)", functions); auto r = expr.evaluate(root); REQUIRE(!r.empty()); CHECK(json(6) == r[0]); } SECTION("test 2") { auto r = jsonpath::json_query(root, "divide($.foo, $.bar)", jsonpath::result_options(), functions); REQUIRE(!r.empty()); CHECK(json(6) == r[0]); } SECTION("test 3") { json r; jsonpath::json_query(root, "divide($.foo, $.bar)", [&](const std::string&, const json& val) {r = val; }, jsonpath::result_options(), functions); CHECK(json(6) == r); } } jsoncons-1.3.2/test/jsonpath/src/jsonpath_expression_tests.cpp000066400000000000000000000344011477700171100250070ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include #include #include // std::unordered_set #include namespace jsonpath = jsoncons::jsonpath; TEST_CASE("jsonpath make_expression::evaluate tests") { std::string input = R"( { "books": [ { "category": "fiction", "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "category": "fiction", "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "category": "fiction", "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "category": "memoir", "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } )"; SECTION("test 1") { int count = 0; const auto root = jsoncons::json::parse(input); const auto original = root; auto expr = jsoncons::jsonpath::make_expression("$.books[*]"); auto op = [&](const std::string& /*location*/, const jsoncons::json& book) { if (book.at("category") == "memoir" && !book.contains("price")) { ++count; } }; expr.evaluate(root, op); CHECK(1 == count); CHECK(root == original); } SECTION("evaluate with std::error_code") { int count = 0; const auto root = jsoncons::json::parse(input); const auto original = root; std::error_code ec; auto expr = jsoncons::jsonpath::make_expression("$.books[*]", ec); CHECK_FALSE(ec); auto op = [&](const std::string& /*location*/, const jsoncons::json& book) { if (book.at("category") == "memoir" && !book.contains("price")) { ++count; } }; expr.evaluate(root, op); CHECK(1 == count); CHECK(root == original); } SECTION("with json_const_pointer_arg") { auto root = jsoncons::json::parse(input); auto nested_json = jsoncons::json::parse(R"( { "category": "religion", "title" : "How the Gospels Became History: Jesus and Mediterranean Myths", "author" : "M. David Litwa", "price" : 60.89 } )"); root["books"].emplace_back(jsoncons::json_const_pointer_arg, &nested_json); std::error_code ec; auto expr = jsoncons::jsonpath::make_expression("$.books[*]", ec); CHECK_FALSE(ec); std::size_t count = 0; auto op = [&](const std::string& /*location*/, const jsoncons::json& book) { if (book.at("category") == "religion") { ++count; } }; expr.evaluate(root, op); CHECK(1 == count); } } TEST_CASE("jsonpath_expression::select tests") { std::string input = R"( { "books": [ { "category": "fiction", "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "category": "fiction", "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "category": "fiction", "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "category": "memoir", "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } )"; SECTION("test 1") { int count = 0; const auto root = jsoncons::json::parse(input); auto expr = jsoncons::jsonpath::make_expression("$.books[*]"); auto op = [&](const jsonpath::path_node& /*path*/, const jsoncons::json& value) { if (value.at("category") == "memoir" && !value.contains("price")) { ++count; //std::cout << jsonpath::to_string(path) << ": " << value << "\n"; } }; expr.select(root, op); CHECK(1 == count); } } TEST_CASE("jsonpath_expression::select_path tests") { std::string input = R"( { "books": [ { "category": "fiction", "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "category": "fiction", "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "category": "fiction", "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "category": "memoir", "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } )"; SECTION("Return locations of selected values") { auto root = jsoncons::json::parse(input); auto expr = jsoncons::jsonpath::make_expression("$.books[*]"); std::vector paths = expr.select_paths(root); REQUIRE(4 == paths.size()); CHECK(jsonpath::to_string(paths[0]) == "$['books'][0]"); CHECK(jsonpath::to_string(paths[1]) == "$['books'][1]"); CHECK(jsonpath::to_string(paths[2]) == "$['books'][2]"); CHECK(jsonpath::to_string(paths[3]) == "$['books'][3]"); } SECTION("Return locations of selected values") { auto root = jsoncons::json::parse(input); auto expr = jsoncons::jsonpath::make_expression("$.books[*]['category','title']"); std::vector paths = expr.select_paths(root,jsonpath::result_options::nodups | jsonpath::result_options::sort_descending); REQUIRE(8 == paths.size()); CHECK(jsonpath::to_string(paths[0]) == "$['books'][3]['title']"); CHECK(jsonpath::to_string(paths[1]) == "$['books'][3]['category']"); CHECK(jsonpath::to_string(paths[2]) == "$['books'][2]['title']"); CHECK(jsonpath::to_string(paths[3]) == "$['books'][2]['category']"); CHECK(jsonpath::to_string(paths[4]) == "$['books'][1]['title']"); CHECK(jsonpath::to_string(paths[5]) == "$['books'][1]['category']"); CHECK(jsonpath::to_string(paths[6]) == "$['books'][0]['title']"); CHECK(jsonpath::to_string(paths[7]) == "$['books'][0]['category']"); //for (const auto& path : paths) //{ // std::cout << jsonpath::to_string(path) << "\n"; //} } SECTION("Return locations, nodups, sort_descending") { auto root = jsoncons::json::parse(input); auto expr = jsoncons::jsonpath::make_expression("$.books[*]['category','category','title','title']"); std::vector paths = expr.select_paths(root,jsonpath::result_options::nodups | jsonpath::result_options::sort_descending); REQUIRE(8 == paths.size()); CHECK(jsonpath::to_string(paths[0]) == "$['books'][3]['title']"); CHECK(jsonpath::to_string(paths[1]) == "$['books'][3]['category']"); CHECK(jsonpath::to_string(paths[2]) == "$['books'][2]['title']"); CHECK(jsonpath::to_string(paths[3]) == "$['books'][2]['category']"); CHECK(jsonpath::to_string(paths[4]) == "$['books'][1]['title']"); CHECK(jsonpath::to_string(paths[5]) == "$['books'][1]['category']"); CHECK(jsonpath::to_string(paths[6]) == "$['books'][0]['title']"); CHECK(jsonpath::to_string(paths[7]) == "$['books'][0]['category']"); //for (const auto& path : paths) //{ // std::cout << jsonpath::to_string(path) << "\n"; //} } SECTION("Return locations, sort_descending") { auto root = jsoncons::json::parse(input); auto expr = jsoncons::jsonpath::make_expression("$.books[*]['category','category','title','title']"); std::vector paths = expr.select_paths(root, jsonpath::result_options::sort_descending); REQUIRE(paths.size() == 16); CHECK(jsonpath::to_string(paths[0]) == "$['books'][3]['title']"); CHECK(jsonpath::to_string(paths[1]) == "$['books'][3]['title']"); CHECK(jsonpath::to_string(paths[2]) == "$['books'][3]['category']"); CHECK(jsonpath::to_string(paths[3]) == "$['books'][3]['category']"); CHECK(jsonpath::to_string(paths[4]) == "$['books'][2]['title']"); CHECK(jsonpath::to_string(paths[5]) == "$['books'][2]['title']"); CHECK(jsonpath::to_string(paths[6]) == "$['books'][2]['category']"); CHECK(jsonpath::to_string(paths[7]) == "$['books'][2]['category']"); CHECK(jsonpath::to_string(paths[8]) == "$['books'][1]['title']"); CHECK(jsonpath::to_string(paths[9]) == "$['books'][1]['title']"); CHECK(jsonpath::to_string(paths[10]) == "$['books'][1]['category']"); CHECK(jsonpath::to_string(paths[11]) == "$['books'][1]['category']"); CHECK(jsonpath::to_string(paths[12]) == "$['books'][0]['title']"); CHECK(jsonpath::to_string(paths[13]) == "$['books'][0]['title']"); CHECK(jsonpath::to_string(paths[14]) == "$['books'][0]['category']"); CHECK(jsonpath::to_string(paths[15]) == "$['books'][0]['category']"); //for (const auto& path : paths) //{ // std::cout << jsonpath::to_string(path) << "\n"; //} } } TEST_CASE("jsonpath_expression::update tests") { std::string input = R"( { "books": [ { "category": "fiction", "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "category": "fiction", "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "category": "fiction", "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "category": "memoir", "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } )"; SECTION("Update in place") { auto root = jsoncons::json::parse(input); auto expr = jsoncons::jsonpath::make_expression("$.books[*]"); auto op = [](const jsonpath::path_node& /*location*/, jsoncons::json& book) { if (book.at("category") == "memoir" && !book.contains("price")) { book.try_emplace("price", 140.0); } }; expr.update(root, op); CHECK(root["books"][3].contains("price")); CHECK(root["books"][3].at("price") == 140); } SECTION("Return locations of selected values") { auto root = jsoncons::json::parse(input); auto expr = jsoncons::jsonpath::make_expression("$.books[*]"); std::vector paths = expr.select_paths(root); REQUIRE(4 == paths.size()); CHECK(jsonpath::to_string(paths[0]) == "$['books'][0]"); CHECK(jsonpath::to_string(paths[1]) == "$['books'][1]"); CHECK(jsonpath::to_string(paths[2]) == "$['books'][2]"); CHECK(jsonpath::to_string(paths[3]) == "$['books'][3]"); //for (const auto& path : paths) //{ // std::cout << jsonpath::to_string(path) << "\n"; //} } SECTION("update default sort order") { auto root = jsoncons::json::parse(input); auto expr = jsoncons::jsonpath::make_expression("$.books[*]"); std::vector path_nodes; auto callback2 = [&](const jsonpath::path_node& base_node, jsoncons::json&) { path_nodes.push_back(base_node); }; expr.update(root, callback2); REQUIRE(4 == path_nodes.size()); CHECK(3 == path_nodes[0].index()); CHECK(2 == path_nodes[1].index()); CHECK(1 == path_nodes[2].index()); CHECK(0 == path_nodes[3].index()); } } TEST_CASE("jsonpath_expression remove") { std::string input = R"( { "books": [ { "category": "fiction", "title" : "A Wild Sheep Chase", "author" : "Haruki Murakami", "price" : 22.72 }, { "category": "fiction", "title" : "The Night Watch", "author" : "Sergei Lukyanenko", "price" : 23.58 }, { "category": "fiction", "title" : "The Comedians", "author" : "Graham Greene", "price" : 21.99 }, { "category": "memoir", "title" : "The Night Watch", "author" : "Phillips, David Atlee" } ] } )"; SECTION("test 1") { auto doc = jsoncons::json::parse(input); auto expected = doc; expected["books"].erase(expected["books"].array_range().begin()+3); expected["books"].erase(expected["books"].array_range().begin(),expected["books"].array_range().begin()+2); std::size_t n = jsonpath::remove(doc, "$.books[1,1,3,3,0,0]"); CHECK(3 == n); REQUIRE(1 == doc.at("books").size()); CHECK(expected == doc); } } jsoncons-1.3.2/test/jsonpath/src/jsonpath_flatten_tests.cpp000066400000000000000000000105351477700171100242470ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("jsonpath flatten test") { json input = json::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 }, { "rater": "HikingAsylum", "assertion": "intermediate", "rated": "Hongmin", "rating": 0.75 } ] } )"); SECTION("flatten") { json result = jsonpath::flatten(input); REQUIRE(result.is_object()); //-V521 REQUIRE(9 == result.size()); //-V521 //std::cout << pretty_print(result) << "\n"; CHECK(result["$['application']"].as() == std::string("hiking")); //-V521 CHECK(result["$['reputons'][0]['assertion']"].as() == std::string("advanced")); //-V521 CHECK(result["$['reputons'][0]['rated']"].as() == std::string("Marilyn C")); //-V521 CHECK(result["$['reputons'][0]['rater']"].as() == std::string("HikingAsylum")); //-V521 CHECK(result["$['reputons'][0]['rating']"].as() == Approx(0.9).epsilon(0.0000001)); //-V521 CHECK(result["$['reputons'][1]['assertion']"].as() == std::string("intermediate")); //-V521 CHECK(result["$['reputons'][1]['rated']"].as() == std::string("Hongmin")); //-V521 CHECK(result["$['reputons'][1]['rater']"].as() == std::string("HikingAsylum")); //-V521 CHECK(result["$['reputons'][1]['rating']"].as() == Approx(0.75).epsilon(0.0000001)); //-V521 //std::cout << pretty_print(result) << "\n"; } SECTION("unflatten") { json result = jsonpath::flatten(input); //std::cout << pretty_print(result) << "\n"; json original = jsonpath::unflatten(result); //std::cout << pretty_print(original) << "\n"; CHECK(original == input); //-V521 } } TEST_CASE("jsonpath flatten array test") { json input = json::parse(R"([1,2,3,"4\u0027s"])"); SECTION("flatten array and unflatten") { json result = jsonpath::flatten(input); //std::cout << pretty_print(result) << "\n"; json original = jsonpath::unflatten(result); //std::cout << pretty_print(original) << "\n"; CHECK(original == input); //-V521 } } TEST_CASE("jsonpath flatten with single quote test") { json input = json::parse(R"( { "like'd": "pizza" } )"); SECTION("flatten array and unflatten") { json result = jsonpath::flatten(input); json original = jsonpath::unflatten(result); CHECK(original == input); //-V521 } } namespace { void compare_match(jsoncons::json& doc, const std::string& path, const std::string& value) { auto result = jsoncons::jsonpath::json_query(doc, path); CHECK_FALSE(result.empty()); // must match //-V521 CHECK_FALSE(result.size() > 1); // too many matches //-V521 auto matched_value = result[0].as(); CHECK(value == matched_value); //-V521 } } // namespace TEST_CASE("jsonpath flatten escape") { std::string json { R"({)" R"("data":)" R"({)" R"("a\"bc": "abc",)" R"("d'ef": "def",)" R"("g.hi": "ghi",)" R"("j\\kl": "jkl",)" R"("m/no": "mno",)" R"("x\"y'z": "xyz")" R"(})" R"(})" }; jsoncons::json doc = jsoncons::json::parse(json); auto flat_doc = jsoncons::jsonpath::flatten(doc); for (const auto& member : flat_doc.object_range()) { const auto& path = member.key(); const auto& value = member.value().as(); compare_match(doc, path, value); } } jsoncons-1.3.2/test/jsonpath/src/jsonpath_function_tests.cpp000066400000000000000000000020061477700171100244310ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include namespace jsonpath = jsoncons::jsonpath; TEST_CASE("csv function tests") { std::string store = R"( { "books": [ { "title": "Sayings of the Century" }, { "title": "Sword of Honour" }, { "title": "Moby Dick" }, { "title": "The Lord of the Rings" } ] } )"; SECTION("length") { auto root = jsoncons::json::parse(store); // The number of books auto result1 = jsonpath::json_query(root, "length($.books)"); REQUIRE(1 == result1.size()); REQUIRE(result1[0].is()); CHECK(4 == result1[0].as()); auto result2 = jsonpath::json_query(root, "length($..books)"); REQUIRE(1 == result2.size()); REQUIRE(result2[0].is()); CHECK(4 == result2[0].as()); } } jsoncons-1.3.2/test/jsonpath/src/jsonpath_json_query_tests.cpp000066400000000000000000000063341477700171100250120ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include #include #include // std::unordered_set #include using namespace jsoncons; TEST_CASE("jsonpath json_query json test") { json j; JSONCONS_TRY { j = json::parse(R"( { "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 } ] } } )"); } JSONCONS_CATCH (const ser_error& e) { std::cout << e.what() << '\n'; } SECTION("test 1") { auto result = jsonpath::json_query(j,"$..book[?(@.category == 'fiction')].title"); auto expected = json::parse(R"(["Sword of Honour","Moby Dick"])"); CHECK(expected == (result)); } SECTION("test 2") { std::string expr = "$..book[?(@.category == 'fiction')].title"; auto result = jsonpath::json_query(j,expr); auto expected = json::parse(R"(["Sword of Honour","Moby Dick"])"); CHECK(expected == (result)); } SECTION("test 3") { std::string expr = "$..book[?(@.title == 'Sword of Honour')].title"; json expected("Sword of Honour"); jsonpath::json_query(j, expr, [expected](const jsoncons::string_view&, const json& title) {CHECK(expected == (title));}); } } TEST_CASE("jsonpath normalized path test") { const json j = json::parse(R"({"\\":0})"); const std::string path = R"($['\\'])"; auto paths = jsonpath::json_query(j, path, jsonpath::result_options::path); CHECK(1 == paths.size()); auto result = jsonpath::json_query(j, paths[0].as_string_view()); CHECK(1 == result.size()); CHECK(0 == result[0].as()); } TEST_CASE("jsonpath json_query wjson test") { wjson j; JSONCONS_TRY { j = wjson::parse(LR"( { "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 } ] } } )"); } JSONCONS_CATCH (const ser_error& e) { std::cout << e.what() << '\n'; } SECTION("test 1") { auto result = jsonpath::json_query(j,L"$..book[?(@.category == 'fiction')].title"); auto expected = wjson::parse(LR"(["Sword of Honour","Moby Dick"])"); CHECK(expected == (result)); } } jsoncons-1.3.2/test/jsonpath/src/jsonpath_json_replace_tests.cpp000066400000000000000000000111631477700171100252540ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include #include // std::unordered_set #include #include using namespace jsoncons; TEST_CASE("test replace tests") { json j; JSONCONS_TRY { j = json::parse(R"( { "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 } ] } } )"); } JSONCONS_CATCH (const ser_error& e) { std::cout << e.what() << '\n'; } SECTION("test 1") { jsonpath::json_replace(j,"$..book[?(@.price==12.99)].price", 30.9); CHECK(30.9 == Approx(j["store"]["book"][1]["price"].as()).epsilon(0.001)); } SECTION("test 2") { std::string expr = "$.store.book[*].price"; // make a discount on all books jsonpath::json_replace(j, expr, [](const std::string&,json& price) { price = std::round(price.as() - 1.0); }); CHECK(8.0 == Approx(j["store"]["book"][0]["price"].as()).epsilon(0.001)); CHECK(12.0 == Approx(j["store"]["book"][1]["price"].as()).epsilon(0.001)); CHECK(8.0 == Approx(j["store"]["book"][2]["price"].as()).epsilon(0.001)); } SECTION("legacy test") { std::string expr = "$.store.book[*].price"; // make a discount on all books jsonpath::json_replace(j, expr, [](const json& price) { return std::round(price.as() - 1.0); }); CHECK(8.0 == Approx(j["store"]["book"][0]["price"].as()).epsilon(0.001)); CHECK(12.0 == Approx(j["store"]["book"][1]["price"].as()).epsilon(0.001)); CHECK(8.0 == Approx(j["store"]["book"][2]["price"].as()).epsilon(0.001)); } } TEST_CASE("replace with binary callback tests") { SECTION("test 1") { jsoncons::ojson doc = jsoncons::ojson::parse(R"({"value":"long______________enough"})"); jsoncons::ojson rep = jsoncons::ojson::parse(R"({"value":"rew"})"); jsoncons::ojson expected = jsoncons::ojson::parse(R"({"value":{"value":"rew"}})"); jsoncons::jsonpath::json_replace(doc, "$..value", [rep](const std::string&, jsoncons::ojson& match) { match = rep; }); CHECK(expected == doc); } SECTION("test 2") { jsoncons::ojson doc = jsoncons::ojson::parse(R"({"value":"long______________enough"})"); jsoncons::ojson rep = jsoncons::ojson::parse(R"({"value":"rew"})"); jsoncons::ojson expected = jsoncons::ojson::parse(R"({"value":{"value":"rew"}})"); jsoncons::jsonpath::json_replace(doc, "$..value", [rep](const std::string&, jsoncons::ojson& match) { match = rep; }); CHECK(expected == doc); } SECTION("test 3") { jsoncons::ojson doc = jsoncons::ojson::parse(R"({"value":"long______________enough"})"); jsoncons::ojson expected = jsoncons::ojson::parse(R"({"value":"rew"})"); jsoncons::jsonpath::json_replace(doc, "$..value", [](const std::string&, jsoncons::ojson& match) { match = "rew"; }); CHECK(expected == doc); } SECTION("test 4") { jsoncons::ojson doc = jsoncons::ojson::parse(R"({"value":"long______________enough"})"); jsoncons::ojson expected = jsoncons::ojson::parse(R"({"value":"XXX"})"); jsoncons::jsonpath::json_replace(doc, "$..value", [](const jsoncons::ojson&) { return jsoncons::ojson{ "XXX" }; }); CHECK(expected == doc); } SECTION("test 5") { jsoncons::ojson doc = jsoncons::ojson::parse(R"({"value":{"value":"long______________enough"}})"); jsoncons::ojson expected = jsoncons::ojson::parse(R"({"value":"XXX"})"); jsoncons::jsonpath::json_replace(doc, "$..value", [](const jsoncons::ojson&) { return jsoncons::ojson{ "XXX" }; }); CHECK(expected == doc); } } jsoncons-1.3.2/test/jsonpath/src/jsonpath_select_paths_tests.cpp000066400000000000000000000034611477700171100252700ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include #include // std::unordered_set #include #include using namespace jsoncons; TEST_CASE("jsonpath.jsonpath select_paths test") { std::string json_string = R"( { "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 } ] } } )"; json doc = json::parse(json_string); SECTION("test 1") { auto expr = jsonpath::make_expression("$..book[?(@.category == 'fiction')].title"); auto result = expr.select_paths(doc); for (const auto& loc : result) { std::string s = jsonpath::to_string(loc); std::cout << s << '\n'; } std::vector locations; jsonpath::json_location expected1; expected1.append("store").append("book").append(1).append("title"); jsonpath::json_location expected2; expected2.append("store").append("book").append(2).append("title"); locations.push_back(expected1); locations.push_back(expected2); CHECK((result == locations)); } } jsoncons-1.3.2/test/jsonpath/src/jsonpath_stateful_allocator_tests.cpp000066400000000000000000000123021477700171100264730ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include using namespace jsoncons; #if defined(JSONCONS_HAS_STATEFUL_ALLOCATOR) && JSONCONS_HAS_STATEFUL_ALLOCATOR == 1 #include #include template using MyScopedAllocator = std::scoped_allocator_adaptor>; using cust_json = basic_json>; TEST_CASE("jsonpath stateful allocator test") { std::string input = R"( { "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 } ] } } )"; SECTION("make_expression") { json_decoder decoder(MyScopedAllocator(1)); auto myAlloc = MyScopedAllocator(3); basic_json_reader,MyScopedAllocator> reader(input, decoder, myAlloc); reader.read(); cust_json j = decoder.get_result(); jsoncons::string_view p{"$..book[?(@.category == 'fiction')].title"}; auto expr = jsoncons::jsonpath::make_expression(combine_allocators(myAlloc), p); auto result = expr.evaluate(j); CHECK(2 == result.size()); CHECK(result[0].as_string_view() == "Sword of Honour"); CHECK(result[1].as_string_view() == "Moby Dick"); } SECTION("json_query 1") { json_decoder> decoder(MyScopedAllocator(1), MyScopedAllocator(2)); auto myAlloc = MyScopedAllocator(3); basic_json_reader,MyScopedAllocator> reader(input, decoder, myAlloc); reader.read(); cust_json j = decoder.get_result(); auto result = jsoncons::jsonpath::json_query(combine_allocators(myAlloc), j,"$..book[?(@.category == 'fiction')].title"); CHECK(2 == result.size()); CHECK(result[0].as_string_view() == "Sword of Honour"); CHECK(result[1].as_string_view() == "Moby Dick"); } SECTION("json_query 2") { json_decoder> decoder(MyScopedAllocator(1), MyScopedAllocator(2)); auto myAlloc = MyScopedAllocator(3); basic_json_reader,MyScopedAllocator> reader(input, decoder, myAlloc); reader.read(); cust_json j = decoder.get_result(); jsonpath::json_query(combine_allocators(myAlloc), j, "$..book[?(@.title == 'Sword of Honour')].title", [](const jsoncons::string_view&, const cust_json& title) { CHECK((title.as() == "Sword of Honour")); } ); } SECTION("json_replace 1") { json_decoder decoder(MyScopedAllocator(1)); auto myAlloc = MyScopedAllocator(3); basic_json_reader,MyScopedAllocator> reader(input, decoder, myAlloc); reader.read(); cust_json j = decoder.get_result(); auto res = jsonpath::json_query(combine_allocators(myAlloc), j, "$..book[?(@.price==12.99)].price"); //std::cout << "res:\n" << pretty_print(res) << "\n\n"; jsonpath::json_replace(combine_allocators(myAlloc), j,"$..book[?(@.price==12.99)].price", 30.9); //std::cout << "j:\n" << pretty_print(j) << "\n\n"; CHECK(30.9 == Approx(j["store"]["book"][1]["price"].as()).epsilon(0.001)); } SECTION("json_replace 2") { json_decoder> decoder(MyScopedAllocator(1), MyScopedAllocator(2)); auto myAlloc = MyScopedAllocator(3); basic_json_reader,MyScopedAllocator> reader(input, decoder, myAlloc); reader.read(); cust_json j = decoder.get_result(); // make a discount on all books jsonpath::json_replace(combine_allocators(myAlloc), j, "$.store.book[*].price", [](const jsoncons::string_view&, cust_json& price) { price = std::round(price.as() - 1.0); } ); CHECK(8.0 == Approx(j["store"]["book"][0]["price"].as()).epsilon(0.001)); CHECK(12.0 == Approx(j["store"]["book"][1]["price"].as()).epsilon(0.001)); CHECK(8.0 == Approx(j["store"]["book"][2]["price"].as()).epsilon(0.001)); } } #endif jsoncons-1.3.2/test/jsonpath/src/jsonpath_test_suite.cpp000066400000000000000000000141651477700171100235630ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include #include #include // std::unordered_set #include #include using namespace jsoncons; void jsonpath_tests(const std::string& fpath) { std::cout << "Test " << fpath << '\n'; std::fstream is(fpath); if (!is) { std::cerr << "Cannot open " << fpath << "\n"; exit(1); } json tests = json::parse(is); for (const auto& test_group : tests.array_range()) { const json& instance = test_group["given"]; for (const auto& test_case : test_group["cases"].array_range()) { std::string expr = test_case["expression"].as(); try { jsonpath::result_options options = jsonpath::result_options(); if (test_case.contains("nodups") && test_case.at("nodups").as()) { options |= jsonpath::result_options::nodups; } if (test_case.contains("sort") && test_case.at("sort").as()) { options |= jsonpath::result_options::sort; } auto expression = jsoncons::jsonpath::make_expression(expr); if (test_case.contains("result")) { jsonpath::result_options rflags = options | jsonpath::result_options::value; json actual = expression.evaluate(instance, rflags); const json& expected = test_case["result"]; //std::cout << "actual\n:" << actual << "\n"; if (actual != expected) { if (test_case.contains("comment")) { std::cout << "\n" << test_case["comment"] << "\n"; } std::cout << "Input:\n" << pretty_print(instance) << "\n\n"; std::cout << "Expression: " << expr << "\n\n"; std::cout << "Actual: " << pretty_print(actual) << "\n\n"; std::cout << "Expected: " << pretty_print(expected) << "\n\n"; } CHECK(expected == actual); } if (test_case.contains("path")) { jsonpath::result_options pflags = options | jsonpath::result_options::path; json actual = expression.evaluate(instance, pflags); const json& expected = test_case["path"]; //std::cout << "actual\n:" << actual << "\n"; if (actual != expected) { if (test_case.contains("comment")) { std::cout << "\n" << test_case["comment"] << "\n"; } std::cout << "Input:\n" << pretty_print(instance) << "\n\n"; std::cout << "Expression: " << expr << "\n\n"; std::cout << "Actual: " << pretty_print(actual) << "\n\n"; std::cout << "Expected: " << pretty_print(expected) << "\n\n"; } CHECK(expected == actual); } if (test_case.contains("error")) { json actual = expression.evaluate(instance); if (test_case.contains("comment")) { std::cout << "Comment: " << test_case["comment"] << "\n"; } std::cout << "Error: " << test_case["error"] << "\n\n"; std::cout << "Input:\n" << pretty_print(instance) << "\n\n"; std::cout << "Expression: " << expr << "\n\n"; std::cout << "Actual: " << pretty_print(actual) << "\n\n"; CHECK(false); } } catch (const std::exception& e) { if (test_case.contains("result")) { std::cout << e.what() << "\n"; const json& expected = test_case["result"]; std::cout << e.what() << "\n"; if (test_case.contains("comment")) { std::cout << "Comment: " << test_case["comment"] << "\n\n"; } std::cout << "Input\n" << pretty_print(instance) << "\n\n"; std::cout << "Expression: " << expr << "\n\n"; std::cout << "Expected: " << expected << "\n\n"; CHECK(false); } } } } } TEST_CASE("jsonpath-tests") { SECTION("compliance") { #if defined(JSONCONS_HAS_STD_REGEX) jsonpath_tests("./jsonpath/input/test_data/regex.json"); #endif jsonpath_tests("./jsonpath/input/test_data/identifiers.json"); jsonpath_tests("./jsonpath/input/test_data/dot-notation.json"); jsonpath_tests("./jsonpath/input/test_data/indices.json"); jsonpath_tests("./jsonpath/input/test_data/wildcard.json"); jsonpath_tests("./jsonpath/input/test_data/recursive-descent.json"); jsonpath_tests("./jsonpath/input/test_data/union.json"); jsonpath_tests("./jsonpath/input/test_data/filters.json"); jsonpath_tests("./jsonpath/input/test_data/functions.json"); jsonpath_tests("./jsonpath/input/test_data/expressions.json"); jsonpath_tests("./jsonpath/input/test_data/syntax.json"); jsonpath_tests("./jsonpath/input/test_data/functions.json"); jsonpath_tests("./jsonpath/input/test_data/slice.json"); jsonpath_tests("./jsonpath/input/test_data/parent-operator.json"); jsonpath_tests("./jsonpath/input/test.json"); } } jsoncons-1.3.2/test/jsonpath/src/path_node_tests.cpp000066400000000000000000000055551477700171100226530ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include using namespace jsoncons; TEST_CASE("test json_location equals") { jsonpath::path_node a1{}; jsonpath::path_node a2(&a1,"foo"); jsonpath::path_node a3(&a2,"bar"); jsonpath::path_node a4(&a3,0); jsonpath::path_node b1{}; jsonpath::path_node b2(&b1,"foo"); jsonpath::path_node b3(&b2,"bar"); jsonpath::path_node b4(&b3,0); CHECK((a4 == b4)); CHECK((jsonpath::to_string(a4) == std::string("$['foo']['bar'][0]"))); } TEST_CASE("test json_location with solidus to_string") { jsonpath::path_node a1{}; jsonpath::path_node a2(&a1,"foo's"); jsonpath::path_node a3(&a2,"bar"); jsonpath::path_node a4(&a3,0); CHECK(jsonpath::to_string(a4) == std::string(R"($['foo\'s']['bar'][0])")); } TEST_CASE("test path_node less") { SECTION("test rhs < lhs") { jsonpath::path_node a1{}; jsonpath::path_node a2(&a1,"foo"); jsonpath::path_node a3(&a2,"bar"); jsonpath::path_node a4(&a3,0); jsonpath::path_node b1{}; jsonpath::path_node b2(&b1,"baz"); jsonpath::path_node b3(&b2,"bar"); jsonpath::path_node b4(&b3,0); CHECK_FALSE(b4 == a4); CHECK(b4 < a4); CHECK_FALSE(a4 < b4); CHECK(b3 < a4); CHECK_FALSE(a4 < b3); CHECK(b2 < a4); CHECK_FALSE(a4 < b2); } SECTION("test rhs < lhs 2") { jsonpath::path_node a1{}; jsonpath::path_node a2(&a1,"foo"); jsonpath::path_node a3(&a2,"bar"); jsonpath::path_node a4(&a3,0); jsonpath::path_node b1{}; jsonpath::path_node b2(&b1,"baz"); jsonpath::path_node b3(&b2,"g"); jsonpath::path_node b4(&b3,0); CHECK_FALSE(b4 == a4); CHECK(b4 < a4); CHECK_FALSE(a4 < b4); CHECK(b3 < a4); CHECK_FALSE(a4 < b3); CHECK(b2 < a4); CHECK_FALSE(a4 < b2); } SECTION("test rhs == lhs") { jsonpath::path_node a1{}; jsonpath::path_node a2(&a1,"foo"); jsonpath::path_node a3(&a2,"bar"); jsonpath::path_node a4(&a3,0); jsonpath::path_node b1{}; jsonpath::path_node b2(&b1,"foo"); jsonpath::path_node b3(&b2,"bar"); jsonpath::path_node b4(&b3,0); CHECK(a1 == b1); CHECK(a2 == b2); CHECK(a3 == b3); CHECK(a4 == b4); CHECK(b1 == a1); CHECK(b2 == a2); CHECK(b3 == a3); CHECK(b4 == a4); CHECK_FALSE(b4 < a4); CHECK_FALSE(a4 < b4); CHECK(b3 < a4); CHECK_FALSE(a4 < b3); CHECK(b2 < a4); CHECK_FALSE(a4 < b2); } } jsoncons-1.3.2/test/jsonpointer/000077500000000000000000000000001477700171100167075ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonpointer/src/000077500000000000000000000000001477700171100174765ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonpointer/src/jsonpointer_flatten_tests.cpp000066400000000000000000000126401477700171100255160ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("jsonpointer unflatten tests 1") { SECTION("test 1") { json input = json::parse(R"( { "discards": { "1000": "Record does not exist", "1004": "Queue limit exceeded", "1010": "Discarding timed-out partial msg" }, "warnings": { "0": "Phone number missing country code", "1": "State code missing", "2": "Zip code missing" } } )"); json flattened = jsonpointer::flatten(input); json unflattened1 = jsonpointer::unflatten(flattened); //std::cout << "(1)\n" << pretty_print(unflattened1) << "\n"; json unflattened2 = jsonpointer::unflatten(flattened, jsonpointer::unflatten_options::assume_object); //std::cout << "(2)\n" << pretty_print(unflattened2) << "\n"; } } TEST_CASE("jsonpointer unflatten tests 2") { json input = json::parse(R"( { "0": { "1000": "Record does not exist", "1004": "Queue limit exceeded", "1010": "Discarding timed-out partial msg" }, "1": { "0": "Phone number missing country code", "1": "State code missing", "2": "Zip code missing" } } )"); json flattened = jsonpointer::flatten(input); SECTION("default test") { json expected = json::parse(R"( [ { "1000": "Record does not exist", "1004": "Queue limit exceeded", "1010": "Discarding timed-out partial msg" }, ["Phone number missing country code", "State code missing", "Zip code missing"] ] )"); json unflattened = jsonpointer::unflatten(flattened); CHECK(expected == unflattened); //std::cout << "(1)\n" << pretty_print(unflattened) << "\n"; } SECTION("object test") { json expected = json::parse(R"( { "0": { "1000": "Record does not exist", "1004": "Queue limit exceeded", "1010": "Discarding timed-out partial msg" }, "1": { "0": "Phone number missing country code", "1": "State code missing", "2": "Zip code missing" } } )"); json unflattened = jsonpointer::unflatten(flattened, jsonpointer::unflatten_options::assume_object); CHECK(expected == unflattened); //std::cout << "(2)\n" << pretty_print(unflattened) << "\n"; } } TEST_CASE("flatten test") { json input = json::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 }, { "rater": "HikingAsylum", "assertion": "intermediate", "rated": "Hongmin", "rating": 0.75 } ] } )"); SECTION("flatten") { json result = jsonpointer::flatten(input); REQUIRE(result.is_object()); REQUIRE(9 == result.size()); CHECK(result["/application"].as() == std::string("hiking")); CHECK(result["/reputons/0/assertion"].as() == std::string("advanced")); CHECK(result["/reputons/0/rated"].as() == std::string("Marilyn C")); CHECK(result["/reputons/0/rater"].as() == std::string("HikingAsylum")); CHECK(result["/reputons/0/rating"].as() == Approx(0.9).epsilon(0.0000001)); CHECK(result["/reputons/1/assertion"].as() == std::string("intermediate")); CHECK(result["/reputons/1/rated"].as() == std::string("Hongmin")); CHECK(result["/reputons/1/rater"].as() == std::string("HikingAsylum")); CHECK(result["/reputons/1/rating"].as() == Approx(0.75).epsilon(0.0000001)); //std::cout << pretty_print(result) << "\n"; json unflattened = jsonpointer::unflatten(result); CHECK(unflattened == input); //std::cout << pretty_print(unflattened) << "\n"; } } TEST_CASE("jsonpointer flatten/unflatten empty array and empty object") { SECTION("object with empty array or object") { json input = json::parse(R"( { "foo": [], "bar": {} } )"); json flattened = jsonpointer::flatten(input); json unflattened = jsonpointer::unflatten(flattened); CHECK(unflattened == input); } SECTION("array with empty array or object") { json input = json::parse(R"( [ [], {} ] )"); json flattened = jsonpointer::flatten(input); json unflattened = jsonpointer::unflatten(flattened); CHECK(unflattened == input); } } jsoncons-1.3.2/test/jsonpointer/src/jsonpointer_tests.cpp000066400000000000000000000343431477700171100240050ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include #include using namespace jsoncons; using namespace jsoncons::literals; template void check_contains(const basic_json& example, const std::string& pointer, bool expected) { bool result = jsonpointer::contains(example,pointer); if (result != expected) { std::cout << "contains failed\n"; std::cout << " given: " << example << "\n"; std::cout << " pointer: " << pointer << "\n"; } CHECK(expected == result); } template void check_get(const basic_json& example, const std::string& pointer, const basic_json& expected) { std::error_code ec; const auto& result = jsonpointer::get(example,pointer,ec); if (result != expected) { std::cout << " given: " << example << "\n"; std::cout << " expected: " << expected << "\n"; std::cout << " pointer: " << pointer << "\n"; } CHECK_FALSE(ec); CHECK(expected == result); } void check_insert_or_assign(json& example, const std::string& path, const json& value, const json& expected) { std::error_code ec; jsonpointer::add(example, path, value, ec); CHECK_FALSE(ec); CHECK(expected == example); } void check_replace(json& example, const std::string& path, const json& value, const json& expected) { std::error_code ec; jsonpointer::replace(example, path, value, ec); CHECK_FALSE(ec); CHECK(expected == example); } void check_remove(json& example, const std::string& path, const json& expected) { std::error_code ec; jsonpointer::remove(example, path, ec); CHECK_FALSE(ec); CHECK(expected == example); } TEST_CASE("get_with_const_ref_test") { // Example from RFC 6901 const json example = json::parse(R"( { "foo": ["bar", "baz"], "": 0, "a/b": 1, "c%d": 2, "e^f": 3, "g|h": 4, "i\\j": 5, "k\"l": 6, " ": 7, "m~n": 8 } )"); check_contains(example,"",true); check_contains(example,"/foo",true); check_contains(example,"/foo/0",true); check_contains(example,"/",true); check_contains(example,"/a~1b",true); check_contains(example,"/c%d",true); check_contains(example,"/e^f",true); check_contains(example,"/g|h",true); check_contains(example,"/i\\j",true); check_contains(example,"/k\"l",true); check_contains(example,"/ ",true); check_contains(example,"/m~0n",true); check_get(example,"",example); check_get(example,"/foo",json::parse("[\"bar\", \"baz\"]")); check_get(example,"/foo/0",json("bar")); check_get(example,"/",json(0)); check_get(example,"/a~1b",json(1)); check_get(example,"/c%d",json(2)); check_get(example,"/e^f",json(3)); check_get(example,"/g|h",json(4)); check_get(example,"/i\\j",json(5)); check_get(example,"/k\"l",json(6)); check_get(example,"/ ",json(7)); check_get(example,"/m~0n",json(8)); } TEST_CASE("get_with_ref_test") { // Example from RFC 6901 json example = json::parse(R"( { "foo": ["bar", "baz"] } )"); std::error_code ec; json& result = jsonpointer::get(example,"/foo/0",ec); CHECK_FALSE(ec); result = "bat"; //std::cout << example << '\n'; } TEST_CASE("get_with_nonexistent_target") { json example = R"( { "foo": "bar" } )"_json; check_contains(example,"/baz",false); } // insert_or_assign TEST_CASE("test_add_object_member") { json example = json::parse(R"( { "foo": "bar"} )"); const json expected = json::parse(R"( { "foo": "bar", "baz" : "qux"} )"); check_insert_or_assign(example,"/baz", json("qux"), expected); } TEST_CASE("test_add_array_element") { json example = json::parse(R"( { "foo": [ "bar", "baz" ] } )"); const json expected = json::parse(R"( { "foo": [ "bar", "qux", "baz" ] } )"); check_insert_or_assign(example,"/foo/1", json("qux"), expected); } TEST_CASE("test_add_array_value") { json example = json::parse(R"( { "foo": ["bar"] } )"); const json expected = json::parse(R"( { "foo": ["bar", ["abc", "def"]] } )"); check_insert_or_assign(example,"/foo/-", json(json_array_arg, {"abc", "def"}), expected); } // remove TEST_CASE("test_remove_object_member") { json example = json::parse(R"( { "foo": "bar", "baz" : "qux"} )"); const json expected = json::parse(R"( { "foo": "bar"} )"); check_remove(example,"/baz", expected); } TEST_CASE("test_remove_array_element") { json example = json::parse(R"( { "foo": [ "bar", "qux", "baz" ] } )"); const json expected = json::parse(R"( { "foo": [ "bar", "baz" ] } )"); check_remove(example,"/foo/1", expected); } // replace TEST_CASE("test_replace_object_value") { json example = json::parse(R"( { "baz": "qux", "foo": "bar" } )"); const json expected = json::parse(R"( { "baz": "boo", "foo": "bar" } )"); check_replace(example,"/baz", json("boo"), expected); } TEST_CASE("test_replace_array_value") { json example = json::parse(R"( { "foo": [ "bar", "baz" ] } )"); const json expected = json::parse(R"( { "foo": [ "bar", "qux" ] } )"); check_replace(example,"/foo/1", json("qux"), expected); } TEST_CASE("jsonpointer path tests") { SECTION("/a~1b") { jsonpointer::json_pointer ptr("/a~1b"); auto it = ptr.begin(); auto end = ptr.end(); CHECK(it != end); CHECK((*it++ == "a/b")); CHECK(it == end); } SECTION("/a~1b") { jsonpointer::json_pointer ptr("/m~0n"); auto it = ptr.begin(); auto end = ptr.end(); CHECK(it != end); CHECK((*it++ == "m~n")); CHECK(it == end); } SECTION("/0/1") { jsonpointer::json_pointer ptr("/0/1"); auto it = ptr.begin(); auto end = ptr.end(); CHECK(it != end); CHECK((*it++ == "0")); CHECK(it != end); CHECK((*it++ == "1")); CHECK(it == end); } } TEST_CASE("wjsonpointer path tests") { SECTION("/a~1b") { jsonpointer::wjson_pointer ptr(L"/a~1b"); auto it = ptr.begin(); auto end = ptr.end(); CHECK(it != end); CHECK((*it++ == L"a/b")); CHECK(it == end); } } TEST_CASE("jsonpointer concatenation") { // Example from RFC 6901 json example = json::parse(R"( { "a/b": ["bar", "baz"], "m~n": ["foo", "qux"] } )"); SECTION("path append a/b") { jsonpointer::json_pointer ptr; ptr /= "a/b"; ptr /= "0"; auto it = ptr.begin(); auto end = ptr.end(); CHECK((*it++ == "a/b")); CHECK((*it++ == "0")); CHECK(it == end); std::error_code ec; json j = jsonpointer::get(example, ptr, ec); //std::cout << j << "\n"; CHECK(j == json("bar")); } SECTION("concatenate two paths") { jsonpointer::json_pointer ptr1; ptr1 /= "m~n"; jsonpointer::json_pointer ptr2; ptr2 /= "1"; jsonpointer::json_pointer ptr = ptr1 + ptr2; auto it = ptr.begin(); auto end = ptr.end(); CHECK((*it++ == "m~n")); CHECK((*it++ == "1")); CHECK(it == end); json j = jsonpointer::get(example, ptr); CHECK(j == json("qux")); //std::cout << j << "\n"; } } TEST_CASE("[jsonpointer] Inserting object after deleting it") { ojson oj; std::error_code ec; jsonpointer::add( oj, "/test", ojson(), ec ); CHECK(1 == oj.size()); jsonpointer::remove( oj, "/test", ec ); CHECK(0 == oj.size()); jsonpointer::add( oj, "/t", ojson(), ec ); CHECK(1 == oj.size()); } TEST_CASE("[jsonpointer] create_if_missing") { SECTION("get from empty") { std::vector keys = {"foo","bar","baz"}; jsonpointer::json_pointer ptr; for (const auto& key : keys) { ptr /= key; } json doc; json result = jsonpointer::get(doc, ptr, true); json expected = json::parse(R"({"foo":{"bar":{"baz":{}}}})"); CHECK(expected == doc); CHECK(result == json()); } SECTION("get from non-empty") { std::vector keys = {"foo","bar","baz"}; jsonpointer::json_pointer ptr; for (const auto& key : keys) { ptr /= key; } json doc = json::parse(R"({"foo":{}})"); json result = jsonpointer::get(doc, ptr, true); json expected = json::parse(R"({"foo":{"bar":{"baz":{}}}})"); CHECK(expected == doc); CHECK(result == json()); } SECTION("add into empty") { std::vector keys = {"foo","bar","baz"}; jsonpointer::json_pointer ptr; for (const auto& key : keys) { ptr /= key; } json doc; jsonpointer::add(doc, ptr, "str", true); json expected = json::parse(R"({"foo":{"bar":{"baz":"str"}}})"); CHECK(expected == doc); } SECTION("add into non-empty") { std::vector keys = {"foo","bar","baz"}; jsonpointer::json_pointer ptr; for (const auto& key : keys) { ptr /= key; } json doc = json::parse(R"({"foo":{}})"); jsonpointer::add(doc, ptr, "str", true); json expected = json::parse(R"({"foo":{"bar":{"baz":"str"}}})"); CHECK(expected == doc); } SECTION("add_if_absent into empty") { std::vector keys = { "foo","bar","baz" }; jsonpointer::json_pointer ptr; for (const auto& key : keys) { ptr /= key; } json doc; jsonpointer::add_if_absent(doc, ptr, "str", true); json expected = json::parse(R"({"foo":{"bar":{"baz":"str"}}})"); CHECK(expected == doc); } SECTION("add_if_absent into non-empty") { std::vector keys = { "foo","bar","baz" }; jsonpointer::json_pointer ptr; for (const auto& key : keys) { ptr /= key; } json doc = json::parse(R"({"foo":{}})"); jsonpointer::add_if_absent(doc, ptr, "str", true); json expected = json::parse(R"({"foo":{"bar":{"baz":"str"}}})"); CHECK(expected == doc); } SECTION("replace into empty") { std::vector keys = {"foo","bar","baz"}; jsonpointer::json_pointer ptr; for (const auto& key : keys) { ptr /= key; } json doc; jsonpointer::replace(doc, ptr, "str", true); json expected = json::parse(R"({"foo":{"bar":{"baz":"str"}}})"); CHECK(expected == doc); } SECTION("replace into non-empty") { std::vector keys = {"foo","bar","baz"}; jsonpointer::json_pointer ptr; for (const auto& key : keys) { ptr /= key; } json doc = json::parse(R"({"foo":{}})"); jsonpointer::replace(doc, ptr, "str", true); json expected = json::parse(R"({"foo":{"bar":{"baz":"str"}}})"); CHECK(expected == doc); } } #if defined(JSONCONS_HAS_STATEFUL_ALLOCATOR) && JSONCONS_HAS_STATEFUL_ALLOCATOR == 1 #include #include template using MyScopedAllocator = std::scoped_allocator_adaptor>; using cust_json = basic_json>; TEST_CASE("jsonpointer get with stateful allocator") { MyScopedAllocator alloc(1); // Example from RFC 6901 const cust_json example = cust_json::parse(combine_allocators(alloc), R"( { "foo": ["bar", "baz"], "": 0, "a/b": 1, "c%d": 2, "e^f": 3, "g|h": 4, "i\\j": 5, "k\"l": 6, " ": 7, "m~n": 8 } )", json_options{}); check_contains(example,"",true); check_contains(example,"/foo",true); check_contains(example,"/foo/0",true); check_contains(example,"/",true); check_contains(example,"/a~1b",true); check_contains(example,"/c%d",true); check_contains(example,"/e^f",true); check_contains(example,"/g|h",true); check_contains(example,"/i\\j",true); check_contains(example,"/k\"l",true); check_contains(example,"/ ",true); check_contains(example,"/m~0n",true); check_get(example,"",example); check_get(example,"/foo", cust_json::parse(combine_allocators(alloc), jsoncons::string_view("[\"bar\", \"baz\"]"), json_options())); check_get(example,"/foo/0", cust_json("bar", semantic_tag::none, alloc)); check_get(example,"/", cust_json(0)); check_get(example,"/a~1b", cust_json(1)); check_get(example,"/c%d", cust_json(2)); check_get(example,"/e^f", cust_json(3)); check_get(example,"/g|h", cust_json(4)); check_get(example,"/i\\j", cust_json(5)); check_get(example,"/k\"l", cust_json(6)); check_get(example,"/ ", cust_json(7)); check_get(example,"/m~0n", cust_json(8)); } #endif TEST_CASE("jsonpointer JSON Schema tests") { SECTION("not a valid JSON-pointer (~ not escaped)") { std::error_code ec; auto jsonp = jsonpointer::json_pointer::parse("/foo/bar~", ec); CHECK(ec); } SECTION("not a valid JSON-pointer (URI Fragment Identifier) #1") { std::error_code ec; auto jsonp = jsonpointer::json_pointer::parse("#", ec); std::cout << jsonp.string() << "\n"; CHECK(ec); } SECTION("not a valid JSON-pointer (some escaped, but not all) #1") { std::error_code ec; auto jsonp = jsonpointer::json_pointer::parse("/~0~", ec); std::cout << jsonp.string() << "\n"; CHECK(ec); } } jsoncons-1.3.2/test/jsonschema/000077500000000000000000000000001477700171100164675ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/000077500000000000000000000000001477700171100224425ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/000077500000000000000000000000001477700171100251425ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/README.md000066400000000000000000000103731477700171100264250ustar00rootroot00000000000000These tests are intended to validate that implementations are correctly generating output in accordance with the specification. Output was initially specified with draft 2019-09. It remained largely unchanged for draft 2020-12, but will receive an update with the next release. _**NOTE** Although the formats didn't change much between 2019-09 and 2020-12, the tests are copied for 2020-12 because the `$schema` is different and implementations may (but shouldn't) produce different output._ ## Organization The tests are organized by specification release and then into two categories: content and structure. Content tests verify that the keywords are producing the correct annotations and/or error messages. Since there are no requirements on the content of error messages, there's not much that can be verified for them, but it is possible to identify when a error message _could_ be present. Primarily, these tests need to extensively cover the annotation behaviors of each keyword. The only output format needed for these tests is `basic` for 2019-09/2020-12 and `list` for later versions. Structure tests verify that the structures of the various formats (i.e. `flag`, `basic`, `detailed`, `verbose` for 2019-09/2020-12 and `flag`, `list`, `hierarchical` for later versions) are correct. These tests don't need to cover each keyword; rather they need to sufficiently cover the various aspects of building the output structures by using whatever keywords are necessary to do so. In each release folder, you'll also find an _output-schema.json_ file that contains the schema from the specification repo that describes output for that release. This schema will need to be loaded as the tests reference it. ## Test Files The content of a test file is similar to the validation tests in `tests/`: for each test case, the `valid` property has been removed, and an `output` property has been added. The `output` property itself has a property for each of the output formats where the value is a schema that will successfully validate for compliant output. For the content tests, only `basic`/`list` needs to be present. ## Other notes ### Ambiguity around 2020-09/2020-12 `basic` The 2019-09/2020-12 specs don't define the structure of `basic` very thoroughly. Specifically there is a nuance where if the list contains a single output node, there are two possible structures, given the text: - the output node for the root schema appears in the list with a containing node that just has a `valid` property ```json { "valid": false, "errors": [ { "valid": false, "keywordLocation": "", "absoluteKeywordLocation": "https://json-schema.org/tests/content/draft2019-09/general/0", "instanceLocation": "" } ] } ``` - the entire structure is collapsed to just the root output node as `detailed` would do. ```json { "valid": false, "keywordLocation": "", "absoluteKeywordLocation": "https://json-schema.org/tests/content/draft2019-09/general/0", "instanceLocation": "" } ``` As the Test Suite should not prefer one interpretation over another, these cases need to be tested another way. A simple solution (though there are likely others) is to force a second output unit by adding an `"anyOf": [ true ]`. This has no impact on the validation result while adding superfluous structure to the output that avoids the above ambiguous scenario. The test schema should still be targeted on what's being tested and ignore any output units generated by this extra keyword. ## Contributing Of course, first and foremost, follow the [Contributing guide](/CONTRIBUTING.md). When writing test cases, try to keep output validation schemas targeted to verify a single requirement. Where possible (and where it makes sense), create multiple tests to cover multiple requirements. This will help keep the output validation schemas small and increase readability. (It also increases your test count. 😉) For the content tests, there is also a _general.json_ file that contains tests that do not necessarily pertain to any single keyword. jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/draft-next/000077500000000000000000000000001477700171100272165ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/draft-next/content/000077500000000000000000000000001477700171100306705ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/draft-next/content/general.json000066400000000000000000000036021477700171100332010ustar00rootroot00000000000000[ { "description": "failed validation produces no annotations", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "https://json-schema.org/tests/content/draft-next/general/0", "type": "string", "readOnly": true }, "tests": [ { "description": "dropped annotations MAY appear in droppedAnnotations", "data": 1, "output": { "list": { "$id": "https://json-schema.org/tests/content/draft-next/general/0/tests/0/basic", "$ref": "/draft/next/output/schema", "properties": { "details": { "contains": { "properties": { "evaluationPath": {"const": ""}, "schemaLocation": {"const": "https://json-schema.org/tests/content/draft-next/general/0#"}, "instanceLocation": {"const": ""}, "annotations": false, "droppedAnnotations": { "properties": { "readOnly": {"const": true} }, "required": ["readOnly"] } }, "required": ["evaluationPath", "schemaLocation", "instanceLocation"] } } }, "required": ["details"] } } } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/draft-next/content/readOnly.json000066400000000000000000000034211477700171100333400ustar00rootroot00000000000000[ { "description": "readOnly generates its value as an annotation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "https://json-schema.org/tests/content/draft-next/readOnly/0", "readOnly": true }, "tests": [ { "description": "readOnly is true", "data": 1, "output": { "list": { "$id": "https://json-schema.org/tests/content/draft-next/readOnly/0/tests/0/basic", "$ref": "/draft/next/output/schema", "properties": { "details": { "contains": { "properties": { "evaluationPath": {"const": ""}, "schemaLocation": {"const": "https://json-schema.org/tests/content/draft-next/readOnly/0#"}, "instanceLocation": {"const": ""}, "annotations": { "properties": { "readOnly": {"const": true} }, "required": ["readOnly"] } }, "required": ["evaluationPath", "schemaLocation", "instanceLocation", "annotations"] } } }, "required": ["details"] } } } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/draft-next/content/type.json000066400000000000000000000032031477700171100325420ustar00rootroot00000000000000[ { "description": "incorrect type", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "https://json-schema.org/tests/content/draft-next/type/0", "type": "string" }, "tests": [ { "description": "incorrect type must be reported, but a message is not required", "data": 1, "output": { "list": { "$id": "https://json-schema.org/tests/content/draft-next/type/0/tests/0/basic", "$ref": "/draft/next/output/schema", "properties": { "details": { "contains": { "properties": { "evaluationPath": {"const": ""}, "schemaLocation": {"const": "https://json-schema.org/tests/content/draft-next/type/0#"}, "instanceLocation": {"const": ""}, "annotations": false, "errors": { "required": ["type"] } }, "required": ["evaluationPath", "schemaLocation", "instanceLocation"] } } }, "required": ["details"] } } } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/draft-next/output-schema.json000066400000000000000000000044221477700171100327110ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/next/schema", "$id": "https://json-schema.org/draft/next/output/schema", "description": "A schema that validates the minimum requirements for validation output", "anyOf": [ { "$ref": "#/$defs/flag" }, { "$ref": "#/$defs/basic" }, { "$ref": "#/$defs/hierarchical" } ], "$defs": { "outputUnit":{ "properties": { "valid": { "type": "boolean" }, "evaluationPath": { "type": "string", "format": "json-pointer" }, "schemaLocation": { "type": "string", "format": "uri" }, "instanceLocation": { "type": "string", "format": "json-pointer" }, "details": { "$ref": "#/$defs/outputUnitArray" }, "annotations": { "type": "object", "additionalProperties": true }, "droppedAnnotations": { "type": "object", "additionalProperties": true }, "errors": { "type": "object", "additionalProperties": { "type": "string" } } }, "required": [ "valid", "evaluationPath", "schemaLocation", "instanceLocation" ], "allOf": [ { "if": { "anyOf": [ { "required": [ "errors" ] }, { "required": [ "droppedAnnotations" ] } ] }, "then": { "properties": { "valid": { "const": false } } } }, { "if": { "required": [ "annotations" ] }, "then": { "properties": { "valid": { "const": true } } } } ] }, "outputUnitArray": { "type": "array", "items": { "$ref": "#/$defs/outputUnit" } }, "flag": { "properties": { "valid": { "type": "boolean" } }, "required": [ "valid" ] }, "basic": { "properties": { "valid": { "type": "boolean" }, "details": { "$ref": "#/$defs/outputUnitArray" } }, "required": [ "valid", "details" ] }, "hierarchical": { "$ref": "#/$defs/outputUnit" } } } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/draft2019-09/000077500000000000000000000000001477700171100270045ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/draft2019-09/content/000077500000000000000000000000001477700171100304565ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/draft2019-09/content/escape.json000066400000000000000000000032031477700171100326070ustar00rootroot00000000000000[ { "description": "tilde and forward slash in json-pointer", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://json-schema.org/tests/content/draft2019-09/escape/0", "properties": { "~a/b": {"type": "number"} } }, "tests": [ { "description": "incorrect type must be reported, but a message is not required", "data": {"~a/b": "foobar"}, "output": { "basic": { "$id": "https://json-schema.org/tests/content/draft2019-09/escape/0/tests/0/basic", "$ref": "/draft/2019-09/output/schema", "properties": { "errors": { "contains": { "properties": { "keywordLocation": {"const": "/properties/~0a~1b/type"}, "absoluteKeywordLocation": {"const": "https://json-schema.org/tests/content/draft2019-09/escape/0#/properties/~0a~1b/type"}, "instanceLocation": {"const": "/~0a~1b"}, "annotation": false }, "required": ["keywordLocation", "instanceLocation"] } } }, "required": ["errors"] } } } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/draft2019-09/content/general.json000066400000000000000000000022721477700171100327710ustar00rootroot00000000000000[ { "description": "failed validation produces no annotations", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://json-schema.org/tests/content/draft2019-09/general/0", "type": "string", "readOnly": true }, "tests": [ { "description": "readOnly annotation is dropped", "data": 1, "output": { "basic": { "$id": "https://json-schema.org/tests/content/draft2019-09/general/0/tests/0/basic", "$ref": "/draft/2019-09/output/schema", "properties": { "errors": { "items": { "properties": { "annotation": false } } }, "annotations": false }, "required": ["errors"] } } } ] } ] readOnly.json000066400000000000000000000031721477700171100330520ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/draft2019-09/content[ { "description": "readOnly generates its value as an annotation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://json-schema.org/tests/content/draft2019-09/readOnly/0", "readOnly": true }, "tests": [ { "description": "readOnly is true", "data": 1, "output": { "basic": { "$id": "https://json-schema.org/tests/content/draft2019-09/readOnly/0/tests/0/basic", "$ref": "/draft/2019-09/output/schema", "properties": { "annotations": { "contains": { "type": "object", "properties": { "keywordLocation": {"const": "/readOnly"}, "absoluteKeywordLocation": {"const": "https://json-schema.org/tests/content/draft2019-09/readOnly/0#/readOnly"}, "instanceLocation": {"const": ""}, "annotation": {"const": true} }, "required": ["keywordLocation", "instanceLocation", "annotation"] } }, "errors": false }, "required": ["annotations"] } } } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/draft2019-09/content/type.json000066400000000000000000000030201477700171100323250ustar00rootroot00000000000000[ { "description": "validating type", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://json-schema.org/tests/content/draft2019-09/type/0", "type": "string", "anyOf": [ true ] }, "tests": [ { "description": "incorrect type must be reported, but a message is not required", "data": 1, "output": { "basic": { "$id": "https://json-schema.org/tests/content/draft2019-09/type/0/tests/0/basic", "$ref": "/draft/2019-09/output/schema", "properties": { "errors": { "contains": { "properties": { "keywordLocation": {"const": "/type"}, "absoluteKeywordLocation": {"const": "https://json-schema.org/tests/content/draft2019-09/type/0#/type"}, "instanceLocation": {"const": ""}, "annotation": false }, "required": ["keywordLocation", "instanceLocation"] } } }, "required": ["errors"] } } } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/draft2019-09/output-schema.json000066400000000000000000000045051477700171100325010ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://json-schema.org/draft/2019-09/output/schema", "description": "A schema that validates the minimum requirements for validation output", "anyOf": [ { "$ref": "#/$defs/flag" }, { "$ref": "#/$defs/basic" }, { "$ref": "#/$defs/detailed" }, { "$ref": "#/$defs/verbose" } ], "$defs": { "outputUnit":{ "properties": { "valid": { "type": "boolean" }, "keywordLocation": { "type": "string", "format": "json-pointer" }, "absoluteKeywordLocation": { "type": "string", "format": "uri" }, "instanceLocation": { "type": "string", "format": "json-pointer" }, "error": { "type": "string" }, "errors": { "$ref": "#/$defs/outputUnitArray" }, "annotations": { "$ref": "#/$defs/outputUnitArray" } }, "required": [ "valid", "keywordLocation", "instanceLocation" ], "allOf": [ { "if": { "properties": { "valid": { "const": false } } }, "then": { "anyOf": [ { "required": [ "error" ] }, { "required": [ "errors" ] } ] } }, { "if": { "anyOf": [ { "properties": { "keywordLocation": { "pattern": "/\\$ref/" } } }, { "properties": { "keywordLocation": { "pattern": "/\\$recursiveRef/" } } } ] }, "then": { "required": [ "absoluteKeywordLocation" ] } } ] }, "outputUnitArray": { "type": "array", "items": { "$ref": "#/$defs/outputUnit" } }, "flag": { "properties": { "valid": { "type": "boolean" } }, "required": [ "valid" ] }, "basic": { "$ref": "#/$defs/outputUnit" }, "detailed": { "$ref": "#/$defs/outputUnit" }, "verbose": { "$ref": "#/$defs/outputUnit" } } } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/draft2020-12/000077500000000000000000000000001477700171100267665ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/draft2020-12/content/000077500000000000000000000000001477700171100304405ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/draft2020-12/content/escape.json000066400000000000000000000032031477700171100325710ustar00rootroot00000000000000[ { "description": "tilde and forward slash in json-pointer", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/tests/content/draft2020-12/escape/0", "properties": { "~a/b": {"type": "number"} } }, "tests": [ { "description": "incorrect type must be reported, but a message is not required", "data": {"~a/b": "foobar"}, "output": { "basic": { "$id": "https://json-schema.org/tests/content/draft2020-12/escape/0/tests/0/basic", "$ref": "/draft/2020-12/output/schema", "properties": { "errors": { "contains": { "properties": { "keywordLocation": {"const": "/properties/~0a~1b/type"}, "absoluteKeywordLocation": {"const": "https://json-schema.org/tests/content/draft2020-12/escape/0#/properties/~0a~1b/type"}, "instanceLocation": {"const": "/~0a~1b"}, "annotation": false }, "required": ["keywordLocation", "instanceLocation"] } } }, "required": ["errors"] } } } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/draft2020-12/content/general.json000066400000000000000000000022721477700171100327530ustar00rootroot00000000000000[ { "description": "failed validation produces no annotations", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/tests/content/draft2020-12/general/0", "type": "string", "readOnly": true }, "tests": [ { "description": "readOnly annotation is dropped", "data": 1, "output": { "basic": { "$id": "https://json-schema.org/tests/content/draft2020-12/general/0/tests/0/basic", "$ref": "/draft/2020-12/output/schema", "properties": { "errors": { "items": { "properties": { "annotation": false } } }, "annotations": false }, "required": ["errors"] } } } ] } ] readOnly.json000066400000000000000000000031041477700171100330270ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/draft2020-12/content[ { "description": "readOnly generates its value as an annotation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/tests/content/draft2020-12/readOnly/0", "readOnly": true }, "tests": [ { "description": "readOnly is true", "data": 1, "output": { "basic": { "$id": "https://json-schema.org/tests/content/draft2020-12/readOnly/0/tests/0/basic", "$ref": "/draft/2020-12/output/schema", "properties": { "annotations": { "contains": { "properties": { "keywordLocation": {"const": "/readOnly"}, "absoluteKeywordLocation": {"const": "https://json-schema.org/tests/content/draft2020-12/readOnly/0#/readOnly"}, "instanceLocation": {"const": ""}, "annotation": {"const": true} }, "required": ["keywordLocation", "instanceLocation", "annotation"] } }, "errors": false }, "required": ["annotations"] } } } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/draft2020-12/content/type.json000066400000000000000000000030201477700171100323070ustar00rootroot00000000000000[ { "description": "validating type", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/tests/content/draft2020-12/type/0", "type": "string", "anyOf": [ true ] }, "tests": [ { "description": "incorrect type must be reported, but a message is not required", "data": 1, "output": { "basic": { "$id": "https://json-schema.org/tests/content/draft2020-12/type/0/tests/0/basic", "$ref": "/draft/2020-12/output/schema", "properties": { "errors": { "contains": { "properties": { "keywordLocation": {"const": "/type"}, "absoluteKeywordLocation": {"const": "https://json-schema.org/tests/content/draft2020-12/type/0#/type"}, "instanceLocation": {"const": ""}, "annotation": false }, "required": ["keywordLocation", "instanceLocation"] } } }, "required": ["errors"] } } } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/output-tests/draft2020-12/output-schema.json000066400000000000000000000045031477700171100324610ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/output/schema", "description": "A schema that validates the minimum requirements for validation output", "anyOf": [ { "$ref": "#/$defs/flag" }, { "$ref": "#/$defs/basic" }, { "$ref": "#/$defs/detailed" }, { "$ref": "#/$defs/verbose" } ], "$defs": { "outputUnit":{ "properties": { "valid": { "type": "boolean" }, "keywordLocation": { "type": "string", "format": "json-pointer" }, "absoluteKeywordLocation": { "type": "string", "format": "uri" }, "instanceLocation": { "type": "string", "format": "json-pointer" }, "error": { "type": "string" }, "errors": { "$ref": "#/$defs/outputUnitArray" }, "annotations": { "$ref": "#/$defs/outputUnitArray" } }, "required": [ "valid", "keywordLocation", "instanceLocation" ], "allOf": [ { "if": { "properties": { "valid": { "const": false } } }, "then": { "anyOf": [ { "required": [ "error" ] }, { "required": [ "errors" ] } ] } }, { "if": { "anyOf": [ { "properties": { "keywordLocation": { "pattern": "/\\$ref/" } } }, { "properties": { "keywordLocation": { "pattern": "/\\$dynamicRef/" } } } ] }, "then": { "required": [ "absoluteKeywordLocation" ] } } ] }, "outputUnitArray": { "type": "array", "items": { "$ref": "#/$defs/outputUnit" } }, "flag": { "properties": { "valid": { "type": "boolean" } }, "required": [ "valid" ] }, "basic": { "$ref": "#/$defs/outputUnit" }, "detailed": { "$ref": "#/$defs/outputUnit" }, "verbose": { "$ref": "#/$defs/outputUnit" } } } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/000077500000000000000000000000001477700171100241205ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/baseUriChange/000077500000000000000000000000001477700171100266205ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/baseUriChange/folderInteger.json000066400000000000000000000000321477700171100322770ustar00rootroot00000000000000{ "type": "integer" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/baseUriChangeFolder/000077500000000000000000000000001477700171100277545ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/baseUriChangeFolder/folderInteger.json000066400000000000000000000000321477700171100334330ustar00rootroot00000000000000{ "type": "integer" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/baseUriChangeFolderInSubschema/000077500000000000000000000000001477700171100320765ustar00rootroot00000000000000folderInteger.json000066400000000000000000000000321477700171100354760ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/baseUriChangeFolderInSubschema{ "type": "integer" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/different-id-ref-string.json000066400000000000000000000002041477700171100314250ustar00rootroot00000000000000{ "$id": "http://localhost:1234/real-id-ref-string.json", "$defs": {"bar": {"type": "string"}}, "$ref": "#/$defs/bar" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next/000077500000000000000000000000001477700171100261745ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next/baseUriChange/000077500000000000000000000000001477700171100306745ustar00rootroot00000000000000folderInteger.json000066400000000000000000000001261477700171100343000ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next/baseUriChange{ "$schema": "https://json-schema.org/draft/next/schema", "type": "integer" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next/baseUriChangeFolder/000077500000000000000000000000001477700171100320305ustar00rootroot00000000000000folderInteger.json000066400000000000000000000001261477700171100354340ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next/baseUriChangeFolder{ "$schema": "https://json-schema.org/draft/next/schema", "type": "integer" } baseUriChangeFolderInSubschema/000077500000000000000000000000001477700171100340735ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-nextfolderInteger.json000066400000000000000000000001261477700171100375560ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next/baseUriChangeFolderInSubschema{ "$schema": "https://json-schema.org/draft/next/schema", "type": "integer" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next/detached-dynamicref.json000066400000000000000000000004351477700171100327510ustar00rootroot00000000000000{ "$id": "http://localhost:1234/draft-next/detached-dynamicref.json", "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "foo": { "$dynamicRef": "#detached" }, "detached": { "$dynamicAnchor": "detached", "type": "integer" } } }jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next/detached-ref.json000066400000000000000000000004101477700171100313750ustar00rootroot00000000000000{ "$id": "http://localhost:1234/draft-next/detached-ref.json", "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "foo": { "$ref": "#detached" }, "detached": { "$anchor": "detached", "type": "integer" } } }jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next/extendible-dynamic-ref.json000066400000000000000000000010171477700171100334050ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/next/schema", "description": "extendible array", "$id": "http://localhost:1234/draft-next/extendible-dynamic-ref.json", "type": "object", "properties": { "elements": { "type": "array", "items": { "$dynamicRef": "#elements" } } }, "required": ["elements"], "additionalProperties": false, "$defs": { "elements": { "$dynamicAnchor": "elements" } } } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next/format-assertion-false.json000066400000000000000000000007311477700171100334550ustar00rootroot00000000000000{ "$id": "http://localhost:1234/draft-next/format-assertion-false.json", "$schema": "https://json-schema.org/draft/next/schema", "$vocabulary": { "https://json-schema.org/draft/next/vocab/core": true, "https://json-schema.org/draft/next/vocab/format-assertion": false }, "allOf": [ { "$ref": "https://json-schema.org/draft/next/meta/core" }, { "$ref": "https://json-schema.org/draft/next/meta/format-assertion" } ] } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next/format-assertion-true.json000066400000000000000000000007271477700171100333470ustar00rootroot00000000000000{ "$id": "http://localhost:1234/draft-next/format-assertion-true.json", "$schema": "https://json-schema.org/draft/next/schema", "$vocabulary": { "https://json-schema.org/draft/next/vocab/core": true, "https://json-schema.org/draft/next/vocab/format-assertion": true }, "allOf": [ { "$ref": "https://json-schema.org/draft/next/meta/core" }, { "$ref": "https://json-schema.org/draft/next/meta/format-assertion" } ] } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next/integer.json000066400000000000000000000001261477700171100305230ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/next/schema", "type": "integer" } locationIndependentIdentifier.json000066400000000000000000000003521477700171100350010ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next{ "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "refToInteger": { "$ref": "#foo" }, "A": { "$anchor": "foo", "type": "integer" } } } metaschema-no-validation.json000066400000000000000000000007161477700171100336650ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next{ "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://localhost:1234/draft-next/metaschema-no-validation.json", "$vocabulary": { "https://json-schema.org/draft/next/vocab/applicator": true, "https://json-schema.org/draft/next/vocab/core": true }, "allOf": [ { "$ref": "https://json-schema.org/draft/next/meta/applicator" }, { "$ref": "https://json-schema.org/draft/next/meta/core" } ] } metaschema-optional-vocabulary.json000066400000000000000000000010241477700171100351040ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next{ "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://localhost:1234/draft-next/metaschema-optional-vocabulary.json", "$vocabulary": { "https://json-schema.org/draft/next/vocab/validation": true, "https://json-schema.org/draft/next/vocab/core": true, "http://localhost:1234/draft/next/vocab/custom": false }, "allOf": [ { "$ref": "https://json-schema.org/draft/next/meta/validation" }, { "$ref": "https://json-schema.org/draft/next/meta/core" } ] } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next/name-defs.json000066400000000000000000000004721477700171100307310ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "orNull": { "anyOf": [ { "type": "null" }, { "$ref": "#" } ] } }, "type": "string" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next/nested/000077500000000000000000000000001477700171100274565ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next/nested/foo-ref-string.json000066400000000000000000000002271477700171100332130ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "properties": { "foo": {"$ref": "string.json"} } } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next/nested/string.json000066400000000000000000000001251477700171100316550ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/next/schema", "type": "string" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next/ref-and-defs.json000066400000000000000000000004461477700171100313260ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://localhost:1234/draft-next/ref-and-defs.json", "$defs": { "inner": { "properties": { "bar": { "type": "string" } } } }, "$ref": "#/$defs/inner" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next/subSchemas.json000066400000000000000000000003351477700171100311650ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "integer": { "type": "integer" }, "refToInteger": { "$ref": "#/$defs/integer" } } } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft-next/tree.json000066400000000000000000000006251477700171100300310ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/next/schema", "description": "tree schema, extensible", "$id": "http://localhost:1234/draft-next/tree.json", "$dynamicAnchor": "node", "type": "object", "properties": { "data": true, "children": { "type": "array", "items": { "$dynamicRef": "#node" } } } } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09/000077500000000000000000000000001477700171100257625ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09/baseUriChange/000077500000000000000000000000001477700171100304625ustar00rootroot00000000000000folderInteger.json000066400000000000000000000001311477700171100340620ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09/baseUriChange{ "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "integer" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09/baseUriChangeFolder/000077500000000000000000000000001477700171100316165ustar00rootroot00000000000000folderInteger.json000066400000000000000000000001311477700171100352160ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09/baseUriChangeFolder{ "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "integer" } baseUriChangeFolderInSubschema/000077500000000000000000000000001477700171100336615ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09folderInteger.json000066400000000000000000000001311477700171100373400ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09/baseUriChangeFolderInSubschema{ "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "integer" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09/dependentRequired.json000066400000000000000000000003031477700171100323200ustar00rootroot00000000000000{ "$id": "http://localhost:1234/draft2019-09/dependentRequired.json", "$schema": "https://json-schema.org/draft/2019-09/schema", "dependentRequired": { "foo": ["bar"] } } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09/detached-ref.json000066400000000000000000000004151477700171100311700ustar00rootroot00000000000000{ "$id": "http://localhost:1234/draft2019-09/detached-ref.json", "$schema": "https://json-schema.org/draft/2019-09/schema", "$defs": { "foo": { "$ref": "#detached" }, "detached": { "$anchor": "detached", "type": "integer" } } }extendible-dynamic-ref.json000066400000000000000000000010241477700171100331120ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09{ "description": "extendible array", "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:1234/draft2019-09/extendible-dynamic-ref.json", "type": "object", "properties": { "elements": { "type": "array", "items": { "$dynamicRef": "#elements" } } }, "required": ["elements"], "additionalProperties": false, "$defs": { "elements": { "$dynamicAnchor": "elements" } } } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09/ignore-prefixItems.json000066400000000000000000000003021477700171100324300ustar00rootroot00000000000000{ "$id": "http://localhost:1234/draft2019-09/ignore-prefixItems.json", "$schema": "https://json-schema.org/draft/2019-09/schema", "prefixItems": [ {"type": "string"} ] } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09/integer.json000066400000000000000000000001311477700171100303050ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "integer" } locationIndependentIdentifier.json000066400000000000000000000003551477700171100345720ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09{ "$schema": "https://json-schema.org/draft/2019-09/schema", "$defs": { "refToInteger": { "$ref": "#foo" }, "A": { "$anchor": "foo", "type": "integer" } } } metaschema-no-validation.json000066400000000000000000000007371477700171100334560ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09{ "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:1234/draft2019-09/metaschema-no-validation.json", "$vocabulary": { "https://json-schema.org/draft/2019-09/vocab/applicator": true, "https://json-schema.org/draft/2019-09/vocab/core": true }, "allOf": [ { "$ref": "https://json-schema.org/draft/2019-09/meta/applicator" }, { "$ref": "https://json-schema.org/draft/2019-09/meta/core" } ] } metaschema-optional-vocabulary.json000066400000000000000000000010501477700171100346710ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09{ "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:1234/draft2019-09/metaschema-optional-vocabulary.json", "$vocabulary": { "https://json-schema.org/draft/2019-09/vocab/validation": true, "https://json-schema.org/draft/2019-09/vocab/core": true, "http://localhost:1234/draft/2019-09/vocab/custom": false }, "allOf": [ { "$ref": "https://json-schema.org/draft/2019-09/meta/validation" }, { "$ref": "https://json-schema.org/draft/2019-09/meta/core" } ] } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09/name-defs.json000066400000000000000000000004751477700171100305220ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/2019-09/schema", "$defs": { "orNull": { "anyOf": [ { "type": "null" }, { "$ref": "#" } ] } }, "type": "string" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09/nested/000077500000000000000000000000001477700171100272445ustar00rootroot00000000000000foo-ref-string.json000066400000000000000000000002321477700171100327160ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09/nested{ "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "foo": {"$ref": "string.json"} } } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09/nested/string.json000066400000000000000000000001301477700171100314370ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "string" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09/ref-and-defs.json000066400000000000000000000004531477700171100311120ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:1234/draft2019-09/ref-and-defs.json", "$defs": { "inner": { "properties": { "bar": { "type": "string" } } } }, "$ref": "#/$defs/inner" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09/subSchemas.json000066400000000000000000000003401477700171100307470ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/2019-09/schema", "$defs": { "integer": { "type": "integer" }, "refToInteger": { "$ref": "#/$defs/integer" } } } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09/tree.json000066400000000000000000000006321477700171100276150ustar00rootroot00000000000000{ "description": "tree schema, extensible", "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:1234/draft2019-09/tree.json", "$dynamicAnchor": "node", "type": "object", "properties": { "data": true, "children": { "type": "array", "items": { "$dynamicRef": "#node" } } } } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12/000077500000000000000000000000001477700171100257445ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12/baseUriChange/000077500000000000000000000000001477700171100304445ustar00rootroot00000000000000folderInteger.json000066400000000000000000000001311477700171100340440ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12/baseUriChange{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "integer" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12/baseUriChangeFolder/000077500000000000000000000000001477700171100316005ustar00rootroot00000000000000folderInteger.json000066400000000000000000000001311477700171100352000ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12/baseUriChangeFolder{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "integer" } baseUriChangeFolderInSubschema/000077500000000000000000000000001477700171100336435ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12folderInteger.json000066400000000000000000000001311477700171100373220ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12/baseUriChangeFolderInSubschema{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "integer" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12/detached-dynamicref.json000066400000000000000000000004421477700171100325170ustar00rootroot00000000000000{ "$id": "http://localhost:1234/draft2020-12/detached-dynamicref.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "foo": { "$dynamicRef": "#detached" }, "detached": { "$dynamicAnchor": "detached", "type": "integer" } } }jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12/detached-ref.json000066400000000000000000000004151477700171100311520ustar00rootroot00000000000000{ "$id": "http://localhost:1234/draft2020-12/detached-ref.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "foo": { "$ref": "#detached" }, "detached": { "$anchor": "detached", "type": "integer" } } }extendible-dynamic-ref.json000066400000000000000000000010241477700171100330740ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12{ "description": "extendible array", "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://localhost:1234/draft2020-12/extendible-dynamic-ref.json", "type": "object", "properties": { "elements": { "type": "array", "items": { "$dynamicRef": "#elements" } } }, "required": ["elements"], "additionalProperties": false, "$defs": { "elements": { "$dynamicAnchor": "elements" } } } format-assertion-false.json000066400000000000000000000007521477700171100331510ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12{ "$id": "http://localhost:1234/draft2020-12/format-assertion-false.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "$vocabulary": { "https://json-schema.org/draft/2020-12/vocab/core": true, "https://json-schema.org/draft/2020-12/vocab/format-assertion": false }, "allOf": [ { "$ref": "https://json-schema.org/draft/2020-12/meta/core" }, { "$ref": "https://json-schema.org/draft/2020-12/meta/format-assertion" } ] } format-assertion-true.json000066400000000000000000000007501477700171100330340ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12{ "$id": "http://localhost:1234/draft2020-12/format-assertion-true.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "$vocabulary": { "https://json-schema.org/draft/2020-12/vocab/core": true, "https://json-schema.org/draft/2020-12/vocab/format-assertion": true }, "allOf": [ { "$ref": "https://json-schema.org/draft/2020-12/meta/core" }, { "$ref": "https://json-schema.org/draft/2020-12/meta/format-assertion" } ] } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12/integer.json000066400000000000000000000001311477700171100302670ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "integer" } locationIndependentIdentifier.json000066400000000000000000000003551477700171100345540ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "refToInteger": { "$ref": "#foo" }, "A": { "$anchor": "foo", "type": "integer" } } } metaschema-no-validation.json000066400000000000000000000007371477700171100334400ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://localhost:1234/draft2020-12/metaschema-no-validation.json", "$vocabulary": { "https://json-schema.org/draft/2020-12/vocab/applicator": true, "https://json-schema.org/draft/2020-12/vocab/core": true }, "allOf": [ { "$ref": "https://json-schema.org/draft/2020-12/meta/applicator" }, { "$ref": "https://json-schema.org/draft/2020-12/meta/core" } ] } metaschema-optional-vocabulary.json000066400000000000000000000010501477700171100346530ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://localhost:1234/draft2020-12/metaschema-optional-vocabulary.json", "$vocabulary": { "https://json-schema.org/draft/2020-12/vocab/validation": true, "https://json-schema.org/draft/2020-12/vocab/core": true, "http://localhost:1234/draft/2020-12/vocab/custom": false }, "allOf": [ { "$ref": "https://json-schema.org/draft/2020-12/meta/validation" }, { "$ref": "https://json-schema.org/draft/2020-12/meta/core" } ] } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12/name-defs.json000066400000000000000000000004751477700171100305040ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "orNull": { "anyOf": [ { "type": "null" }, { "$ref": "#" } ] } }, "type": "string" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12/nested/000077500000000000000000000000001477700171100272265ustar00rootroot00000000000000foo-ref-string.json000066400000000000000000000002321477700171100327000ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12/nested{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "foo": {"$ref": "string.json"} } } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12/nested/string.json000066400000000000000000000001301477700171100314210ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "string" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12/prefixItems.json000066400000000000000000000002731477700171100311400ustar00rootroot00000000000000{ "$id": "http://localhost:1234/draft2020-12/prefixItems.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [ {"type": "string"} ] } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12/ref-and-defs.json000066400000000000000000000004531477700171100310740ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://localhost:1234/draft2020-12/ref-and-defs.json", "$defs": { "inner": { "properties": { "bar": { "type": "string" } } } }, "$ref": "#/$defs/inner" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12/subSchemas.json000066400000000000000000000003401477700171100307310ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "integer": { "type": "integer" }, "refToInteger": { "$ref": "#/$defs/integer" } } } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft2020-12/tree.json000066400000000000000000000006321477700171100275770ustar00rootroot00000000000000{ "description": "tree schema, extensible", "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://localhost:1234/draft2020-12/tree.json", "$dynamicAnchor": "node", "type": "object", "properties": { "data": true, "children": { "type": "array", "items": { "$dynamicRef": "#node" } } } } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft6/000077500000000000000000000000001477700171100253065ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft6/detached-ref.json000066400000000000000000000004051477700171100305130ustar00rootroot00000000000000{ "$id": "http://localhost:1234/draft6/detached-ref.json", "$schema": "http://json-schema.org/draft-06/schema#", "definitions": { "foo": { "$ref": "#detached" }, "detached": { "$id": "#detached", "type": "integer" } } }jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft7/000077500000000000000000000000001477700171100253075ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft7/detached-ref.json000066400000000000000000000004051477700171100305140ustar00rootroot00000000000000{ "$id": "http://localhost:1234/draft7/detached-ref.json", "$schema": "http://json-schema.org/draft-07/schema#", "definitions": { "foo": { "$ref": "#detached" }, "detached": { "$id": "#detached", "type": "integer" } } }jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/draft7/ignore-dependentRequired.json000066400000000000000000000002551477700171100331340ustar00rootroot00000000000000{ "$id": "http://localhost:1234/draft7/integer.json", "$schema": "http://json-schema.org/draft-07/schema#", "dependentRequired": { "foo": ["bar"] } }jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/extendible-dynamic-ref.json000066400000000000000000000007101477700171100313300ustar00rootroot00000000000000{ "description": "extendible array", "$id": "http://localhost:1234/extendible-dynamic-ref.json", "type": "object", "properties": { "elements": { "type": "array", "items": { "$dynamicRef": "#elements" } } }, "required": ["elements"], "additionalProperties": false, "$defs": { "elements": { "$dynamicAnchor": "elements" } } } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/integer.json000066400000000000000000000000321477700171100264430ustar00rootroot00000000000000{ "type": "integer" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/locationIndependentIdentifier.json000066400000000000000000000002561477700171100330070ustar00rootroot00000000000000{ "$defs": { "refToInteger": { "$ref": "#foo" }, "A": { "$anchor": "foo", "type": "integer" } } } locationIndependentIdentifierDraft4.json000066400000000000000000000002601477700171100337700ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes{ "definitions": { "refToInteger": { "$ref": "#foo" }, "A": { "id": "#foo", "type": "integer" } } } locationIndependentIdentifierPre2019.json000066400000000000000000000002611477700171100337070ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes{ "definitions": { "refToInteger": { "$ref": "#foo" }, "A": { "$id": "#foo", "type": "integer" } } } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/name-defs.json000066400000000000000000000003761477700171100266600ustar00rootroot00000000000000{ "$defs": { "orNull": { "anyOf": [ { "type": "null" }, { "$ref": "#" } ] } }, "type": "string" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/name.json000066400000000000000000000004041477700171100257310ustar00rootroot00000000000000{ "definitions": { "orNull": { "anyOf": [ { "type": "null" }, { "$ref": "#" } ] } }, "type": "string" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/nested-absolute-ref-to-string.json000066400000000000000000000003101477700171100326010ustar00rootroot00000000000000{ "$defs": { "bar": { "$id": "http://localhost:1234/the-nested-id.json", "type": "string" } }, "$ref": "http://localhost:1234/the-nested-id.json" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/nested/000077500000000000000000000000001477700171100254025ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/nested/foo-ref-string.json000066400000000000000000000001331477700171100311330ustar00rootroot00000000000000{ "type": "object", "properties": { "foo": {"$ref": "string.json"} } } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/nested/string.json000066400000000000000000000000311477700171100275750ustar00rootroot00000000000000{ "type": "string" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/ref-and-definitions.json000066400000000000000000000004031477700171100306350ustar00rootroot00000000000000{ "$id": "http://localhost:1234/ref-and-definitions.json", "definitions": { "inner": { "properties": { "bar": { "type": "string" } } } }, "allOf": [ { "$ref": "#/definitions/inner" } ] } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/ref-and-defs.json000066400000000000000000000003371477700171100272510ustar00rootroot00000000000000{ "$id": "http://localhost:1234/ref-and-defs.json", "$defs": { "inner": { "properties": { "bar": { "type": "string" } } } }, "$ref": "#/$defs/inner" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/subSchemas.json000066400000000000000000000002551477700171100271120ustar00rootroot00000000000000{ "definitions": { "integer": { "type": "integer" }, "refToInteger": { "$ref": "#/definitions/integer" } } } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/tree.json000066400000000000000000000005161477700171100257540ustar00rootroot00000000000000{ "description": "tree schema, extensible", "$id": "http://localhost:1234/tree.json", "$dynamicAnchor": "node", "type": "object", "properties": { "data": true, "children": { "type": "array", "items": { "$dynamicRef": "#node" } } } } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/remotes/urn-ref-string.json000066400000000000000000000002041477700171100276710ustar00rootroot00000000000000{ "$id": "urn:uuid:feebdaed-ffff-0000-ffff-0000deadbeef", "$defs": {"bar": {"type": "string"}}, "$ref": "#/$defs/bar" } jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/000077500000000000000000000000001477700171100236045ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/000077500000000000000000000000001477700171100256605ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/additionalProperties.json000066400000000000000000000114741477700171100327470ustar00rootroot00000000000000[ { "description": "additionalProperties being false does not allow other properties", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": {"foo": {}, "bar": {}}, "patternProperties": { "^v": {} }, "additionalProperties": false }, "tests": [ { "description": "no additional properties is valid", "data": {"foo": 1}, "valid": true }, { "description": "an additional property is invalid", "data": {"foo" : 1, "bar" : 2, "quux" : "boom"}, "valid": false }, { "description": "ignores arrays", "data": [1, 2, 3], "valid": true }, { "description": "ignores strings", "data": "foobarbaz", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true }, { "description": "patternProperties are not additional properties", "data": {"foo":1, "vroom": 2}, "valid": true } ] }, { "description": "non-ASCII pattern with additionalProperties", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "patternProperties": {"^á": {}}, "additionalProperties": false }, "tests": [ { "description": "matching the pattern is valid", "data": {"ármányos": 2}, "valid": true }, { "description": "not matching the pattern is invalid", "data": {"élmény": 2}, "valid": false } ] }, { "description": "additionalProperties with schema", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": {"foo": {}, "bar": {}}, "additionalProperties": {"type": "boolean"} }, "tests": [ { "description": "no additional properties is valid", "data": {"foo": 1}, "valid": true }, { "description": "an additional valid property is valid", "data": {"foo" : 1, "bar" : 2, "quux" : true}, "valid": true }, { "description": "an additional invalid property is invalid", "data": {"foo" : 1, "bar" : 2, "quux" : 12}, "valid": false } ] }, { "description": "additionalProperties can exist by itself", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "additionalProperties": {"type": "boolean"} }, "tests": [ { "description": "an additional valid property is valid", "data": {"foo" : true}, "valid": true }, { "description": "an additional invalid property is invalid", "data": {"foo" : 1}, "valid": false } ] }, { "description": "additionalProperties are allowed by default", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": {"foo": {}, "bar": {}} }, "tests": [ { "description": "additional properties are allowed", "data": {"foo": 1, "bar": 2, "quux": true}, "valid": true } ] }, { "description": "additionalProperties does not look in applicators", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "allOf": [ {"properties": {"foo": {}}} ], "additionalProperties": {"type": "boolean"} }, "tests": [ { "description": "properties defined in allOf are not examined", "data": {"foo": 1, "bar": true}, "valid": false } ] }, { "description": "additionalProperties with null valued instance properties", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "additionalProperties": { "type": "null" } }, "tests": [ { "description": "allows null values", "data": {"foo": null}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/allOf.json000066400000000000000000000207311477700171100276130ustar00rootroot00000000000000[ { "description": "allOf", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "allOf": [ { "properties": { "bar": {"type": "integer"} }, "required": ["bar"] }, { "properties": { "foo": {"type": "string"} }, "required": ["foo"] } ] }, "tests": [ { "description": "allOf", "data": {"foo": "baz", "bar": 2}, "valid": true }, { "description": "mismatch second", "data": {"foo": "baz"}, "valid": false }, { "description": "mismatch first", "data": {"bar": 2}, "valid": false }, { "description": "wrong type", "data": {"foo": "baz", "bar": "quux"}, "valid": false } ] }, { "description": "allOf with base schema", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": {"bar": {"type": "integer"}}, "required": ["bar"], "allOf" : [ { "properties": { "foo": {"type": "string"} }, "required": ["foo"] }, { "properties": { "baz": {"type": "null"} }, "required": ["baz"] } ] }, "tests": [ { "description": "valid", "data": {"foo": "quux", "bar": 2, "baz": null}, "valid": true }, { "description": "mismatch base schema", "data": {"foo": "quux", "baz": null}, "valid": false }, { "description": "mismatch first allOf", "data": {"bar": 2, "baz": null}, "valid": false }, { "description": "mismatch second allOf", "data": {"foo": "quux", "bar": 2}, "valid": false }, { "description": "mismatch both", "data": {"bar": 2}, "valid": false } ] }, { "description": "allOf simple types", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "allOf": [ {"maximum": 30}, {"minimum": 20} ] }, "tests": [ { "description": "valid", "data": 25, "valid": true }, { "description": "mismatch one", "data": 35, "valid": false } ] }, { "description": "allOf with boolean schemas, all true", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "allOf": [true, true] }, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "allOf with boolean schemas, some false", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "allOf": [true, false] }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "allOf with boolean schemas, all false", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "allOf": [false, false] }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "allOf with one empty schema", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "allOf": [ {} ] }, "tests": [ { "description": "any data is valid", "data": 1, "valid": true } ] }, { "description": "allOf with two empty schemas", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "allOf": [ {}, {} ] }, "tests": [ { "description": "any data is valid", "data": 1, "valid": true } ] }, { "description": "allOf with the first empty schema", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "allOf": [ {}, { "type": "number" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "string is invalid", "data": "foo", "valid": false } ] }, { "description": "allOf with the last empty schema", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "allOf": [ { "type": "number" }, {} ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "string is invalid", "data": "foo", "valid": false } ] }, { "description": "nested allOf, to check validation semantics", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "allOf": [ { "allOf": [ { "type": "null" } ] } ] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "anything non-null is invalid", "data": 123, "valid": false } ] }, { "description": "allOf combined with anyOf, oneOf", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "allOf": [ { "multipleOf": 2 } ], "anyOf": [ { "multipleOf": 3 } ], "oneOf": [ { "multipleOf": 5 } ] }, "tests": [ { "description": "allOf: false, anyOf: false, oneOf: false", "data": 1, "valid": false }, { "description": "allOf: false, anyOf: false, oneOf: true", "data": 5, "valid": false }, { "description": "allOf: false, anyOf: true, oneOf: false", "data": 3, "valid": false }, { "description": "allOf: false, anyOf: true, oneOf: true", "data": 15, "valid": false }, { "description": "allOf: true, anyOf: false, oneOf: false", "data": 2, "valid": false }, { "description": "allOf: true, anyOf: false, oneOf: true", "data": 10, "valid": false }, { "description": "allOf: true, anyOf: true, oneOf: false", "data": 6, "valid": false }, { "description": "allOf: true, anyOf: true, oneOf: true", "data": 30, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/anchor.json000066400000000000000000000157401477700171100300340ustar00rootroot00000000000000[ { "description": "Location-independent identifier", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "#foo", "$defs": { "A": { "$anchor": "foo", "type": "integer" } } }, "tests": [ { "data": 1, "description": "match", "valid": true }, { "data": "a", "description": "mismatch", "valid": false } ] }, { "description": "Location-independent identifier with absolute URI", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "http://localhost:1234/draft-next/bar#foo", "$defs": { "A": { "$id": "http://localhost:1234/draft-next/bar", "$anchor": "foo", "type": "integer" } } }, "tests": [ { "data": 1, "description": "match", "valid": true }, { "data": "a", "description": "mismatch", "valid": false } ] }, { "description": "Location-independent identifier with base URI change in subschema", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://localhost:1234/draft-next/root", "$ref": "http://localhost:1234/draft-next/nested.json#foo", "$defs": { "A": { "$id": "nested.json", "$defs": { "B": { "$anchor": "foo", "type": "integer" } } } } }, "tests": [ { "data": 1, "description": "match", "valid": true }, { "data": "a", "description": "mismatch", "valid": false } ] }, { "description": "$anchor inside an enum is not a real identifier", "comment": "the implementation must not be confused by an $anchor buried in the enum", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "anchor_in_enum": { "enum": [ { "$anchor": "my_anchor", "type": "null" } ] }, "real_identifier_in_schema": { "$anchor": "my_anchor", "type": "string" }, "zzz_anchor_in_const": { "const": { "$anchor": "my_anchor", "type": "null" } } }, "anyOf": [ { "$ref": "#/$defs/anchor_in_enum" }, { "$ref": "#my_anchor" } ] }, "tests": [ { "description": "exact match to enum, and type matches", "data": { "$anchor": "my_anchor", "type": "null" }, "valid": true }, { "description": "in implementations that strip $anchor, this may match either $def", "data": { "type": "null" }, "valid": false }, { "description": "match $ref to $anchor", "data": "a string to match #/$defs/anchor_in_enum", "valid": true }, { "description": "no match on enum or $ref to $anchor", "data": 1, "valid": false } ] }, { "description": "same $anchor with different base uri", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://localhost:1234/draft-next/foobar", "$defs": { "A": { "$id": "child1", "allOf": [ { "$id": "child2", "$anchor": "my_anchor", "type": "number" }, { "$anchor": "my_anchor", "type": "string" } ] } }, "$ref": "child1#my_anchor" }, "tests": [ { "description": "$ref resolves to /$defs/A/allOf/1", "data": "a", "valid": true }, { "description": "$ref does not resolve to /$defs/A/allOf/0", "data": 1, "valid": false } ] }, { "description": "non-schema object containing an $anchor property", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "const_not_anchor": { "const": { "$anchor": "not_a_real_anchor" } } }, "if": { "const": "skip not_a_real_anchor" }, "then": true, "else" : { "$ref": "#/$defs/const_not_anchor" } }, "tests": [ { "description": "skip traversing definition for a valid result", "data": "skip not_a_real_anchor", "valid": true }, { "description": "const at const_not_anchor does not match", "data": 1, "valid": false } ] }, { "description": "invalid anchors", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "https://json-schema.org/draft/next/schema" }, "tests": [ { "description": "MUST start with a letter (and not #)", "data": { "$anchor" : "#foo" }, "valid": false }, { "description": "JSON pointers are not valid", "data": { "$anchor" : "/a/b" }, "valid": false }, { "description": "invalid with valid beginning", "data": { "$anchor" : "foo#something" }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/anyOf.json000066400000000000000000000124751477700171100276400ustar00rootroot00000000000000[ { "description": "anyOf", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "anyOf": [ { "type": "integer" }, { "minimum": 2 } ] }, "tests": [ { "description": "first anyOf valid", "data": 1, "valid": true }, { "description": "second anyOf valid", "data": 2.5, "valid": true }, { "description": "both anyOf valid", "data": 3, "valid": true }, { "description": "neither anyOf valid", "data": 1.5, "valid": false } ] }, { "description": "anyOf with base schema", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "string", "anyOf" : [ { "maxLength": 2 }, { "minLength": 4 } ] }, "tests": [ { "description": "mismatch base schema", "data": 3, "valid": false }, { "description": "one anyOf valid", "data": "foobar", "valid": true }, { "description": "both anyOf invalid", "data": "foo", "valid": false } ] }, { "description": "anyOf with boolean schemas, all true", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "anyOf": [true, true] }, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "anyOf with boolean schemas, some true", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "anyOf": [true, false] }, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "anyOf with boolean schemas, all false", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "anyOf": [false, false] }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "anyOf complex types", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "anyOf": [ { "properties": { "bar": {"type": "integer"} }, "required": ["bar"] }, { "properties": { "foo": {"type": "string"} }, "required": ["foo"] } ] }, "tests": [ { "description": "first anyOf valid (complex)", "data": {"bar": 2}, "valid": true }, { "description": "second anyOf valid (complex)", "data": {"foo": "baz"}, "valid": true }, { "description": "both anyOf valid (complex)", "data": {"foo": "baz", "bar": 2}, "valid": true }, { "description": "neither anyOf valid (complex)", "data": {"foo": 2, "bar": "quux"}, "valid": false } ] }, { "description": "anyOf with one empty schema", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "anyOf": [ { "type": "number" }, {} ] }, "tests": [ { "description": "string is valid", "data": "foo", "valid": true }, { "description": "number is valid", "data": 123, "valid": true } ] }, { "description": "nested anyOf, to check validation semantics", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "anyOf": [ { "anyOf": [ { "type": "null" } ] } ] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "anything non-null is invalid", "data": 123, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/boolean_schema.json000066400000000000000000000054021477700171100315130ustar00rootroot00000000000000[ { "description": "boolean schema 'true'", "schema": true, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "string is valid", "data": "foo", "valid": true }, { "description": "boolean true is valid", "data": true, "valid": true }, { "description": "boolean false is valid", "data": false, "valid": true }, { "description": "null is valid", "data": null, "valid": true }, { "description": "object is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "empty object is valid", "data": {}, "valid": true }, { "description": "array is valid", "data": ["foo"], "valid": true }, { "description": "empty array is valid", "data": [], "valid": true } ] }, { "description": "boolean schema 'false'", "schema": false, "tests": [ { "description": "number is invalid", "data": 1, "valid": false }, { "description": "string is invalid", "data": "foo", "valid": false }, { "description": "boolean true is invalid", "data": true, "valid": false }, { "description": "boolean false is invalid", "data": false, "valid": false }, { "description": "null is invalid", "data": null, "valid": false }, { "description": "object is invalid", "data": {"foo": "bar"}, "valid": false }, { "description": "empty object is invalid", "data": {}, "valid": false }, { "description": "array is invalid", "data": ["foo"], "valid": false }, { "description": "empty array is invalid", "data": [], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/const.json000066400000000000000000000252701477700171100277070ustar00rootroot00000000000000[ { "description": "const validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "const": 2 }, "tests": [ { "description": "same value is valid", "data": 2, "valid": true }, { "description": "another value is invalid", "data": 5, "valid": false }, { "description": "another type is invalid", "data": "a", "valid": false } ] }, { "description": "const with object", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "const": {"foo": "bar", "baz": "bax"} }, "tests": [ { "description": "same object is valid", "data": {"foo": "bar", "baz": "bax"}, "valid": true }, { "description": "same object with different property order is valid", "data": {"baz": "bax", "foo": "bar"}, "valid": true }, { "description": "another object is invalid", "data": {"foo": "bar"}, "valid": false }, { "description": "another type is invalid", "data": [1, 2], "valid": false } ] }, { "description": "const with array", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "const": [{ "foo": "bar" }] }, "tests": [ { "description": "same array is valid", "data": [{"foo": "bar"}], "valid": true }, { "description": "another array item is invalid", "data": [2], "valid": false }, { "description": "array with additional items is invalid", "data": [1, 2, 3], "valid": false } ] }, { "description": "const with null", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "const": null }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "not null is invalid", "data": 0, "valid": false } ] }, { "description": "const with false does not match 0", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "const": false }, "tests": [ { "description": "false is valid", "data": false, "valid": true }, { "description": "integer zero is invalid", "data": 0, "valid": false }, { "description": "float zero is invalid", "data": 0.0, "valid": false } ] }, { "description": "const with true does not match 1", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "const": true }, "tests": [ { "description": "true is valid", "data": true, "valid": true }, { "description": "integer one is invalid", "data": 1, "valid": false }, { "description": "float one is invalid", "data": 1.0, "valid": false } ] }, { "description": "const with [false] does not match [0]", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "const": [false] }, "tests": [ { "description": "[false] is valid", "data": [false], "valid": true }, { "description": "[0] is invalid", "data": [0], "valid": false }, { "description": "[0.0] is invalid", "data": [0.0], "valid": false } ] }, { "description": "const with [true] does not match [1]", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "const": [true] }, "tests": [ { "description": "[true] is valid", "data": [true], "valid": true }, { "description": "[1] is invalid", "data": [1], "valid": false }, { "description": "[1.0] is invalid", "data": [1.0], "valid": false } ] }, { "description": "const with {\"a\": false} does not match {\"a\": 0}", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "const": {"a": false} }, "tests": [ { "description": "{\"a\": false} is valid", "data": {"a": false}, "valid": true }, { "description": "{\"a\": 0} is invalid", "data": {"a": 0}, "valid": false }, { "description": "{\"a\": 0.0} is invalid", "data": {"a": 0.0}, "valid": false } ] }, { "description": "const with {\"a\": true} does not match {\"a\": 1}", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "const": {"a": true} }, "tests": [ { "description": "{\"a\": true} is valid", "data": {"a": true}, "valid": true }, { "description": "{\"a\": 1} is invalid", "data": {"a": 1}, "valid": false }, { "description": "{\"a\": 1.0} is invalid", "data": {"a": 1.0}, "valid": false } ] }, { "description": "const with 0 does not match other zero-like types", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "const": 0 }, "tests": [ { "description": "false is invalid", "data": false, "valid": false }, { "description": "integer zero is valid", "data": 0, "valid": true }, { "description": "float zero is valid", "data": 0.0, "valid": true }, { "description": "empty object is invalid", "data": {}, "valid": false }, { "description": "empty array is invalid", "data": [], "valid": false }, { "description": "empty string is invalid", "data": "", "valid": false } ] }, { "description": "const with 1 does not match true", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "const": 1 }, "tests": [ { "description": "true is invalid", "data": true, "valid": false }, { "description": "integer one is valid", "data": 1, "valid": true }, { "description": "float one is valid", "data": 1.0, "valid": true } ] }, { "description": "const with -2.0 matches integer and float types", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "const": -2.0 }, "tests": [ { "description": "integer -2 is valid", "data": -2, "valid": true }, { "description": "integer 2 is invalid", "data": 2, "valid": false }, { "description": "float -2.0 is valid", "data": -2.0, "valid": true }, { "description": "float 2.0 is invalid", "data": 2.0, "valid": false }, { "description": "float -2.00001 is invalid", "data": -2.00001, "valid": false } ] }, { "description": "float and integers are equal up to 64-bit representation limits", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "const": 9007199254740992 }, "tests": [ { "description": "integer is valid", "data": 9007199254740992, "valid": true }, { "description": "integer minus one is invalid", "data": 9007199254740991, "valid": false }, { "description": "float is valid", "data": 9007199254740992.0, "valid": true }, { "description": "float minus one is invalid", "data": 9007199254740991.0, "valid": false } ] }, { "description": "nul characters in strings", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "const": "hello\u0000there" }, "tests": [ { "description": "match string with nul", "data": "hello\u0000there", "valid": true }, { "description": "do not match string lacking nul", "data": "hellothere", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/contains.json000066400000000000000000000133071477700171100303750ustar00rootroot00000000000000[ { "description": "contains keyword validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "contains": { "minimum": 5 } }, "tests": [ { "description": "array with item matching schema (5) is valid", "data": [3, 4, 5], "valid": true }, { "description": "array with item matching schema (6) is valid", "data": [3, 4, 6], "valid": true }, { "description": "array with two items matching schema (5, 6) is valid", "data": [3, 4, 5, 6], "valid": true }, { "description": "array without items matching schema is invalid", "data": [2, 3, 4], "valid": false }, { "description": "empty array is invalid", "data": [], "valid": false }, { "description": "not array or object is valid", "data": 42, "valid": true } ] }, { "description": "contains keyword with const keyword", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "contains": { "const": 5 } }, "tests": [ { "description": "array with item 5 is valid", "data": [3, 4, 5], "valid": true }, { "description": "array with two items 5 is valid", "data": [3, 4, 5, 5], "valid": true }, { "description": "array without item 5 is invalid", "data": [1, 2, 3, 4], "valid": false } ] }, { "description": "contains keyword with boolean schema true", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "contains": true }, "tests": [ { "description": "any non-empty array is valid", "data": ["foo"], "valid": true }, { "description": "empty array is invalid", "data": [], "valid": false } ] }, { "description": "contains keyword with boolean schema false", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "contains": false }, "tests": [ { "description": "any non-empty array is invalid", "data": ["foo"], "valid": false }, { "description": "empty array is invalid", "data": [], "valid": false }, { "description": "non-arrays are valid - string", "data": "contains does not apply to strings", "valid": true }, { "description": "non-arrays are valid - object", "data": {}, "valid": true }, { "description": "non-arrays are valid - number", "data": 42, "valid": true }, { "description": "non-arrays are valid - boolean", "data": false, "valid": true }, { "description": "non-arrays are valid - null", "data": null, "valid": true } ] }, { "description": "items + contains", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "additionalProperties": { "multipleOf": 2 }, "items": { "multipleOf": 2 }, "contains": { "multipleOf": 3 } }, "tests": [ { "description": "matches items, does not match contains", "data": [2, 4, 8], "valid": false }, { "description": "does not match items, matches contains", "data": [3, 6, 9], "valid": false }, { "description": "matches both items and contains", "data": [6, 12], "valid": true }, { "description": "matches neither items nor contains", "data": [1, 5], "valid": false } ] }, { "description": "contains with false if subschema", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "contains": { "if": false, "else": true } }, "tests": [ { "description": "any non-empty array is valid", "data": ["foo"], "valid": true }, { "description": "empty array is invalid", "data": [], "valid": false } ] }, { "description": "contains with null instance elements", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "contains": { "type": "null" } }, "tests": [ { "description": "allows null items", "data": [ null ], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/content.json000066400000000000000000000104411477700171100302250ustar00rootroot00000000000000[ { "description": "validation of string-encoded content based on media type", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "contentMediaType": "application/json" }, "tests": [ { "description": "a valid JSON document", "data": "{\"foo\": \"bar\"}", "valid": true }, { "description": "an invalid JSON document; validates true", "data": "{:}", "valid": true }, { "description": "ignores non-strings", "data": 100, "valid": true } ] }, { "description": "validation of binary string-encoding", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "contentEncoding": "base64" }, "tests": [ { "description": "a valid base64 string", "data": "eyJmb28iOiAiYmFyIn0K", "valid": true }, { "description": "an invalid base64 string (% is not a valid character); validates true", "data": "eyJmb28iOi%iYmFyIn0K", "valid": true }, { "description": "ignores non-strings", "data": 100, "valid": true } ] }, { "description": "validation of binary-encoded media type documents", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "contentMediaType": "application/json", "contentEncoding": "base64" }, "tests": [ { "description": "a valid base64-encoded JSON document", "data": "eyJmb28iOiAiYmFyIn0K", "valid": true }, { "description": "a validly-encoded invalid JSON document; validates true", "data": "ezp9Cg==", "valid": true }, { "description": "an invalid base64 string that is valid JSON; validates true", "data": "{}", "valid": true }, { "description": "ignores non-strings", "data": 100, "valid": true } ] }, { "description": "validation of binary-encoded media type documents with schema", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "contentMediaType": "application/json", "contentEncoding": "base64", "contentSchema": { "type": "object", "required": ["foo"], "properties": { "foo": { "type": "string" } } } }, "tests": [ { "description": "a valid base64-encoded JSON document", "data": "eyJmb28iOiAiYmFyIn0K", "valid": true }, { "description": "another valid base64-encoded JSON document", "data": "eyJib28iOiAyMCwgImZvbyI6ICJiYXoifQ==", "valid": true }, { "description": "an invalid base64-encoded JSON document; validates true", "data": "eyJib28iOiAyMH0=", "valid": true }, { "description": "an empty object as a base64-encoded JSON document; validates true", "data": "e30=", "valid": true }, { "description": "an empty array as a base64-encoded JSON document", "data": "W10=", "valid": true }, { "description": "a validly-encoded invalid JSON document; validates true", "data": "ezp9Cg==", "valid": true }, { "description": "an invalid base64 string that is valid JSON; validates true", "data": "{}", "valid": true }, { "description": "ignores non-strings", "data": 100, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/default.json000066400000000000000000000046031477700171100302020ustar00rootroot00000000000000[ { "description": "invalid type for default", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": { "foo": { "type": "integer", "default": [] } } }, "tests": [ { "description": "valid when property is specified", "data": {"foo": 13}, "valid": true }, { "description": "still valid when the invalid default is used", "data": {}, "valid": true } ] }, { "description": "invalid string value for default", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": { "bar": { "type": "string", "minLength": 4, "default": "bad" } } }, "tests": [ { "description": "valid when property is specified", "data": {"bar": "good"}, "valid": true }, { "description": "still valid when the invalid default is used", "data": {}, "valid": true } ] }, { "description": "the default keyword does not do anything if the property is missing", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "properties": { "alpha": { "type": "number", "maximum": 3, "default": 5 } } }, "tests": [ { "description": "an explicit property value is checked against maximum (passing)", "data": { "alpha": 1 }, "valid": true }, { "description": "an explicit property value is checked against maximum (failing)", "data": { "alpha": 5 }, "valid": false }, { "description": "missing properties are not filled in with the default", "data": {}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/defs.json000066400000000000000000000011671477700171100275010ustar00rootroot00000000000000[ { "description": "validate definition against metaschema", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "https://json-schema.org/draft/next/schema" }, "tests": [ { "description": "valid definition schema", "data": {"$defs": {"foo": {"type": "integer"}}}, "valid": true }, { "description": "invalid definition schema", "data": {"$defs": {"foo": {"type": 1}}}, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/dependentRequired.json000066400000000000000000000102721477700171100322240ustar00rootroot00000000000000[ { "description": "single dependency", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "dependentRequired": {"bar": ["foo"]} }, "tests": [ { "description": "neither", "data": {}, "valid": true }, { "description": "nondependant", "data": {"foo": 1}, "valid": true }, { "description": "with dependency", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "missing dependency", "data": {"bar": 2}, "valid": false }, { "description": "ignores arrays", "data": ["bar"], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "empty dependents", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "dependentRequired": {"bar": []} }, "tests": [ { "description": "empty object", "data": {}, "valid": true }, { "description": "object with one property", "data": {"bar": 2}, "valid": true }, { "description": "non-object is valid", "data": 1, "valid": true } ] }, { "description": "multiple dependents required", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "dependentRequired": {"quux": ["foo", "bar"]} }, "tests": [ { "description": "neither", "data": {}, "valid": true }, { "description": "nondependants", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "with dependencies", "data": {"foo": 1, "bar": 2, "quux": 3}, "valid": true }, { "description": "missing dependency", "data": {"foo": 1, "quux": 2}, "valid": false }, { "description": "missing other dependency", "data": {"bar": 1, "quux": 2}, "valid": false }, { "description": "missing both dependencies", "data": {"quux": 1}, "valid": false } ] }, { "description": "dependencies with escaped characters", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "dependentRequired": { "foo\nbar": ["foo\rbar"], "foo\"bar": ["foo'bar"] } }, "tests": [ { "description": "CRLF", "data": { "foo\nbar": 1, "foo\rbar": 2 }, "valid": true }, { "description": "quoted quotes", "data": { "foo'bar": 1, "foo\"bar": 2 }, "valid": true }, { "description": "CRLF missing dependent", "data": { "foo\nbar": 1, "foo": 2 }, "valid": false }, { "description": "quoted quotes missing dependent", "data": { "foo\"bar": 2 }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/dependentSchemas.json000066400000000000000000000115411477700171100320270ustar00rootroot00000000000000[ { "description": "single dependency", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "dependentSchemas": { "bar": { "properties": { "foo": {"type": "integer"}, "bar": {"type": "integer"} } } } }, "tests": [ { "description": "valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "no dependency", "data": {"foo": "quux"}, "valid": true }, { "description": "wrong type", "data": {"foo": "quux", "bar": 2}, "valid": false }, { "description": "wrong type other", "data": {"foo": 2, "bar": "quux"}, "valid": false }, { "description": "wrong type both", "data": {"foo": "quux", "bar": "quux"}, "valid": false }, { "description": "ignores arrays", "data": ["bar"], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "boolean subschemas", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "dependentSchemas": { "foo": true, "bar": false } }, "tests": [ { "description": "object with property having schema true is valid", "data": {"foo": 1}, "valid": true }, { "description": "object with property having schema false is invalid", "data": {"bar": 2}, "valid": false }, { "description": "object with both properties is invalid", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "empty object is valid", "data": {}, "valid": true } ] }, { "description": "dependencies with escaped characters", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "dependentSchemas": { "foo\tbar": {"minProperties": 4}, "foo'bar": {"required": ["foo\"bar"]} } }, "tests": [ { "description": "quoted tab", "data": { "foo\tbar": 1, "a": 2, "b": 3, "c": 4 }, "valid": true }, { "description": "quoted quote", "data": { "foo'bar": {"foo\"bar": 1} }, "valid": false }, { "description": "quoted tab invalid under dependent schema", "data": { "foo\tbar": 1, "a": 2 }, "valid": false }, { "description": "quoted quote invalid under dependent schema", "data": {"foo'bar": 1}, "valid": false } ] }, { "description": "dependent subschema incompatible with root", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": { "foo": {} }, "dependentSchemas": { "foo": { "properties": { "bar": {} }, "additionalProperties": false } } }, "tests": [ { "description": "matches root", "data": {"foo": 1}, "valid": false }, { "description": "matches dependency", "data": {"bar": 1}, "valid": true }, { "description": "matches both", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "no dependency", "data": {"baz": 1}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/dynamicRef.json000066400000000000000000000477661477700171100306600ustar00rootroot00000000000000[ { "description": "A $dynamicRef to a $dynamicAnchor in the same schema resource behaves like a normal $ref to an $anchor", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "https://test.json-schema.org/dynamicRef-dynamicAnchor-same-schema/root", "type": "array", "items": { "$dynamicRef": "#items" }, "$defs": { "foo": { "$dynamicAnchor": "items", "type": "string" } } }, "tests": [ { "description": "An array of strings is valid", "data": ["foo", "bar"], "valid": true }, { "description": "An array containing non-strings is invalid", "data": ["foo", 42], "valid": false } ] }, { "description": "A $ref to a $dynamicAnchor in the same schema resource behaves like a normal $ref to an $anchor", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "https://test.json-schema.org/ref-dynamicAnchor-same-schema/root", "type": "array", "items": { "$ref": "#items" }, "$defs": { "foo": { "$dynamicAnchor": "items", "type": "string" } } }, "tests": [ { "description": "An array of strings is valid", "data": ["foo", "bar"], "valid": true }, { "description": "An array containing non-strings is invalid", "data": ["foo", 42], "valid": false } ] }, { "description": "A $dynamicRef resolves to the first $dynamicAnchor still in scope that is encountered when the schema is evaluated", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "https://test.json-schema.org/typical-dynamic-resolution/root", "$ref": "list", "$defs": { "foo": { "$dynamicAnchor": "items", "type": "string" }, "list": { "$id": "list", "type": "array", "items": { "$dynamicRef": "#items" } } } }, "tests": [ { "description": "An array of strings is valid", "data": ["foo", "bar"], "valid": true }, { "description": "An array containing non-strings is invalid", "data": ["foo", 42], "valid": false } ] }, { "description": "A $dynamicRef with intermediate scopes that don't include a matching $dynamicAnchor does not affect dynamic scope resolution", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "https://test.json-schema.org/dynamic-resolution-with-intermediate-scopes/root", "$ref": "intermediate-scope", "$defs": { "foo": { "$dynamicAnchor": "items", "type": "string" }, "intermediate-scope": { "$id": "intermediate-scope", "$ref": "list" }, "list": { "$id": "list", "type": "array", "items": { "$dynamicRef": "#items" } } } }, "tests": [ { "description": "An array of strings is valid", "data": ["foo", "bar"], "valid": true }, { "description": "An array containing non-strings is invalid", "data": ["foo", 42], "valid": false } ] }, { "description": "An $anchor with the same name as a $dynamicAnchor is not used for dynamic scope resolution", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "https://test.json-schema.org/dynamic-resolution-ignores-anchors/root", "$ref": "list", "$defs": { "foo": { "$anchor": "items", "type": "string" }, "list": { "$id": "list", "type": "array", "items": { "$dynamicRef": "#items" }, "$defs": { "items": { "$dynamicAnchor": "items" } } } } }, "tests": [ { "description": "Any array is valid", "data": ["foo", 42], "valid": true } ] }, { "description": "A $dynamicRef that initially resolves to a schema with a matching $dynamicAnchor resolves to the first $dynamicAnchor in the dynamic scope", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "https://test.json-schema.org/relative-dynamic-reference/root", "$dynamicAnchor": "meta", "type": "object", "properties": { "foo": { "const": "pass" } }, "$ref": "extended", "$defs": { "extended": { "$id": "extended", "$dynamicAnchor": "meta", "type": "object", "properties": { "bar": { "$ref": "bar" } } }, "bar": { "$id": "bar", "type": "object", "properties": { "baz": { "$dynamicRef": "extended#meta" } } } } }, "tests": [ { "description": "The recursive part is valid against the root", "data": { "foo": "pass", "bar": { "baz": { "foo": "pass" } } }, "valid": true }, { "description": "The recursive part is not valid against the root", "data": { "foo": "pass", "bar": { "baz": { "foo": "fail" } } }, "valid": false } ] }, { "description": "multiple dynamic paths to the $dynamicRef keyword", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "https://test.json-schema.org/dynamic-ref-with-multiple-paths/main", "propertyDependencies": { "kindOfList": { "numbers": { "$ref": "numberList" }, "strings": { "$ref": "stringList" } } }, "$defs": { "genericList": { "$id": "genericList", "properties": { "list": { "items": { "$dynamicRef": "#itemType" } } } }, "numberList": { "$id": "numberList", "$defs": { "itemType": { "$dynamicAnchor": "itemType", "type": "number" } }, "$ref": "genericList" }, "stringList": { "$id": "stringList", "$defs": { "itemType": { "$dynamicAnchor": "itemType", "type": "string" } }, "$ref": "genericList" } } }, "tests": [ { "description": "number list with number values", "data": { "kindOfList": "numbers", "list": [1.1] }, "valid": true }, { "description": "number list with string values", "data": { "kindOfList": "numbers", "list": ["foo"] }, "valid": false }, { "description": "string list with number values", "data": { "kindOfList": "strings", "list": [1.1] }, "valid": false }, { "description": "string list with string values", "data": { "kindOfList": "strings", "list": ["foo"] }, "valid": true } ] }, { "description": "after leaving a dynamic scope, it is not used by a $dynamicRef", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "https://test.json-schema.org/dynamic-ref-leaving-dynamic-scope/main", "if": { "$id": "first_scope", "$defs": { "thingy": { "$comment": "this is first_scope#thingy", "$dynamicAnchor": "thingy", "type": "number" } } }, "then": { "$id": "second_scope", "$ref": "start", "$defs": { "thingy": { "$comment": "this is second_scope#thingy, the final destination of the $dynamicRef", "$dynamicAnchor": "thingy", "type": "null" } } }, "$defs": { "start": { "$comment": "this is the landing spot from $ref", "$id": "start", "$dynamicRef": "inner_scope#thingy" }, "thingy": { "$comment": "this is the first stop for the $dynamicRef", "$id": "inner_scope", "$dynamicAnchor": "thingy", "type": "string" } } }, "tests": [ { "description": "string matches /$defs/thingy, but the $dynamicRef does not stop here", "data": "a string", "valid": false }, { "description": "first_scope is not in dynamic scope for the $dynamicRef", "data": 42, "valid": false }, { "description": "/then/$defs/thingy is the final stop for the $dynamicRef", "data": null, "valid": true } ] }, { "description": "strict-tree schema, guards against misspelled properties", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://localhost:1234/draft-next/strict-tree.json", "$dynamicAnchor": "node", "$ref": "tree.json", "unevaluatedProperties": false }, "tests": [ { "description": "instance with misspelled field", "data": { "children": [{ "daat": 1 }] }, "valid": false }, { "description": "instance with correct field", "data": { "children": [{ "data": 1 }] }, "valid": true } ] }, { "description": "tests for implementation dynamic anchor and reference link", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://localhost:1234/draft-next/strict-extendible.json", "$ref": "extendible-dynamic-ref.json", "$defs": { "elements": { "$dynamicAnchor": "elements", "properties": { "a": true }, "required": ["a"], "additionalProperties": false } } }, "tests": [ { "description": "incorrect parent schema", "data": { "a": true }, "valid": false }, { "description": "incorrect extended schema", "data": { "elements": [ { "b": 1 } ] }, "valid": false }, { "description": "correct extended schema", "data": { "elements": [ { "a": 1 } ] }, "valid": true } ] }, { "description": "$ref and $dynamicAnchor are independent of order - $defs first", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://localhost:1234/draft-next/strict-extendible-allof-defs-first.json", "allOf": [ { "$ref": "extendible-dynamic-ref.json" }, { "$defs": { "elements": { "$dynamicAnchor": "elements", "properties": { "a": true }, "required": ["a"], "additionalProperties": false } } } ] }, "tests": [ { "description": "incorrect parent schema", "data": { "a": true }, "valid": false }, { "description": "incorrect extended schema", "data": { "elements": [ { "b": 1 } ] }, "valid": false }, { "description": "correct extended schema", "data": { "elements": [ { "a": 1 } ] }, "valid": true } ] }, { "description": "$ref and $dynamicAnchor are independent of order - $ref first", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://localhost:1234/draft-next/strict-extendible-allof-ref-first.json", "allOf": [ { "$defs": { "elements": { "$dynamicAnchor": "elements", "properties": { "a": true }, "required": ["a"], "additionalProperties": false } } }, { "$ref": "extendible-dynamic-ref.json" } ] }, "tests": [ { "description": "incorrect parent schema", "data": { "a": true }, "valid": false }, { "description": "incorrect extended schema", "data": { "elements": [ { "b": 1 } ] }, "valid": false }, { "description": "correct extended schema", "data": { "elements": [ { "a": 1 } ] }, "valid": true } ] }, { "description": "$dynamicAnchor inside propertyDependencies", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://localhost:1234/draft-next/dynamicanchor-in-propertydependencies.json", "$defs": { "inner": { "$id": "inner", "$dynamicAnchor": "foo", "type": "object", "properties": { "expectedTypes": { "type": "string" } }, "additionalProperties": { "$dynamicRef": "#foo" } } }, "propertyDependencies": { "expectedTypes": { "strings": { "$id": "east", "$ref": "inner", "$defs": { "foo": { "$dynamicAnchor": "foo", "type": "string" } } }, "integers": { "$id": "west", "$ref": "inner", "$defs": { "foo": { "$dynamicAnchor": "foo", "type": "integer" } } } } } }, "tests": [ { "description": "expected strings - additional property as string is valid", "data": { "expectedTypes": "strings", "anotherProperty": "also a string" }, "valid": true }, { "description": "expected strings - additional property as not string is invalid", "data": { "expectedTypes": "strings", "anotherProperty": 42 }, "valid": false }, { "description": "expected integers - additional property as integer is valid", "data": { "expectedTypes": "integers", "anotherProperty": 42 }, "valid": true }, { "description": "expected integers - additional property as not integer is invalid", "data": { "expectedTypes": "integers", "anotherProperty": "a string" }, "valid": false } ] }, { "description": "$ref to $dynamicRef finds detached $dynamicAnchor", "schema": { "$ref": "http://localhost:1234/draft-next/detached-dynamicref.json#/$defs/foo" }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/enum.json000066400000000000000000000163671477700171100275340ustar00rootroot00000000000000[ { "description": "simple enum validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "enum": [1, 2, 3] }, "tests": [ { "description": "one of the enum is valid", "data": 1, "valid": true }, { "description": "something else is invalid", "data": 4, "valid": false } ] }, { "description": "heterogeneous enum validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "enum": [6, "foo", [], true, {"foo": 12}] }, "tests": [ { "description": "one of the enum is valid", "data": [], "valid": true }, { "description": "something else is invalid", "data": null, "valid": false }, { "description": "objects are deep compared", "data": {"foo": false}, "valid": false }, { "description": "valid object matches", "data": {"foo": 12}, "valid": true }, { "description": "extra properties in object is invalid", "data": {"foo": 12, "boo": 42}, "valid": false } ] }, { "description": "heterogeneous enum-with-null validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "enum": [6, null] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "number is valid", "data": 6, "valid": true }, { "description": "something else is invalid", "data": "test", "valid": false } ] }, { "description": "enums in properties", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type":"object", "properties": { "foo": {"enum":["foo"]}, "bar": {"enum":["bar"]} }, "required": ["bar"] }, "tests": [ { "description": "both properties are valid", "data": {"foo":"foo", "bar":"bar"}, "valid": true }, { "description": "wrong foo value", "data": {"foo":"foot", "bar":"bar"}, "valid": false }, { "description": "wrong bar value", "data": {"foo":"foo", "bar":"bart"}, "valid": false }, { "description": "missing optional property is valid", "data": {"bar":"bar"}, "valid": true }, { "description": "missing required property is invalid", "data": {"foo":"foo"}, "valid": false }, { "description": "missing all properties is invalid", "data": {}, "valid": false } ] }, { "description": "enum with escaped characters", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "enum": ["foo\nbar", "foo\rbar"] }, "tests": [ { "description": "member 1 is valid", "data": "foo\nbar", "valid": true }, { "description": "member 2 is valid", "data": "foo\rbar", "valid": true }, { "description": "another string is invalid", "data": "abc", "valid": false } ] }, { "description": "enum with false does not match 0", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "enum": [false] }, "tests": [ { "description": "false is valid", "data": false, "valid": true }, { "description": "integer zero is invalid", "data": 0, "valid": false }, { "description": "float zero is invalid", "data": 0.0, "valid": false } ] }, { "description": "enum with true does not match 1", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "enum": [true] }, "tests": [ { "description": "true is valid", "data": true, "valid": true }, { "description": "integer one is invalid", "data": 1, "valid": false }, { "description": "float one is invalid", "data": 1.0, "valid": false } ] }, { "description": "enum with 0 does not match false", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "enum": [0] }, "tests": [ { "description": "false is invalid", "data": false, "valid": false }, { "description": "integer zero is valid", "data": 0, "valid": true }, { "description": "float zero is valid", "data": 0.0, "valid": true } ] }, { "description": "enum with 1 does not match true", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "enum": [1] }, "tests": [ { "description": "true is invalid", "data": true, "valid": false }, { "description": "integer one is valid", "data": 1, "valid": true }, { "description": "float one is valid", "data": 1.0, "valid": true } ] }, { "description": "nul characters in strings", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "enum": [ "hello\u0000there" ] }, "tests": [ { "description": "match string with nul", "data": "hello\u0000there", "valid": true }, { "description": "do not match string lacking nul", "data": "hellothere", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/exclusiveMaximum.json000066400000000000000000000015131477700171100321200ustar00rootroot00000000000000[ { "description": "exclusiveMaximum validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "exclusiveMaximum": 3.0 }, "tests": [ { "description": "below the exclusiveMaximum is valid", "data": 2.2, "valid": true }, { "description": "boundary point is invalid", "data": 3.0, "valid": false }, { "description": "above the exclusiveMaximum is invalid", "data": 3.5, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/exclusiveMinimum.json000066400000000000000000000015131477700171100321160ustar00rootroot00000000000000[ { "description": "exclusiveMinimum validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "exclusiveMinimum": 1.1 }, "tests": [ { "description": "above the exclusiveMinimum is valid", "data": 1.2, "valid": true }, { "description": "boundary point is invalid", "data": 1.1, "valid": false }, { "description": "below the exclusiveMinimum is invalid", "data": 0.6, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/format.json000066400000000000000000000617631477700171100300600ustar00rootroot00000000000000[ { "description": "email format", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "email" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid email string is only an annotation by default", "data": "2962", "valid": true } ] }, { "description": "idn-email format", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "idn-email" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid idn-email string is only an annotation by default", "data": "2962", "valid": true } ] }, { "description": "regex format", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "regex" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid regex string is only an annotation by default", "data": "^(abc]", "valid": true } ] }, { "description": "ipv4 format", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "ipv4" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid ipv4 string is only an annotation by default", "data": "127.0.0.0.1", "valid": true } ] }, { "description": "ipv6 format", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "ipv6" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid ipv6 string is only an annotation by default", "data": "12345::", "valid": true } ] }, { "description": "idn-hostname format", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "idn-hostname" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid idn-hostname string is only an annotation by default", "data": "〮실례.테스트", "valid": true } ] }, { "description": "hostname format", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "hostname" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid hostname string is only an annotation by default", "data": "-a-host-name-that-starts-with--", "valid": true } ] }, { "description": "date format", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "date" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid date string is only an annotation by default", "data": "06/19/1963", "valid": true } ] }, { "description": "date-time format", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "date-time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid date-time string is only an annotation by default", "data": "1990-02-31T15:59:60.123-08:00", "valid": true } ] }, { "description": "time format", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid time string is only an annotation by default", "data": "08:30:06 PST", "valid": true } ] }, { "description": "json-pointer format", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "json-pointer" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid json-pointer string is only an annotation by default", "data": "/foo/bar~", "valid": true } ] }, { "description": "relative-json-pointer format", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "relative-json-pointer" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid relative-json-pointer string is only an annotation by default", "data": "/foo/bar", "valid": true } ] }, { "description": "iri format", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "iri" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid iri string is only an annotation by default", "data": "http://2001:0db8:85a3:0000:0000:8a2e:0370:7334", "valid": true } ] }, { "description": "iri-reference format", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "iri-reference" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid iri-reference string is only an annotation by default", "data": "\\\\WINDOWS\\filëßåré", "valid": true } ] }, { "description": "uri format", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "uri" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid uri string is only an annotation by default", "data": "//foo.bar/?baz=qux#quux", "valid": true } ] }, { "description": "uri-reference format", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "uri-reference" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid uri-reference string is only an annotation by default", "data": "\\\\WINDOWS\\fileshare", "valid": true } ] }, { "description": "uri-template format", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "uri-template" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid uri-template string is only an annotation by default", "data": "http://example.com/dictionary/{term:1}/{term", "valid": true } ] }, { "description": "uuid format", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "uuid" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid uuid string is only an annotation by default", "data": "2eb8aa08-aa98-11ea-b4aa-73b441d1638", "valid": true } ] }, { "description": "duration format", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "duration" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid duration string is only an annotation by default", "data": "PT1D", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/id.json000066400000000000000000000237601477700171100271570ustar00rootroot00000000000000[ { "description": "Invalid use of fragments in location-independent $id", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "https://json-schema.org/draft/next/schema" }, "tests": [ { "description": "Identifier name", "data": { "$ref": "#foo", "$defs": { "A": { "$id": "#foo", "type": "integer" } } }, "valid": false }, { "description": "Identifier name and no ref", "data": { "$defs": { "A": { "$id": "#foo" } } }, "valid": false }, { "description": "Identifier path", "data": { "$ref": "#/a/b", "$defs": { "A": { "$id": "#/a/b", "type": "integer" } } }, "valid": false }, { "description": "Identifier name with absolute URI", "data": { "$ref": "http://localhost:1234/draft-next/bar#foo", "$defs": { "A": { "$id": "http://localhost:1234/draft-next/bar#foo", "type": "integer" } } }, "valid": false }, { "description": "Identifier path with absolute URI", "data": { "$ref": "http://localhost:1234/draft-next/bar#/a/b", "$defs": { "A": { "$id": "http://localhost:1234/draft-next/bar#/a/b", "type": "integer" } } }, "valid": false }, { "description": "Identifier name with base URI change in subschema", "data": { "$id": "http://localhost:1234/draft-next/root", "$ref": "http://localhost:1234/draft-next/nested.json#foo", "$defs": { "A": { "$id": "nested.json", "$defs": { "B": { "$id": "#foo", "type": "integer" } } } } }, "valid": false }, { "description": "Identifier path with base URI change in subschema", "data": { "$id": "http://localhost:1234/draft-next/root", "$ref": "http://localhost:1234/draft-next/nested.json#/a/b", "$defs": { "A": { "$id": "nested.json", "$defs": { "B": { "$id": "#/a/b", "type": "integer" } } } } }, "valid": false } ] }, { "description": "Valid use of empty fragments in location-independent $id", "comment": "These are allowed but discouraged", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "https://json-schema.org/draft/next/schema" }, "tests": [ { "description": "Identifier name with absolute URI", "data": { "$ref": "http://localhost:1234/draft-next/bar", "$defs": { "A": { "$id": "http://localhost:1234/draft-next/bar#", "type": "integer" } } }, "valid": true }, { "description": "Identifier name with base URI change in subschema", "data": { "$id": "http://localhost:1234/draft-next/root", "$ref": "http://localhost:1234/draft-next/nested.json#/$defs/B", "$defs": { "A": { "$id": "nested.json", "$defs": { "B": { "$id": "#", "type": "integer" } } } } }, "valid": true } ] }, { "description": "Unnormalized $ids are allowed but discouraged", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "https://json-schema.org/draft/next/schema" }, "tests": [ { "description": "Unnormalized identifier", "data": { "$ref": "http://localhost:1234/draft-next/foo/baz", "$defs": { "A": { "$id": "http://localhost:1234/draft-next/foo/bar/../baz", "type": "integer" } } }, "valid": true }, { "description": "Unnormalized identifier and no ref", "data": { "$defs": { "A": { "$id": "http://localhost:1234/draft-next/foo/bar/../baz", "type": "integer" } } }, "valid": true }, { "description": "Unnormalized identifier with empty fragment", "data": { "$ref": "http://localhost:1234/draft-next/foo/baz", "$defs": { "A": { "$id": "http://localhost:1234/draft-next/foo/bar/../baz#", "type": "integer" } } }, "valid": true }, { "description": "Unnormalized identifier with empty fragment and no ref", "data": { "$defs": { "A": { "$id": "http://localhost:1234/draft-next/foo/bar/../baz#", "type": "integer" } } }, "valid": true } ] }, { "description": "$id inside an enum is not a real identifier", "comment": "the implementation must not be confused by an $id buried in the enum", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "id_in_enum": { "enum": [ { "$id": "https://localhost:1234/draft-next/id/my_identifier.json", "type": "null" } ] }, "real_id_in_schema": { "$id": "https://localhost:1234/draft-next/id/my_identifier.json", "type": "string" }, "zzz_id_in_const": { "const": { "$id": "https://localhost:1234/draft-next/id/my_identifier.json", "type": "null" } } }, "anyOf": [ { "$ref": "#/$defs/id_in_enum" }, { "$ref": "https://localhost:1234/draft-next/id/my_identifier.json" } ] }, "tests": [ { "description": "exact match to enum, and type matches", "data": { "$id": "https://localhost:1234/draft-next/id/my_identifier.json", "type": "null" }, "valid": true }, { "description": "match $ref to $id", "data": "a string to match #/$defs/id_in_enum", "valid": true }, { "description": "no match on enum or $ref to $id", "data": 1, "valid": false } ] }, { "description": "non-schema object containing an $id property", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "const_not_id": { "const": { "$id": "not_a_real_id" } } }, "if": { "const": "skip not_a_real_id" }, "then": true, "else" : { "$ref": "#/$defs/const_not_id" } }, "tests": [ { "description": "skip traversing definition for a valid result", "data": "skip not_a_real_id", "valid": true }, { "description": "const at const_not_id does not match", "data": 1, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/if-then-else.json000066400000000000000000000165721477700171100310460ustar00rootroot00000000000000[ { "description": "ignore if without then or else", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "if": { "const": 0 } }, "tests": [ { "description": "valid when valid against lone if", "data": 0, "valid": true }, { "description": "valid when invalid against lone if", "data": "hello", "valid": true } ] }, { "description": "ignore then without if", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "then": { "const": 0 } }, "tests": [ { "description": "valid when valid against lone then", "data": 0, "valid": true }, { "description": "valid when invalid against lone then", "data": "hello", "valid": true } ] }, { "description": "ignore else without if", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "else": { "const": 0 } }, "tests": [ { "description": "valid when valid against lone else", "data": 0, "valid": true }, { "description": "valid when invalid against lone else", "data": "hello", "valid": true } ] }, { "description": "if and then without else", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "if": { "exclusiveMaximum": 0 }, "then": { "minimum": -10 } }, "tests": [ { "description": "valid through then", "data": -1, "valid": true }, { "description": "invalid through then", "data": -100, "valid": false }, { "description": "valid when if test fails", "data": 3, "valid": true } ] }, { "description": "if and else without then", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "if": { "exclusiveMaximum": 0 }, "else": { "multipleOf": 2 } }, "tests": [ { "description": "valid when if test passes", "data": -1, "valid": true }, { "description": "valid through else", "data": 4, "valid": true }, { "description": "invalid through else", "data": 3, "valid": false } ] }, { "description": "validate against correct branch, then vs else", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "if": { "exclusiveMaximum": 0 }, "then": { "minimum": -10 }, "else": { "multipleOf": 2 } }, "tests": [ { "description": "valid through then", "data": -1, "valid": true }, { "description": "invalid through then", "data": -100, "valid": false }, { "description": "valid through else", "data": 4, "valid": true }, { "description": "invalid through else", "data": 3, "valid": false } ] }, { "description": "non-interference across combined schemas", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "allOf": [ { "if": { "exclusiveMaximum": 0 } }, { "then": { "minimum": -10 } }, { "else": { "multipleOf": 2 } } ] }, "tests": [ { "description": "valid, but would have been invalid through then", "data": -100, "valid": true }, { "description": "valid, but would have been invalid through else", "data": 3, "valid": true } ] }, { "description": "if with boolean schema true", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "if": true, "then": { "const": "then" }, "else": { "const": "else" } }, "tests": [ { "description": "boolean schema true in if always chooses the then path (valid)", "data": "then", "valid": true }, { "description": "boolean schema true in if always chooses the then path (invalid)", "data": "else", "valid": false } ] }, { "description": "if with boolean schema false", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "if": false, "then": { "const": "then" }, "else": { "const": "else" } }, "tests": [ { "description": "boolean schema false in if always chooses the else path (invalid)", "data": "then", "valid": false }, { "description": "boolean schema false in if always chooses the else path (valid)", "data": "else", "valid": true } ] }, { "description": "if appears at the end when serialized (keyword processing sequence)", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "then": { "const": "yes" }, "else": { "const": "other" }, "if": { "maxLength": 4 } }, "tests": [ { "description": "yes redirects to then and passes", "data": "yes", "valid": true }, { "description": "other redirects to else and passes", "data": "other", "valid": true }, { "description": "no redirects to then and fails", "data": "no", "valid": false }, { "description": "invalid redirects to else and fails", "data": "invalid", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/infinite-loop-detection.json000066400000000000000000000020301477700171100332760ustar00rootroot00000000000000[ { "description": "evaluating the same schema location against the same data location twice is not a sign of an infinite loop", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "int": { "type": "integer" } }, "allOf": [ { "properties": { "foo": { "$ref": "#/$defs/int" } } }, { "additionalProperties": { "$ref": "#/$defs/int" } } ] }, "tests": [ { "description": "passing case", "data": { "foo": 1 }, "valid": true }, { "description": "failing case", "data": { "foo": "a string" }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/items.json000066400000000000000000000217331477700171100277020ustar00rootroot00000000000000[ { "description": "a schema given for items", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "items": {"type": "integer"} }, "tests": [ { "description": "valid items", "data": [ 1, 2, 3 ], "valid": true }, { "description": "wrong type of items", "data": [1, "x"], "valid": false }, { "description": "ignores non-arrays", "data": {"foo" : "bar"}, "valid": true }, { "description": "JavaScript pseudo-array is valid", "data": { "0": "invalid", "length": 1 }, "valid": true } ] }, { "description": "items with boolean schema (true)", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "items": true }, "tests": [ { "description": "any array is valid", "data": [ 1, "foo", true ], "valid": true }, { "description": "empty array is valid", "data": [], "valid": true } ] }, { "description": "items with boolean schema (false)", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "items": false }, "tests": [ { "description": "any non-empty array is invalid", "data": [ 1, "foo", true ], "valid": false }, { "description": "empty array is valid", "data": [], "valid": true } ] }, { "description": "items and subitems", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "item": { "type": "array", "items": false, "prefixItems": [ { "$ref": "#/$defs/sub-item" }, { "$ref": "#/$defs/sub-item" } ] }, "sub-item": { "type": "object", "required": ["foo"] } }, "type": "array", "items": false, "prefixItems": [ { "$ref": "#/$defs/item" }, { "$ref": "#/$defs/item" }, { "$ref": "#/$defs/item" } ] }, "tests": [ { "description": "valid items", "data": [ [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": true }, { "description": "too many items", "data": [ [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "too many sub-items", "data": [ [ {"foo": null}, {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "wrong item", "data": [ {"foo": null}, [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "wrong sub-item", "data": [ [ {}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "fewer items is valid", "data": [ [ {"foo": null} ], [ {"foo": null} ] ], "valid": true } ] }, { "description": "nested items", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "array", "items": { "type": "array", "items": { "type": "array", "items": { "type": "array", "items": { "type": "number" } } } } }, "tests": [ { "description": "valid nested array", "data": [[[[1]], [[2],[3]]], [[[4], [5], [6]]]], "valid": true }, { "description": "nested array with invalid type", "data": [[[["1"]], [[2],[3]]], [[[4], [5], [6]]]], "valid": false }, { "description": "not deep enough", "data": [[[1], [2],[3]], [[4], [5], [6]]], "valid": false } ] }, { "description": "prefixItems with no additional items allowed", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "prefixItems": [{}, {}, {}], "items": false }, "tests": [ { "description": "empty array", "data": [ ], "valid": true }, { "description": "fewer number of items present (1)", "data": [ 1 ], "valid": true }, { "description": "fewer number of items present (2)", "data": [ 1, 2 ], "valid": true }, { "description": "equal number of items present", "data": [ 1, 2, 3 ], "valid": true }, { "description": "additional items are not permitted", "data": [ 1, 2, 3, 4 ], "valid": false } ] }, { "description": "items does not look in applicators, valid case", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "allOf": [ { "prefixItems": [ { "minimum": 3 } ] } ], "items": { "minimum": 5 } }, "tests": [ { "description": "prefixItems in allOf does not constrain items, invalid case", "data": [ 3, 5 ], "valid": false }, { "description": "prefixItems in allOf does not constrain items, valid case", "data": [ 5, 5 ], "valid": true } ] }, { "description": "prefixItems validation adjusts the starting index for items", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "prefixItems": [ { "type": "string" } ], "items": { "type": "integer" } }, "tests": [ { "description": "valid items", "data": [ "x", 2, 3 ], "valid": true }, { "description": "wrong type of second item", "data": [ "x", "y" ], "valid": false } ] }, { "description": "items with heterogeneous array", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "prefixItems": [{}], "items": false }, "tests": [ { "description": "heterogeneous invalid instance", "data": [ "foo", "bar", 37 ], "valid": false }, { "description": "valid instance", "data": [ null ], "valid": true } ] }, { "description": "items with null instance elements", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "items": { "type": "null" } }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/maxContains.json000066400000000000000000000057561477700171100310540ustar00rootroot00000000000000[ { "description": "maxContains without contains is ignored", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "maxContains": 1 }, "tests": [ { "description": "one item valid against lone maxContains", "data": [1], "valid": true }, { "description": "two items still valid against lone maxContains", "data": [1, 2], "valid": true } ] }, { "description": "maxContains with contains", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "contains": { "const": 1 }, "maxContains": 1 }, "tests": [ { "description": "empty array", "data": [], "valid": false }, { "description": "all elements match, valid maxContains", "data": [1], "valid": true }, { "description": "all elements match, invalid maxContains", "data": [1, 1], "valid": false }, { "description": "some elements match, valid maxContains", "data": [1, 2], "valid": true }, { "description": "some elements match, invalid maxContains", "data": [1, 2, 1], "valid": false } ] }, { "description": "maxContains with contains, value with a decimal", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "contains": {"const": 1}, "maxContains": 1.0 }, "tests": [ { "description": "one element matches, valid maxContains", "data": [ 1 ], "valid": true }, { "description": "too many elements match, invalid maxContains", "data": [ 1, 1 ], "valid": false } ] }, { "description": "minContains < maxContains", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "contains": { "const": 1 }, "minContains": 1, "maxContains": 3 }, "tests": [ { "description": "array with actual < minContains < maxContains", "data": [], "valid": false }, { "description": "array with minContains < actual < maxContains", "data": [1, 1], "valid": true }, { "description": "array with minContains < maxContains < actual", "data": [1, 1, 1, 1], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/maxItems.json000066400000000000000000000024411477700171100303430ustar00rootroot00000000000000[ { "description": "maxItems validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "maxItems": 2 }, "tests": [ { "description": "shorter is valid", "data": [1], "valid": true }, { "description": "exact length is valid", "data": [1, 2], "valid": true }, { "description": "too long is invalid", "data": [1, 2, 3], "valid": false }, { "description": "ignores non-arrays", "data": "foobar", "valid": true } ] }, { "description": "maxItems validation with a decimal", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "maxItems": 2.0 }, "tests": [ { "description": "shorter is valid", "data": [1], "valid": true }, { "description": "too long is invalid", "data": [1, 2, 3], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/maxLength.json000066400000000000000000000027351477700171100305110ustar00rootroot00000000000000[ { "description": "maxLength validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "maxLength": 2 }, "tests": [ { "description": "shorter is valid", "data": "f", "valid": true }, { "description": "exact length is valid", "data": "fo", "valid": true }, { "description": "too long is invalid", "data": "foo", "valid": false }, { "description": "ignores non-strings", "data": 100, "valid": true }, { "description": "two supplementary Unicode code points is long enough", "data": "\uD83D\uDCA9\uD83D\uDCA9", "valid": true } ] }, { "description": "maxLength validation with a decimal", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "maxLength": 2.0 }, "tests": [ { "description": "shorter is valid", "data": "f", "valid": true }, { "description": "too long is invalid", "data": "foo", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/maxProperties.json000066400000000000000000000042671477700171100314260ustar00rootroot00000000000000[ { "description": "maxProperties validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "maxProperties": 2 }, "tests": [ { "description": "shorter is valid", "data": {"foo": 1}, "valid": true }, { "description": "exact length is valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "too long is invalid", "data": {"foo": 1, "bar": 2, "baz": 3}, "valid": false }, { "description": "ignores arrays", "data": [1, 2, 3], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "maxProperties validation with a decimal", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "maxProperties": 2.0 }, "tests": [ { "description": "shorter is valid", "data": {"foo": 1}, "valid": true }, { "description": "too long is invalid", "data": {"foo": 1, "bar": 2, "baz": 3}, "valid": false } ] }, { "description": "maxProperties = 0 means the object is empty", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "maxProperties": 0 }, "tests": [ { "description": "no properties is valid", "data": {}, "valid": true }, { "description": "one property is invalid", "data": { "foo": 1 }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/maximum.json000066400000000000000000000031701477700171100302310ustar00rootroot00000000000000[ { "description": "maximum validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "maximum": 3.0 }, "tests": [ { "description": "below the maximum is valid", "data": 2.6, "valid": true }, { "description": "boundary point is valid", "data": 3.0, "valid": true }, { "description": "above the maximum is invalid", "data": 3.5, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] }, { "description": "maximum validation with unsigned integer", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "maximum": 300 }, "tests": [ { "description": "below the maximum is invalid", "data": 299.97, "valid": true }, { "description": "boundary point integer is valid", "data": 300, "valid": true }, { "description": "boundary point float is valid", "data": 300.00, "valid": true }, { "description": "above the maximum is invalid", "data": 300.5, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/minContains.json000066400000000000000000000146271477700171100310470ustar00rootroot00000000000000[ { "description": "minContains without contains is ignored", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "minContains": 1 }, "tests": [ { "description": "one item valid against lone minContains", "data": [1], "valid": true }, { "description": "zero items still valid against lone minContains", "data": [], "valid": true } ] }, { "description": "minContains=1 with contains", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "contains": { "const": 1 }, "minContains": 1 }, "tests": [ { "description": "empty data", "data": [], "valid": false }, { "description": "no elements match", "data": [2], "valid": false }, { "description": "single element matches, valid minContains", "data": [1], "valid": true }, { "description": "some elements match, valid minContains", "data": [1, 2], "valid": true }, { "description": "all elements match, valid minContains", "data": [1, 1], "valid": true } ] }, { "description": "minContains=2 with contains", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "contains": { "const": 1 }, "minContains": 2 }, "tests": [ { "description": "empty data", "data": [], "valid": false }, { "description": "all elements match, invalid minContains", "data": [1], "valid": false }, { "description": "some elements match, invalid minContains", "data": [1, 2], "valid": false }, { "description": "all elements match, valid minContains (exactly as needed)", "data": [1, 1], "valid": true }, { "description": "all elements match, valid minContains (more than needed)", "data": [1, 1, 1], "valid": true }, { "description": "some elements match, valid minContains", "data": [1, 2, 1], "valid": true } ] }, { "description": "minContains=2 with contains with a decimal value", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "contains": {"const": 1}, "minContains": 2.0 }, "tests": [ { "description": "one element matches, invalid minContains", "data": [ 1 ], "valid": false }, { "description": "both elements match, valid minContains", "data": [ 1, 1 ], "valid": true } ] }, { "description": "maxContains = minContains", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "contains": { "const": 1 }, "maxContains": 2, "minContains": 2 }, "tests": [ { "description": "empty data", "data": [], "valid": false }, { "description": "all elements match, invalid minContains", "data": [1], "valid": false }, { "description": "all elements match, invalid maxContains", "data": [1, 1, 1], "valid": false }, { "description": "all elements match, valid maxContains and minContains", "data": [1, 1], "valid": true } ] }, { "description": "maxContains < minContains", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "contains": { "const": 1 }, "maxContains": 1, "minContains": 3 }, "tests": [ { "description": "empty data", "data": [], "valid": false }, { "description": "invalid minContains", "data": [1], "valid": false }, { "description": "invalid maxContains", "data": [1, 1, 1], "valid": false }, { "description": "invalid maxContains and minContains", "data": [1, 1], "valid": false } ] }, { "description": "minContains = 0", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "contains": { "const": 1 }, "minContains": 0 }, "tests": [ { "description": "empty data", "data": [], "valid": true }, { "description": "minContains = 0 makes contains always pass", "data": [2], "valid": true } ] }, { "description": "minContains = 0 with maxContains", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "contains": {"const": 1}, "minContains": 0, "maxContains": 1 }, "tests": [ { "description": "empty data", "data": [ ], "valid": true }, { "description": "not more than maxContains", "data": [ 1 ], "valid": true }, { "description": "too many", "data": [ 1, 1 ], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/minItems.json000066400000000000000000000024201477700171100303360ustar00rootroot00000000000000[ { "description": "minItems validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "minItems": 1 }, "tests": [ { "description": "longer is valid", "data": [1, 2], "valid": true }, { "description": "exact length is valid", "data": [1], "valid": true }, { "description": "too short is invalid", "data": [], "valid": false }, { "description": "ignores non-arrays", "data": "", "valid": true } ] }, { "description": "minItems validation with a decimal", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "minItems": 1.0 }, "tests": [ { "description": "longer is valid", "data": [1, 2], "valid": true }, { "description": "too short is invalid", "data": [], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/minLength.json000066400000000000000000000027231477700171100305040ustar00rootroot00000000000000[ { "description": "minLength validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "minLength": 2 }, "tests": [ { "description": "longer is valid", "data": "foo", "valid": true }, { "description": "exact length is valid", "data": "fo", "valid": true }, { "description": "too short is invalid", "data": "f", "valid": false }, { "description": "ignores non-strings", "data": 1, "valid": true }, { "description": "one supplementary Unicode code point is not long enough", "data": "\uD83D\uDCA9", "valid": false } ] }, { "description": "minLength validation with a decimal", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "minLength": 2.0 }, "tests": [ { "description": "longer is valid", "data": "foo", "valid": true }, { "description": "too short is invalid", "data": "f", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/minProperties.json000066400000000000000000000031371477700171100314170ustar00rootroot00000000000000[ { "description": "minProperties validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "minProperties": 1 }, "tests": [ { "description": "longer is valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "exact length is valid", "data": {"foo": 1}, "valid": true }, { "description": "too short is invalid", "data": {}, "valid": false }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores strings", "data": "", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "minProperties validation with a decimal", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "minProperties": 1.0 }, "tests": [ { "description": "longer is valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "too short is invalid", "data": {}, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/minimum.json000066400000000000000000000040761477700171100302350ustar00rootroot00000000000000[ { "description": "minimum validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "minimum": 1.1 }, "tests": [ { "description": "above the minimum is valid", "data": 2.6, "valid": true }, { "description": "boundary point is valid", "data": 1.1, "valid": true }, { "description": "below the minimum is invalid", "data": 0.6, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] }, { "description": "minimum validation with signed integer", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "minimum": -2 }, "tests": [ { "description": "negative above the minimum is valid", "data": -1, "valid": true }, { "description": "positive above the minimum is valid", "data": 0, "valid": true }, { "description": "boundary point is valid", "data": -2, "valid": true }, { "description": "boundary point with float is valid", "data": -2.0, "valid": true }, { "description": "float below the minimum is invalid", "data": -2.0001, "valid": false }, { "description": "int below the minimum is invalid", "data": -3, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/multipleOf.json000066400000000000000000000051421477700171100306750ustar00rootroot00000000000000[ { "description": "by int", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "multipleOf": 2 }, "tests": [ { "description": "int by int", "data": 10, "valid": true }, { "description": "int by int fail", "data": 7, "valid": false }, { "description": "ignores non-numbers", "data": "foo", "valid": true } ] }, { "description": "by number", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "multipleOf": 1.5 }, "tests": [ { "description": "zero is multiple of anything", "data": 0, "valid": true }, { "description": "4.5 is multiple of 1.5", "data": 4.5, "valid": true }, { "description": "35 is not multiple of 1.5", "data": 35, "valid": false } ] }, { "description": "by small number", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "multipleOf": 0.0001 }, "tests": [ { "description": "0.0075 is multiple of 0.0001", "data": 0.0075, "valid": true }, { "description": "0.00751 is not multiple of 0.0001", "data": 0.00751, "valid": false } ] }, { "description": "float division = inf", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "integer", "multipleOf": 0.123456789 }, "tests": [ { "description": "always invalid, but naive implementations may raise an overflow error", "data": 1e308, "valid": false } ] }, { "description": "small multiple of large integer", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "integer", "multipleOf": 1e-8 }, "tests": [ { "description": "any integer is a multiple of 1e-8", "data": 12391239123, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/not.json000066400000000000000000000101231477700171100273500ustar00rootroot00000000000000[ { "description": "not", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "not": {"type": "integer"} }, "tests": [ { "description": "allowed", "data": "foo", "valid": true }, { "description": "disallowed", "data": 1, "valid": false } ] }, { "description": "not multiple types", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "not": {"type": ["integer", "boolean"]} }, "tests": [ { "description": "valid", "data": "foo", "valid": true }, { "description": "mismatch", "data": 1, "valid": false }, { "description": "other mismatch", "data": true, "valid": false } ] }, { "description": "not more complex schema", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "not": { "type": "object", "properties": { "foo": { "type": "string" } } } }, "tests": [ { "description": "match", "data": 1, "valid": true }, { "description": "other match", "data": {"foo": 1}, "valid": true }, { "description": "mismatch", "data": {"foo": "bar"}, "valid": false } ] }, { "description": "forbidden property", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": { "foo": { "not": {} } } }, "tests": [ { "description": "property present", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "property absent", "data": {"bar": 1, "baz": 2}, "valid": true } ] }, { "description": "not with boolean schema true", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "not": true }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "not with boolean schema false", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "not": false }, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "collect annotations inside a 'not', even if collection is disabled", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "not": { "$comment": "this subschema must still produce annotations internally, even though the 'not' will ultimately discard them", "anyOf": [ true, { "properties": { "foo": true } } ], "unevaluatedProperties": false } }, "tests": [ { "description": "unevaluated property", "data": { "bar": 1 }, "valid": true }, { "description": "annotations are still collected inside a 'not'", "data": { "foo": 1 }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/oneOf.json000066400000000000000000000176271477700171100276360ustar00rootroot00000000000000[ { "description": "oneOf", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "oneOf": [ { "type": "integer" }, { "minimum": 2 } ] }, "tests": [ { "description": "first oneOf valid", "data": 1, "valid": true }, { "description": "second oneOf valid", "data": 2.5, "valid": true }, { "description": "both oneOf valid", "data": 3, "valid": false }, { "description": "neither oneOf valid", "data": 1.5, "valid": false } ] }, { "description": "oneOf with base schema", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "string", "oneOf" : [ { "minLength": 2 }, { "maxLength": 4 } ] }, "tests": [ { "description": "mismatch base schema", "data": 3, "valid": false }, { "description": "one oneOf valid", "data": "foobar", "valid": true }, { "description": "both oneOf valid", "data": "foo", "valid": false } ] }, { "description": "oneOf with boolean schemas, all true", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "oneOf": [true, true, true] }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "oneOf with boolean schemas, one true", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "oneOf": [true, false, false] }, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "oneOf with boolean schemas, more than one true", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "oneOf": [true, true, false] }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "oneOf with boolean schemas, all false", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "oneOf": [false, false, false] }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "oneOf complex types", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "oneOf": [ { "properties": { "bar": {"type": "integer"} }, "required": ["bar"] }, { "properties": { "foo": {"type": "string"} }, "required": ["foo"] } ] }, "tests": [ { "description": "first oneOf valid (complex)", "data": {"bar": 2}, "valid": true }, { "description": "second oneOf valid (complex)", "data": {"foo": "baz"}, "valid": true }, { "description": "both oneOf valid (complex)", "data": {"foo": "baz", "bar": 2}, "valid": false }, { "description": "neither oneOf valid (complex)", "data": {"foo": 2, "bar": "quux"}, "valid": false } ] }, { "description": "oneOf with empty schema", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "oneOf": [ { "type": "number" }, {} ] }, "tests": [ { "description": "one valid - valid", "data": "foo", "valid": true }, { "description": "both valid - invalid", "data": 123, "valid": false } ] }, { "description": "oneOf with required", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "oneOf": [ { "required": ["foo", "bar"] }, { "required": ["foo", "baz"] } ] }, "tests": [ { "description": "both invalid - invalid", "data": {"bar": 2}, "valid": false }, { "description": "first valid - valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "second valid - valid", "data": {"foo": 1, "baz": 3}, "valid": true }, { "description": "both valid - invalid", "data": {"foo": 1, "bar": 2, "baz" : 3}, "valid": false } ] }, { "description": "oneOf with missing optional property", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "oneOf": [ { "properties": { "bar": true, "baz": true }, "required": ["bar"] }, { "properties": { "foo": true }, "required": ["foo"] } ] }, "tests": [ { "description": "first oneOf valid", "data": {"bar": 8}, "valid": true }, { "description": "second oneOf valid", "data": {"foo": "foo"}, "valid": true }, { "description": "both oneOf valid", "data": {"foo": "foo", "bar": 8}, "valid": false }, { "description": "neither oneOf valid", "data": {"baz": "quux"}, "valid": false } ] }, { "description": "nested oneOf, to check validation semantics", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "oneOf": [ { "oneOf": [ { "type": "null" } ] } ] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "anything non-null is invalid", "data": 123, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/000077500000000000000000000000001477700171100275055ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/bignum.json000066400000000000000000000065011477700171100316630ustar00rootroot00000000000000[ { "description": "integer", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "integer" }, "tests": [ { "description": "a bignum is an integer", "data": 12345678910111213141516171819202122232425262728293031, "valid": true }, { "description": "a negative bignum is an integer", "data": -12345678910111213141516171819202122232425262728293031, "valid": true } ] }, { "description": "number", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "number" }, "tests": [ { "description": "a bignum is a number", "data": 98249283749234923498293171823948729348710298301928331, "valid": true }, { "description": "a negative bignum is a number", "data": -98249283749234923498293171823948729348710298301928331, "valid": true } ] }, { "description": "string", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "string" }, "tests": [ { "description": "a bignum is not a string", "data": 98249283749234923498293171823948729348710298301928331, "valid": false } ] }, { "description": "maximum integer comparison", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "maximum": 18446744073709551615 }, "tests": [ { "description": "comparison works for high numbers", "data": 18446744073709551600, "valid": true } ] }, { "description": "float comparison with high precision", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "exclusiveMaximum": 972783798187987123879878123.18878137 }, "tests": [ { "description": "comparison works for high numbers", "data": 972783798187987123879878123.188781371, "valid": false } ] }, { "description": "minimum integer comparison", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "minimum": -18446744073709551615 }, "tests": [ { "description": "comparison works for very negative numbers", "data": -18446744073709551600, "valid": true } ] }, { "description": "float comparison with high precision on negative numbers", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "exclusiveMinimum": -972783798187987123879878123.18878137 }, "tests": [ { "description": "comparison works for very negative numbers", "data": -972783798187987123879878123.188781371, "valid": false } ] } ] dependencies-compatibility.json000066400000000000000000000176731477700171100356340ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional[ { "description": "single dependency", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "dependencies": {"bar": ["foo"]} }, "tests": [ { "description": "neither", "data": {}, "valid": true }, { "description": "nondependant", "data": {"foo": 1}, "valid": true }, { "description": "with dependency", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "missing dependency", "data": {"bar": 2}, "valid": false }, { "description": "ignores arrays", "data": ["bar"], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "empty dependents", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "dependencies": {"bar": []} }, "tests": [ { "description": "empty object", "data": {}, "valid": true }, { "description": "object with one property", "data": {"bar": 2}, "valid": true }, { "description": "non-object is valid", "data": 1, "valid": true } ] }, { "description": "multiple dependents required", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "dependencies": {"quux": ["foo", "bar"]} }, "tests": [ { "description": "neither", "data": {}, "valid": true }, { "description": "nondependants", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "with dependencies", "data": {"foo": 1, "bar": 2, "quux": 3}, "valid": true }, { "description": "missing dependency", "data": {"foo": 1, "quux": 2}, "valid": false }, { "description": "missing other dependency", "data": {"bar": 1, "quux": 2}, "valid": false }, { "description": "missing both dependencies", "data": {"quux": 1}, "valid": false } ] }, { "description": "dependencies with escaped characters", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "dependencies": { "foo\nbar": ["foo\rbar"], "foo\"bar": ["foo'bar"] } }, "tests": [ { "description": "CRLF", "data": { "foo\nbar": 1, "foo\rbar": 2 }, "valid": true }, { "description": "quoted quotes", "data": { "foo'bar": 1, "foo\"bar": 2 }, "valid": true }, { "description": "CRLF missing dependent", "data": { "foo\nbar": 1, "foo": 2 }, "valid": false }, { "description": "quoted quotes missing dependent", "data": { "foo\"bar": 2 }, "valid": false } ] }, { "description": "single schema dependency", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "dependencies": { "bar": { "properties": { "foo": {"type": "integer"}, "bar": {"type": "integer"} } } } }, "tests": [ { "description": "valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "no dependency", "data": {"foo": "quux"}, "valid": true }, { "description": "wrong type", "data": {"foo": "quux", "bar": 2}, "valid": false }, { "description": "wrong type other", "data": {"foo": 2, "bar": "quux"}, "valid": false }, { "description": "wrong type both", "data": {"foo": "quux", "bar": "quux"}, "valid": false }, { "description": "ignores arrays", "data": ["bar"], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "boolean subschemas", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "dependencies": { "foo": true, "bar": false } }, "tests": [ { "description": "object with property having schema true is valid", "data": {"foo": 1}, "valid": true }, { "description": "object with property having schema false is invalid", "data": {"bar": 2}, "valid": false }, { "description": "object with both properties is invalid", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "empty object is valid", "data": {}, "valid": true } ] }, { "description": "schema dependencies with escaped characters", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "dependencies": { "foo\tbar": {"minProperties": 4}, "foo'bar": {"required": ["foo\"bar"]} } }, "tests": [ { "description": "quoted tab", "data": { "foo\tbar": 1, "a": 2, "b": 3, "c": 4 }, "valid": true }, { "description": "quoted quote", "data": { "foo'bar": {"foo\"bar": 1} }, "valid": false }, { "description": "quoted tab invalid under dependent schema", "data": { "foo\tbar": 1, "a": 2 }, "valid": false }, { "description": "quoted quote invalid under dependent schema", "data": {"foo'bar": 1}, "valid": false } ] } ] ecmascript-regex.json000066400000000000000000000476441477700171100336020ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional[ { "description": "ECMA 262 regex $ does not match trailing newline", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "string", "pattern": "^abc$" }, "tests": [ { "description": "matches in Python, but not in ECMA 262", "data": "abc\\n", "valid": false }, { "description": "matches", "data": "abc", "valid": true } ] }, { "description": "ECMA 262 regex converts \\t to horizontal tab", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "string", "pattern": "^\\t$" }, "tests": [ { "description": "does not match", "data": "\\t", "valid": false }, { "description": "matches", "data": "\u0009", "valid": true } ] }, { "description": "ECMA 262 regex escapes control codes with \\c and upper letter", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "string", "pattern": "^\\cC$" }, "tests": [ { "description": "does not match", "data": "\\cC", "valid": false }, { "description": "matches", "data": "\u0003", "valid": true } ] }, { "description": "ECMA 262 regex escapes control codes with \\c and lower letter", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "string", "pattern": "^\\cc$" }, "tests": [ { "description": "does not match", "data": "\\cc", "valid": false }, { "description": "matches", "data": "\u0003", "valid": true } ] }, { "description": "ECMA 262 \\d matches ascii digits only", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "string", "pattern": "^\\d$" }, "tests": [ { "description": "ASCII zero matches", "data": "0", "valid": true }, { "description": "NKO DIGIT ZERO does not match (unlike e.g. Python)", "data": "߀", "valid": false }, { "description": "NKO DIGIT ZERO (as \\u escape) does not match", "data": "\u07c0", "valid": false } ] }, { "description": "ECMA 262 \\D matches everything but ascii digits", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "string", "pattern": "^\\D$" }, "tests": [ { "description": "ASCII zero does not match", "data": "0", "valid": false }, { "description": "NKO DIGIT ZERO matches (unlike e.g. Python)", "data": "߀", "valid": true }, { "description": "NKO DIGIT ZERO (as \\u escape) matches", "data": "\u07c0", "valid": true } ] }, { "description": "ECMA 262 \\w matches ascii letters only", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "string", "pattern": "^\\w$" }, "tests": [ { "description": "ASCII 'a' matches", "data": "a", "valid": true }, { "description": "latin-1 e-acute does not match (unlike e.g. Python)", "data": "é", "valid": false } ] }, { "description": "ECMA 262 \\W matches everything but ascii letters", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "string", "pattern": "^\\W$" }, "tests": [ { "description": "ASCII 'a' does not match", "data": "a", "valid": false }, { "description": "latin-1 e-acute matches (unlike e.g. Python)", "data": "é", "valid": true } ] }, { "description": "ECMA 262 \\s matches whitespace", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "string", "pattern": "^\\s$" }, "tests": [ { "description": "ASCII space matches", "data": " ", "valid": true }, { "description": "Character tabulation matches", "data": "\t", "valid": true }, { "description": "Line tabulation matches", "data": "\u000b", "valid": true }, { "description": "Form feed matches", "data": "\u000c", "valid": true }, { "description": "latin-1 non-breaking-space matches", "data": "\u00a0", "valid": true }, { "description": "zero-width whitespace matches", "data": "\ufeff", "valid": true }, { "description": "line feed matches (line terminator)", "data": "\u000a", "valid": true }, { "description": "paragraph separator matches (line terminator)", "data": "\u2029", "valid": true }, { "description": "EM SPACE matches (Space_Separator)", "data": "\u2003", "valid": true }, { "description": "Non-whitespace control does not match", "data": "\u0001", "valid": false }, { "description": "Non-whitespace does not match", "data": "\u2013", "valid": false } ] }, { "description": "ECMA 262 \\S matches everything but whitespace", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "string", "pattern": "^\\S$" }, "tests": [ { "description": "ASCII space does not match", "data": " ", "valid": false }, { "description": "Character tabulation does not match", "data": "\t", "valid": false }, { "description": "Line tabulation does not match", "data": "\u000b", "valid": false }, { "description": "Form feed does not match", "data": "\u000c", "valid": false }, { "description": "latin-1 non-breaking-space does not match", "data": "\u00a0", "valid": false }, { "description": "zero-width whitespace does not match", "data": "\ufeff", "valid": false }, { "description": "line feed does not match (line terminator)", "data": "\u000a", "valid": false }, { "description": "paragraph separator does not match (line terminator)", "data": "\u2029", "valid": false }, { "description": "EM SPACE does not match (Space_Separator)", "data": "\u2003", "valid": false }, { "description": "Non-whitespace control matches", "data": "\u0001", "valid": true }, { "description": "Non-whitespace matches", "data": "\u2013", "valid": true } ] }, { "description": "patterns always use unicode semantics with pattern", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "pattern": "\\p{Letter}cole" }, "tests": [ { "description": "ascii character in json string", "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", "valid": true }, { "description": "literal unicode character in json string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": true }, { "description": "unicode character in hex format in string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": true }, { "description": "unicode matching is case-sensitive", "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", "valid": false } ] }, { "description": "\\w in patterns matches [A-Za-z0-9_], not unicode letters", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "pattern": "\\wcole" }, "tests": [ { "description": "ascii character in json string", "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", "valid": true }, { "description": "literal unicode character in json string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "unicode character in hex format in string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "unicode matching is case-sensitive", "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", "valid": false } ] }, { "description": "pattern with ASCII ranges", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "pattern": "[a-z]cole" }, "tests": [ { "description": "literal unicode character in json string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "unicode character in hex format in string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "ascii characters match", "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", "valid": true } ] }, { "description": "\\d in pattern matches [0-9], not unicode digits", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "pattern": "^\\d+$" }, "tests": [ { "description": "ascii digits", "data": "42", "valid": true }, { "description": "ascii non-digits", "data": "-%#", "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": "৪২", "valid": false } ] }, { "description": "\\a is not an ECMA 262 control escape", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "https://json-schema.org/draft/next/schema" }, "tests": [ { "description": "when used as a pattern", "data": { "pattern": "\\a" }, "valid": false } ] }, { "description": "pattern with non-ASCII digits", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "pattern": "^\\p{digit}+$" }, "tests": [ { "description": "ascii digits", "data": "42", "valid": true }, { "description": "ascii non-digits", "data": "-%#", "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": "৪২", "valid": true } ] }, { "description": "patterns always use unicode semantics with patternProperties", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "patternProperties": { "\\p{Letter}cole": true }, "additionalProperties": false }, "tests": [ { "description": "ascii character in json string", "data": { "l'ecole": "pas de vraie vie" }, "valid": true }, { "description": "literal unicode character in json string", "data": { "l'école": "pas de vraie vie" }, "valid": true }, { "description": "unicode character in hex format in string", "data": { "l'\u00e9cole": "pas de vraie vie" }, "valid": true }, { "description": "unicode matching is case-sensitive", "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, "valid": false } ] }, { "description": "\\w in patternProperties matches [A-Za-z0-9_], not unicode letters", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "patternProperties": { "\\wcole": true }, "additionalProperties": false }, "tests": [ { "description": "ascii character in json string", "data": { "l'ecole": "pas de vraie vie" }, "valid": true }, { "description": "literal unicode character in json string", "data": { "l'école": "pas de vraie vie" }, "valid": false }, { "description": "unicode character in hex format in string", "data": { "l'\u00e9cole": "pas de vraie vie" }, "valid": false }, { "description": "unicode matching is case-sensitive", "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, "valid": false } ] }, { "description": "patternProperties with ASCII ranges", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "patternProperties": { "[a-z]cole": true }, "additionalProperties": false }, "tests": [ { "description": "literal unicode character in json string", "data": { "l'école": "pas de vraie vie" }, "valid": false }, { "description": "unicode character in hex format in string", "data": { "l'\u00e9cole": "pas de vraie vie" }, "valid": false }, { "description": "ascii characters match", "data": { "l'ecole": "pas de vraie vie" }, "valid": true } ] }, { "description": "\\d in patternProperties matches [0-9], not unicode digits", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "patternProperties": { "^\\d+$": true }, "additionalProperties": false }, "tests": [ { "description": "ascii digits", "data": { "42": "life, the universe, and everything" }, "valid": true }, { "description": "ascii non-digits", "data": { "-%#": "spending the year dead for tax reasons" }, "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": { "৪২": "khajit has wares if you have coin" }, "valid": false } ] }, { "description": "patternProperties with non-ASCII digits", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "patternProperties": { "^\\p{digit}+$": true }, "additionalProperties": false }, "tests": [ { "description": "ascii digits", "data": { "42": "life, the universe, and everything" }, "valid": true }, { "description": "ascii non-digits", "data": { "-%#": "spending the year dead for tax reasons" }, "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": { "৪২": "khajit has wares if you have coin" }, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/float-overflow.json000066400000000000000000000007171477700171100333530ustar00rootroot00000000000000[ { "description": "all integers are multiples of 0.5, if overflow is handled", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "integer", "multipleOf": 0.5 }, "tests": [ { "description": "valid if optional overflow handling is implemented", "data": 1e308, "valid": true } ] } ] format-assertion.json000066400000000000000000000025301477700171100336160ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional[ { "description": "schema that uses custom metaschema with format-assertion: false", "schema": { "$id": "https://schema/using/format-assertion/false", "$schema": "http://localhost:1234/draft-next/format-assertion-false.json", "format": "ipv4" }, "tests": [ { "description": "format-assertion: false: valid string", "data": "127.0.0.1", "valid": true }, { "description": "format-assertion: false: invalid string", "data": "not-an-ipv4", "valid": false } ] }, { "description": "schema that uses custom metaschema with format-assertion: true", "schema": { "$id": "https://schema/using/format-assertion/true", "$schema": "http://localhost:1234/draft-next/format-assertion-true.json", "format": "ipv4" }, "tests": [ { "description": "format-assertion: true: valid string", "data": "127.0.0.1", "valid": true }, { "description": "format-assertion: true: invalid string", "data": "not-an-ipv4", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/format/000077500000000000000000000000001477700171100307755ustar00rootroot00000000000000date-time.json000066400000000000000000000112101477700171100334550ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/format[ { "description": "validation of date-time strings", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "date-time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid date-time string", "data": "1963-06-19T08:30:06.283185Z", "valid": true }, { "description": "a valid date-time string without second fraction", "data": "1963-06-19T08:30:06Z", "valid": true }, { "description": "a valid date-time string with plus offset", "data": "1937-01-01T12:00:27.87+00:20", "valid": true }, { "description": "a valid date-time string with minus offset", "data": "1990-12-31T15:59:50.123-08:00", "valid": true }, { "description": "a valid date-time with a leap second, UTC", "data": "1998-12-31T23:59:60Z", "valid": true }, { "description": "a valid date-time with a leap second, with minus offset", "data": "1998-12-31T15:59:60.123-08:00", "valid": true }, { "description": "an invalid date-time past leap second, UTC", "data": "1998-12-31T23:59:61Z", "valid": false }, { "description": "an invalid date-time with leap second on a wrong minute, UTC", "data": "1998-12-31T23:58:60Z", "valid": false }, { "description": "an invalid date-time with leap second on a wrong hour, UTC", "data": "1998-12-31T22:59:60Z", "valid": false }, { "description": "an invalid day in date-time string", "data": "1990-02-31T15:59:59.123-08:00", "valid": false }, { "description": "an invalid offset in date-time string", "data": "1990-12-31T15:59:59-24:00", "valid": false }, { "description": "an invalid closing Z after time-zone offset", "data": "1963-06-19T08:30:06.28123+01:00Z", "valid": false }, { "description": "an invalid date-time string", "data": "06/19/1963 08:30:06 PST", "valid": false }, { "description": "case-insensitive T and Z", "data": "1963-06-19t08:30:06.283185z", "valid": true }, { "description": "only RFC3339 not all of ISO 8601 are valid", "data": "2013-350T01:01:01", "valid": false }, { "description": "invalid non-padded month dates", "data": "1963-6-19T08:30:06.283185Z", "valid": false }, { "description": "invalid non-padded day dates", "data": "1963-06-1T08:30:06.283185Z", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4) in date portion", "data": "1963-06-1৪T00:00:00Z", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4) in time portion", "data": "1963-06-11T0৪:00:00Z", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/format/date.json000066400000000000000000000202021477700171100326010ustar00rootroot00000000000000[ { "description": "validation of date strings", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "date" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid date string", "data": "1963-06-19", "valid": true }, { "description": "a valid date string with 31 days in January", "data": "2020-01-31", "valid": true }, { "description": "a invalid date string with 32 days in January", "data": "2020-01-32", "valid": false }, { "description": "a valid date string with 28 days in February (normal)", "data": "2021-02-28", "valid": true }, { "description": "a invalid date string with 29 days in February (normal)", "data": "2021-02-29", "valid": false }, { "description": "a valid date string with 29 days in February (leap)", "data": "2020-02-29", "valid": true }, { "description": "a invalid date string with 30 days in February (leap)", "data": "2020-02-30", "valid": false }, { "description": "a valid date string with 31 days in March", "data": "2020-03-31", "valid": true }, { "description": "a invalid date string with 32 days in March", "data": "2020-03-32", "valid": false }, { "description": "a valid date string with 30 days in April", "data": "2020-04-30", "valid": true }, { "description": "a invalid date string with 31 days in April", "data": "2020-04-31", "valid": false }, { "description": "a valid date string with 31 days in May", "data": "2020-05-31", "valid": true }, { "description": "a invalid date string with 32 days in May", "data": "2020-05-32", "valid": false }, { "description": "a valid date string with 30 days in June", "data": "2020-06-30", "valid": true }, { "description": "a invalid date string with 31 days in June", "data": "2020-06-31", "valid": false }, { "description": "a valid date string with 31 days in July", "data": "2020-07-31", "valid": true }, { "description": "a invalid date string with 32 days in July", "data": "2020-07-32", "valid": false }, { "description": "a valid date string with 31 days in August", "data": "2020-08-31", "valid": true }, { "description": "a invalid date string with 32 days in August", "data": "2020-08-32", "valid": false }, { "description": "a valid date string with 30 days in September", "data": "2020-09-30", "valid": true }, { "description": "a invalid date string with 31 days in September", "data": "2020-09-31", "valid": false }, { "description": "a valid date string with 31 days in October", "data": "2020-10-31", "valid": true }, { "description": "a invalid date string with 32 days in October", "data": "2020-10-32", "valid": false }, { "description": "a valid date string with 30 days in November", "data": "2020-11-30", "valid": true }, { "description": "a invalid date string with 31 days in November", "data": "2020-11-31", "valid": false }, { "description": "a valid date string with 31 days in December", "data": "2020-12-31", "valid": true }, { "description": "a invalid date string with 32 days in December", "data": "2020-12-32", "valid": false }, { "description": "a invalid date string with invalid month", "data": "2020-13-01", "valid": false }, { "description": "an invalid date string", "data": "06/19/1963", "valid": false }, { "description": "only RFC3339 not all of ISO 8601 are valid", "data": "2013-350", "valid": false }, { "description": "non-padded month dates are not valid", "data": "1998-1-20", "valid": false }, { "description": "non-padded day dates are not valid", "data": "1998-01-1", "valid": false }, { "description": "invalid month", "data": "1998-13-01", "valid": false }, { "description": "invalid month-day combination", "data": "1998-04-31", "valid": false }, { "description": "2021 is not a leap year", "data": "2021-02-29", "valid": false }, { "description": "2020 is a leap year", "data": "2020-02-29", "valid": true }, { "description": "invalid non-ASCII '৪' (a Bengali 4)", "data": "1963-06-1৪", "valid": false }, { "description": "ISO8601 / non-RFC3339: YYYYMMDD without dashes (2023-03-28)", "data": "20230328", "valid": false }, { "description": "ISO8601 / non-RFC3339: week number implicit day of week (2023-01-02)", "data": "2023-W01", "valid": false }, { "description": "ISO8601 / non-RFC3339: week number with day of week (2023-03-28)", "data": "2023-W13-2", "valid": false }, { "description": "ISO8601 / non-RFC3339: week number rollover to next year (2023-01-01)", "data": "2022W527", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/format/duration.json000066400000000000000000000077151477700171100335270ustar00rootroot00000000000000[ { "description": "validation of duration strings", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "duration" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid duration string", "data": "P4DT12H30M5S", "valid": true }, { "description": "an invalid duration string", "data": "PT1D", "valid": false }, { "description": "no elements present", "data": "P", "valid": false }, { "description": "no time elements present", "data": "P1YT", "valid": false }, { "description": "no date or time elements present", "data": "PT", "valid": false }, { "description": "elements out of order", "data": "P2D1Y", "valid": false }, { "description": "missing time separator", "data": "P1D2H", "valid": false }, { "description": "time element in the date position", "data": "P2S", "valid": false }, { "description": "four years duration", "data": "P4Y", "valid": true }, { "description": "zero time, in seconds", "data": "PT0S", "valid": true }, { "description": "zero time, in days", "data": "P0D", "valid": true }, { "description": "one month duration", "data": "P1M", "valid": true }, { "description": "one minute duration", "data": "PT1M", "valid": true }, { "description": "one and a half days, in hours", "data": "PT36H", "valid": true }, { "description": "one and a half days, in days and hours", "data": "P1DT12H", "valid": true }, { "description": "two weeks", "data": "P2W", "valid": true }, { "description": "weeks cannot be combined with other units", "data": "P1Y2W", "valid": false }, { "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "P২Y", "valid": false }, { "description": "element without unit", "data": "P1", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/format/email.json000066400000000000000000000077211477700171100327660ustar00rootroot00000000000000[ { "description": "validation of e-mail addresses", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "email" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid e-mail address", "data": "joe.bloggs@example.com", "valid": true }, { "description": "an invalid e-mail address", "data": "2962", "valid": false }, { "description": "tilde in local part is valid", "data": "te~st@example.com", "valid": true }, { "description": "tilde before local part is valid", "data": "~test@example.com", "valid": true }, { "description": "tilde after local part is valid", "data": "test~@example.com", "valid": true }, { "description": "a quoted string with a space in the local part is valid", "data": "\"joe bloggs\"@example.com", "valid": true }, { "description": "a quoted string with a double dot in the local part is valid", "data": "\"joe..bloggs\"@example.com", "valid": true }, { "description": "a quoted string with a @ in the local part is valid", "data": "\"joe@bloggs\"@example.com", "valid": true }, { "description": "an IPv4-address-literal after the @ is valid", "data": "joe.bloggs@[127.0.0.1]", "valid": true }, { "description": "an IPv6-address-literal after the @ is valid", "data": "joe.bloggs@[IPv6:::1]", "valid": true }, { "description": "dot before local part is not valid", "data": ".test@example.com", "valid": false }, { "description": "dot after local part is not valid", "data": "test.@example.com", "valid": false }, { "description": "two separated dots inside local part are valid", "data": "te.s.t@example.com", "valid": true }, { "description": "two subsequent dots inside local part are not valid", "data": "te..st@example.com", "valid": false }, { "description": "an invalid domain", "data": "joe.bloggs@invalid=domain.com", "valid": false }, { "description": "an invalid IPv4-address-literal", "data": "joe.bloggs@[127.0.0.300]", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/format/hostname.json000066400000000000000000000077561477700171100335250ustar00rootroot00000000000000[ { "description": "validation of host names", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "hostname" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid host name", "data": "www.example.com", "valid": true }, { "description": "a valid punycoded IDN hostname", "data": "xn--4gbwdl.xn--wgbh1c", "valid": true }, { "description": "a host name starting with an illegal character", "data": "-a-host-name-that-starts-with--", "valid": false }, { "description": "a host name containing illegal characters", "data": "not_a_valid_host_name", "valid": false }, { "description": "a host name with a component too long", "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", "valid": false }, { "description": "starts with hyphen", "data": "-hostname", "valid": false }, { "description": "ends with hyphen", "data": "hostname-", "valid": false }, { "description": "starts with underscore", "data": "_hostname", "valid": false }, { "description": "ends with underscore", "data": "hostname_", "valid": false }, { "description": "contains underscore", "data": "host_name", "valid": false }, { "description": "maximum label length", "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.com", "valid": true }, { "description": "exceeds maximum label length", "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl.com", "valid": false }, { "description": "single label", "data": "hostname", "valid": true }, { "description": "single label with hyphen", "data": "host-name", "valid": true }, { "description": "single label with digits", "data": "h0stn4me", "valid": true }, { "description": "single label starting with digit", "data": "1host", "valid": true }, { "description": "single label ending with digit", "data": "hostnam3", "valid": true } ] } ] idn-email.json000066400000000000000000000035041477700171100334520ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/format[ { "description": "validation of an internationalized e-mail addresses", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "idn-email" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid idn e-mail (example@example.test in Hangul)", "data": "실례@실례.테스트", "valid": true }, { "description": "an invalid idn e-mail address", "data": "2962", "valid": false }, { "description": "a valid e-mail address", "data": "joe.bloggs@example.com", "valid": true }, { "description": "an invalid e-mail address", "data": "2962", "valid": false } ] } ] idn-hostname.json000066400000000000000000000363731477700171100342130ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/format[ { "description": "validation of internationalized host names", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "idn-hostname" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid host name (example.test in Hangul)", "data": "실례.테스트", "valid": true }, { "description": "illegal first char U+302E Hangul single dot tone mark", "data": "〮실례.테스트", "valid": false }, { "description": "contains illegal char U+302E Hangul single dot tone mark", "data": "실〮례.테스트", "valid": false }, { "description": "a host name with a component too long", "data": "실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실례례테스트례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례테스트례례실례.테스트", "valid": false }, { "description": "invalid label, correct Punycode", "comment": "https://tools.ietf.org/html/rfc5890#section-2.3.2.1 https://tools.ietf.org/html/rfc5891#section-4.4 https://tools.ietf.org/html/rfc3492#section-7.1", "data": "-> $1.00 <--", "valid": false }, { "description": "valid Chinese Punycode", "comment": "https://tools.ietf.org/html/rfc5890#section-2.3.2.1 https://tools.ietf.org/html/rfc5891#section-4.4", "data": "xn--ihqwcrb4cv8a8dqg056pqjye", "valid": true }, { "description": "invalid Punycode", "comment": "https://tools.ietf.org/html/rfc5891#section-4.4 https://tools.ietf.org/html/rfc5890#section-2.3.2.1", "data": "xn--X", "valid": false }, { "description": "U-label contains \"--\" in the 3rd and 4th position", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1 https://tools.ietf.org/html/rfc5890#section-2.3.2.1", "data": "XN--aa---o47jg78q", "valid": false }, { "description": "U-label starts with a dash", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", "data": "-hello", "valid": false }, { "description": "U-label ends with a dash", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", "data": "hello-", "valid": false }, { "description": "U-label starts and ends with a dash", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", "data": "-hello-", "valid": false }, { "description": "Begins with a Spacing Combining Mark", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", "data": "\u0903hello", "valid": false }, { "description": "Begins with a Nonspacing Mark", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", "data": "\u0300hello", "valid": false }, { "description": "Begins with an Enclosing Mark", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", "data": "\u0488hello", "valid": false }, { "description": "Exceptions that are PVALID, left-to-right chars", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", "data": "\u00df\u03c2\u0f0b\u3007", "valid": true }, { "description": "Exceptions that are PVALID, right-to-left chars", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", "data": "\u06fd\u06fe", "valid": true }, { "description": "Exceptions that are DISALLOWED, right-to-left chars", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", "data": "\u0640\u07fa", "valid": false }, { "description": "Exceptions that are DISALLOWED, left-to-right chars", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6 Note: The two combining marks (U+302E and U+302F) are in the middle and not at the start", "data": "\u3031\u3032\u3033\u3034\u3035\u302e\u302f\u303b", "valid": false }, { "description": "MIDDLE DOT with no preceding 'l'", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", "data": "a\u00b7l", "valid": false }, { "description": "MIDDLE DOT with nothing preceding", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", "data": "\u00b7l", "valid": false }, { "description": "MIDDLE DOT with no following 'l'", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", "data": "l\u00b7a", "valid": false }, { "description": "MIDDLE DOT with nothing following", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", "data": "l\u00b7", "valid": false }, { "description": "MIDDLE DOT with surrounding 'l's", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", "data": "l\u00b7l", "valid": true }, { "description": "Greek KERAIA not followed by Greek", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", "data": "\u03b1\u0375S", "valid": false }, { "description": "Greek KERAIA not followed by anything", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", "data": "\u03b1\u0375", "valid": false }, { "description": "Greek KERAIA followed by Greek", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", "data": "\u03b1\u0375\u03b2", "valid": true }, { "description": "Hebrew GERESH not preceded by Hebrew", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", "data": "A\u05f3\u05d1", "valid": false }, { "description": "Hebrew GERESH not preceded by anything", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", "data": "\u05f3\u05d1", "valid": false }, { "description": "Hebrew GERESH preceded by Hebrew", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", "data": "\u05d0\u05f3\u05d1", "valid": true }, { "description": "Hebrew GERSHAYIM not preceded by Hebrew", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", "data": "A\u05f4\u05d1", "valid": false }, { "description": "Hebrew GERSHAYIM not preceded by anything", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", "data": "\u05f4\u05d1", "valid": false }, { "description": "Hebrew GERSHAYIM preceded by Hebrew", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", "data": "\u05d0\u05f4\u05d1", "valid": true }, { "description": "KATAKANA MIDDLE DOT with no Hiragana, Katakana, or Han", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", "data": "def\u30fbabc", "valid": false }, { "description": "KATAKANA MIDDLE DOT with no other characters", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", "data": "\u30fb", "valid": false }, { "description": "KATAKANA MIDDLE DOT with Hiragana", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", "data": "\u30fb\u3041", "valid": true }, { "description": "KATAKANA MIDDLE DOT with Katakana", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", "data": "\u30fb\u30a1", "valid": true }, { "description": "KATAKANA MIDDLE DOT with Han", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", "data": "\u30fb\u4e08", "valid": true }, { "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", "data": "\u0660\u06f0", "valid": false }, { "description": "Arabic-Indic digits not mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", "data": "\u0628\u0660\u0628", "valid": true }, { "description": "Extended Arabic-Indic digits not mixed with Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.9", "data": "\u06f00", "valid": true }, { "description": "ZERO WIDTH JOINER not preceded by Virama", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", "data": "\u0915\u200d\u0937", "valid": false }, { "description": "ZERO WIDTH JOINER not preceded by anything", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", "data": "\u200d\u0937", "valid": false }, { "description": "ZERO WIDTH JOINER preceded by Virama", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", "data": "\u0915\u094d\u200d\u0937", "valid": true }, { "description": "ZERO WIDTH NON-JOINER preceded by Virama", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1", "data": "\u0915\u094d\u200c\u0937", "valid": true }, { "description": "ZERO WIDTH NON-JOINER not preceded by Virama but matches regexp", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1 https://www.w3.org/TR/alreq/#h_disjoining_enforcement", "data": "\u0628\u064a\u200c\u0628\u064a", "valid": true }, { "description": "single label", "data": "hostname", "valid": true }, { "description": "single label with hyphen", "data": "host-name", "valid": true }, { "description": "single label with digits", "data": "h0stn4me", "valid": true }, { "description": "single label starting with digit", "data": "1host", "valid": true }, { "description": "single label ending with digit", "data": "hostnam3", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/format/ipv4.json000066400000000000000000000060121477700171100325510ustar00rootroot00000000000000[ { "description": "validation of IP addresses", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "ipv4" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid IP address", "data": "192.168.0.1", "valid": true }, { "description": "an IP address with too many components", "data": "127.0.0.0.1", "valid": false }, { "description": "an IP address with out-of-range values", "data": "256.256.256.256", "valid": false }, { "description": "an IP address without 4 components", "data": "127.0", "valid": false }, { "description": "an IP address as an integer", "data": "0x7f000001", "valid": false }, { "description": "an IP address as an integer (decimal)", "data": "2130706433", "valid": false }, { "description": "invalid leading zeroes, as they are treated as octals", "comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/", "data": "087.10.0.1", "valid": false }, { "description": "value without leading zero is valid", "data": "87.10.0.1", "valid": true }, { "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২7.0.0.1", "valid": false }, { "description": "netmask is not a part of ipv4 address", "data": "192.168.1.0/24", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/format/ipv6.json000066400000000000000000000155671477700171100325720ustar00rootroot00000000000000[ { "description": "validation of IPv6 addresses", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "ipv6" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid IPv6 address", "data": "::1", "valid": true }, { "description": "an IPv6 address with out-of-range values", "data": "12345::", "valid": false }, { "description": "trailing 4 hex symbols is valid", "data": "::abef", "valid": true }, { "description": "trailing 5 hex symbols is invalid", "data": "::abcef", "valid": false }, { "description": "an IPv6 address with too many components", "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", "valid": false }, { "description": "an IPv6 address containing illegal characters", "data": "::laptop", "valid": false }, { "description": "no digits is valid", "data": "::", "valid": true }, { "description": "leading colons is valid", "data": "::42:ff:1", "valid": true }, { "description": "trailing colons is valid", "data": "d6::", "valid": true }, { "description": "missing leading octet is invalid", "data": ":2:3:4:5:6:7:8", "valid": false }, { "description": "missing trailing octet is invalid", "data": "1:2:3:4:5:6:7:", "valid": false }, { "description": "missing leading octet with omitted octets later", "data": ":2:3:4::8", "valid": false }, { "description": "single set of double colons in the middle is valid", "data": "1:d6::42", "valid": true }, { "description": "two sets of double colons is invalid", "data": "1::d6::42", "valid": false }, { "description": "mixed format with the ipv4 section as decimal octets", "data": "1::d6:192.168.0.1", "valid": true }, { "description": "mixed format with double colons between the sections", "data": "1:2::192.168.0.1", "valid": true }, { "description": "mixed format with ipv4 section with octet out of range", "data": "1::2:192.168.256.1", "valid": false }, { "description": "mixed format with ipv4 section with a hex octet", "data": "1::2:192.168.ff.1", "valid": false }, { "description": "mixed format with leading double colons (ipv4-mapped ipv6 address)", "data": "::ffff:192.168.0.1", "valid": true }, { "description": "triple colons is invalid", "data": "1:2:3:4:5:::8", "valid": false }, { "description": "8 octets", "data": "1:2:3:4:5:6:7:8", "valid": true }, { "description": "insufficient octets without double colons", "data": "1:2:3:4:5:6:7", "valid": false }, { "description": "no colons is invalid", "data": "1", "valid": false }, { "description": "ipv4 is not ipv6", "data": "127.0.0.1", "valid": false }, { "description": "ipv4 segment must have 4 octets", "data": "1:2:3:4:1.2.3", "valid": false }, { "description": "leading whitespace is invalid", "data": " ::1", "valid": false }, { "description": "trailing whitespace is invalid", "data": "::1 ", "valid": false }, { "description": "netmask is not a part of ipv6 address", "data": "fe80::/64", "valid": false }, { "description": "zone id is not a part of ipv6 address", "data": "fe80::a%eth1", "valid": false }, { "description": "a long valid ipv6", "data": "1000:1000:1000:1000:1000:1000:255.255.255.255", "valid": true }, { "description": "a long invalid ipv6, below length limit, first", "data": "100:100:100:100:100:100:255.255.255.255.255", "valid": false }, { "description": "a long invalid ipv6, below length limit, second", "data": "100:100:100:100:100:100:100:255.255.255.255", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4)", "data": "1:2:3:4:5:6:7:৪", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4) in the IPv4 portion", "data": "1:2::192.16৪.0.1", "valid": false } ] } ] iri-reference.json000066400000000000000000000044421477700171100343340ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/format[ { "description": "validation of IRI References", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "iri-reference" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid IRI", "data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx", "valid": true }, { "description": "a valid protocol-relative IRI Reference", "data": "//ƒøø.ßår/?∂éœ=πîx#πîüx", "valid": true }, { "description": "a valid relative IRI Reference", "data": "/âππ", "valid": true }, { "description": "an invalid IRI Reference", "data": "\\\\WINDOWS\\filëßåré", "valid": false }, { "description": "a valid IRI Reference", "data": "âππ", "valid": true }, { "description": "a valid IRI fragment", "data": "#ƒrägmênt", "valid": true }, { "description": "an invalid IRI fragment", "data": "#ƒräg\\mênt", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/format/iri.json000066400000000000000000000054541477700171100324630ustar00rootroot00000000000000[ { "description": "validation of IRIs", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "iri" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid IRI with anchor tag", "data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx", "valid": true }, { "description": "a valid IRI with anchor tag and parentheses", "data": "http://ƒøø.com/blah_(wîkïpédiå)_blah#ßité-1", "valid": true }, { "description": "a valid IRI with URL-encoded stuff", "data": "http://ƒøø.ßår/?q=Test%20URL-encoded%20stuff", "valid": true }, { "description": "a valid IRI with many special characters", "data": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", "valid": true }, { "description": "a valid IRI based on IPv6", "data": "http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]", "valid": true }, { "description": "an invalid IRI based on IPv6", "data": "http://2001:0db8:85a3:0000:0000:8a2e:0370:7334", "valid": false }, { "description": "an invalid relative IRI Reference", "data": "/abc", "valid": false }, { "description": "an invalid IRI", "data": "\\\\WINDOWS\\filëßåré", "valid": false }, { "description": "an invalid IRI though valid IRI reference", "data": "âππ", "valid": false } ] } ] json-pointer.json000066400000000000000000000152131477700171100342420ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/format[ { "description": "validation of JSON-pointers (JSON String Representation)", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "json-pointer" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid JSON-pointer", "data": "/foo/bar~0/baz~1/%a", "valid": true }, { "description": "not a valid JSON-pointer (~ not escaped)", "data": "/foo/bar~", "valid": false }, { "description": "valid JSON-pointer with empty segment", "data": "/foo//bar", "valid": true }, { "description": "valid JSON-pointer with the last empty segment", "data": "/foo/bar/", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #1", "data": "", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #2", "data": "/foo", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #3", "data": "/foo/0", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #4", "data": "/", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #5", "data": "/a~1b", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #6", "data": "/c%d", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #7", "data": "/e^f", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #8", "data": "/g|h", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #9", "data": "/i\\j", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #10", "data": "/k\"l", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #11", "data": "/ ", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #12", "data": "/m~0n", "valid": true }, { "description": "valid JSON-pointer used adding to the last array position", "data": "/foo/-", "valid": true }, { "description": "valid JSON-pointer (- used as object member name)", "data": "/foo/-/bar", "valid": true }, { "description": "valid JSON-pointer (multiple escaped characters)", "data": "/~1~0~0~1~1", "valid": true }, { "description": "valid JSON-pointer (escaped with fraction part) #1", "data": "/~1.1", "valid": true }, { "description": "valid JSON-pointer (escaped with fraction part) #2", "data": "/~0.1", "valid": true }, { "description": "not a valid JSON-pointer (URI Fragment Identifier) #1", "data": "#", "valid": false }, { "description": "not a valid JSON-pointer (URI Fragment Identifier) #2", "data": "#/", "valid": false }, { "description": "not a valid JSON-pointer (URI Fragment Identifier) #3", "data": "#a", "valid": false }, { "description": "not a valid JSON-pointer (some escaped, but not all) #1", "data": "/~0~", "valid": false }, { "description": "not a valid JSON-pointer (some escaped, but not all) #2", "data": "/~0/~", "valid": false }, { "description": "not a valid JSON-pointer (wrong escape character) #1", "data": "/~2", "valid": false }, { "description": "not a valid JSON-pointer (wrong escape character) #2", "data": "/~-1", "valid": false }, { "description": "not a valid JSON-pointer (multiple characters not escaped)", "data": "/~~", "valid": false }, { "description": "not a valid JSON-pointer (isn't empty nor starts with /) #1", "data": "a", "valid": false }, { "description": "not a valid JSON-pointer (isn't empty nor starts with /) #2", "data": "0", "valid": false }, { "description": "not a valid JSON-pointer (isn't empty nor starts with /) #3", "data": "a/a", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/format/regex.json000066400000000000000000000027461477700171100330130ustar00rootroot00000000000000[ { "description": "validation of regular expressions", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "regex" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid regular expression", "data": "([abc])+\\s+$", "valid": true }, { "description": "a regular expression with unclosed parens is invalid", "data": "^(abc]", "valid": false } ] } ] relative-json-pointer.json000066400000000000000000000060731477700171100360570ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/format[ { "description": "validation of Relative JSON Pointers (RJP)", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "relative-json-pointer" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid upwards RJP", "data": "1", "valid": true }, { "description": "a valid downwards RJP", "data": "0/foo/bar", "valid": true }, { "description": "a valid up and then down RJP, with array index", "data": "2/0/baz/1/zip", "valid": true }, { "description": "a valid RJP taking the member or index name", "data": "0#", "valid": true }, { "description": "an invalid RJP that is a valid JSON Pointer", "data": "/foo/bar", "valid": false }, { "description": "negative prefix", "data": "-1/foo/bar", "valid": false }, { "description": "explicit positive prefix", "data": "+1/foo/bar", "valid": false }, { "description": "## is not a valid json-pointer", "data": "0##", "valid": false }, { "description": "zero cannot be followed by other digits, plus json-pointer", "data": "01/a", "valid": false }, { "description": "zero cannot be followed by other digits, plus octothorpe", "data": "01#", "valid": false }, { "description": "empty string", "data": "", "valid": false }, { "description": "multi-digit integer prefix", "data": "120/foo/bar", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/format/time.json000066400000000000000000000176351477700171100326420ustar00rootroot00000000000000[ { "description": "validation of time strings", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid time string", "data": "08:30:06Z", "valid": true }, { "description": "invalid time string with extra leading zeros", "data": "008:030:006Z", "valid": false }, { "description": "invalid time string with no leading zero for single digit", "data": "8:3:6Z", "valid": false }, { "description": "hour, minute, second must be two digits", "data": "8:0030:6Z", "valid": false }, { "description": "a valid time string with leap second, Zulu", "data": "23:59:60Z", "valid": true }, { "description": "invalid leap second, Zulu (wrong hour)", "data": "22:59:60Z", "valid": false }, { "description": "invalid leap second, Zulu (wrong minute)", "data": "23:58:60Z", "valid": false }, { "description": "valid leap second, zero time-offset", "data": "23:59:60+00:00", "valid": true }, { "description": "invalid leap second, zero time-offset (wrong hour)", "data": "22:59:60+00:00", "valid": false }, { "description": "invalid leap second, zero time-offset (wrong minute)", "data": "23:58:60+00:00", "valid": false }, { "description": "valid leap second, positive time-offset", "data": "01:29:60+01:30", "valid": true }, { "description": "valid leap second, large positive time-offset", "data": "23:29:60+23:30", "valid": true }, { "description": "invalid leap second, positive time-offset (wrong hour)", "data": "23:59:60+01:00", "valid": false }, { "description": "invalid leap second, positive time-offset (wrong minute)", "data": "23:59:60+00:30", "valid": false }, { "description": "valid leap second, negative time-offset", "data": "15:59:60-08:00", "valid": true }, { "description": "valid leap second, large negative time-offset", "data": "00:29:60-23:30", "valid": true }, { "description": "invalid leap second, negative time-offset (wrong hour)", "data": "23:59:60-01:00", "valid": false }, { "description": "invalid leap second, negative time-offset (wrong minute)", "data": "23:59:60-00:30", "valid": false }, { "description": "a valid time string with second fraction", "data": "23:20:50.52Z", "valid": true }, { "description": "a valid time string with precise second fraction", "data": "08:30:06.283185Z", "valid": true }, { "description": "a valid time string with plus offset", "data": "08:30:06+00:20", "valid": true }, { "description": "a valid time string with minus offset", "data": "08:30:06-08:00", "valid": true }, { "description": "hour, minute in time-offset must be two digits", "data": "08:30:06-8:000", "valid": false }, { "description": "a valid time string with case-insensitive Z", "data": "08:30:06z", "valid": true }, { "description": "an invalid time string with invalid hour", "data": "24:00:00Z", "valid": false }, { "description": "an invalid time string with invalid minute", "data": "00:60:00Z", "valid": false }, { "description": "an invalid time string with invalid second", "data": "00:00:61Z", "valid": false }, { "description": "an invalid time string with invalid leap second (wrong hour)", "data": "22:59:60Z", "valid": false }, { "description": "an invalid time string with invalid leap second (wrong minute)", "data": "23:58:60Z", "valid": false }, { "description": "an invalid time string with invalid time numoffset hour", "data": "01:02:03+24:00", "valid": false }, { "description": "an invalid time string with invalid time numoffset minute", "data": "01:02:03+00:60", "valid": false }, { "description": "an invalid time string with invalid time with both Z and numoffset", "data": "01:02:03Z+00:30", "valid": false }, { "description": "an invalid offset indicator", "data": "08:30:06 PST", "valid": false }, { "description": "only RFC3339 not all of ISO 8601 are valid", "data": "01:01:01,1111", "valid": false }, { "description": "no time offset", "data": "12:00:00", "valid": false }, { "description": "no time offset with second fraction", "data": "12:00:00.52", "valid": false }, { "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২:00:00Z", "valid": false }, { "description": "offset not starting with plus or minus", "data": "08:30:06#00:20", "valid": false }, { "description": "contains letters", "data": "ab:cd:ef", "valid": false } ] } ] uri-reference.json000066400000000000000000000043671477700171100343560ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/format[ { "description": "validation of URI References", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "uri-reference" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid URI", "data": "http://foo.bar/?baz=qux#quux", "valid": true }, { "description": "a valid protocol-relative URI Reference", "data": "//foo.bar/?baz=qux#quux", "valid": true }, { "description": "a valid relative URI Reference", "data": "/abc", "valid": true }, { "description": "an invalid URI Reference", "data": "\\\\WINDOWS\\fileshare", "valid": false }, { "description": "a valid URI Reference", "data": "abc", "valid": true }, { "description": "a valid URI fragment", "data": "#fragment", "valid": true }, { "description": "an invalid URI fragment", "data": "#frag\\ment", "valid": false } ] } ] uri-template.json000066400000000000000000000035611477700171100342260ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/format[ { "description": "format: uri-template", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "uri-template" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid uri-template", "data": "http://example.com/dictionary/{term:1}/{term}", "valid": true }, { "description": "an invalid uri-template", "data": "http://example.com/dictionary/{term:1}/{term", "valid": false }, { "description": "a valid uri-template without variables", "data": "http://example.com/dictionary", "valid": true }, { "description": "a valid relative uri-template", "data": "dictionary/{term:1}/{term}", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/format/uri.json000066400000000000000000000111641477700171100324720ustar00rootroot00000000000000[ { "description": "validation of URIs", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "uri" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid URL with anchor tag", "data": "http://foo.bar/?baz=qux#quux", "valid": true }, { "description": "a valid URL with anchor tag and parentheses", "data": "http://foo.com/blah_(wikipedia)_blah#cite-1", "valid": true }, { "description": "a valid URL with URL-encoded stuff", "data": "http://foo.bar/?q=Test%20URL-encoded%20stuff", "valid": true }, { "description": "a valid puny-coded URL ", "data": "http://xn--nw2a.xn--j6w193g/", "valid": true }, { "description": "a valid URL with many special characters", "data": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", "valid": true }, { "description": "a valid URL based on IPv4", "data": "http://223.255.255.254", "valid": true }, { "description": "a valid URL with ftp scheme", "data": "ftp://ftp.is.co.za/rfc/rfc1808.txt", "valid": true }, { "description": "a valid URL for a simple text file", "data": "http://www.ietf.org/rfc/rfc2396.txt", "valid": true }, { "description": "a valid URL ", "data": "ldap://[2001:db8::7]/c=GB?objectClass?one", "valid": true }, { "description": "a valid mailto URI", "data": "mailto:John.Doe@example.com", "valid": true }, { "description": "a valid newsgroup URI", "data": "news:comp.infosystems.www.servers.unix", "valid": true }, { "description": "a valid tel URI", "data": "tel:+1-816-555-1212", "valid": true }, { "description": "a valid URN", "data": "urn:oasis:names:specification:docbook:dtd:xml:4.1.2", "valid": true }, { "description": "an invalid protocol-relative URI Reference", "data": "//foo.bar/?baz=qux#quux", "valid": false }, { "description": "an invalid relative URI Reference", "data": "/abc", "valid": false }, { "description": "an invalid URI", "data": "\\\\WINDOWS\\fileshare", "valid": false }, { "description": "an invalid URI though valid URI reference", "data": "abc", "valid": false }, { "description": "an invalid URI with spaces", "data": "http:// shouldfail.com", "valid": false }, { "description": "an invalid URI with spaces and missing scheme", "data": ":// should fail", "valid": false }, { "description": "an invalid URI with comma in scheme", "data": "bar,baz:foo", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/format/uuid.json000066400000000000000000000072541477700171100326460ustar00rootroot00000000000000[ { "description": "uuid format", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "format": "uuid" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "all upper-case", "data": "2EB8AA08-AA98-11EA-B4AA-73B441D16380", "valid": true }, { "description": "all lower-case", "data": "2eb8aa08-aa98-11ea-b4aa-73b441d16380", "valid": true }, { "description": "mixed case", "data": "2eb8aa08-AA98-11ea-B4Aa-73B441D16380", "valid": true }, { "description": "all zeroes is valid", "data": "00000000-0000-0000-0000-000000000000", "valid": true }, { "description": "wrong length", "data": "2eb8aa08-aa98-11ea-b4aa-73b441d1638", "valid": false }, { "description": "missing section", "data": "2eb8aa08-aa98-11ea-73b441d16380", "valid": false }, { "description": "bad characters (not hex)", "data": "2eb8aa08-aa98-11ea-b4ga-73b441d16380", "valid": false }, { "description": "no dashes", "data": "2eb8aa08aa9811eab4aa73b441d16380", "valid": false }, { "description": "too few dashes", "data": "2eb8aa08aa98-11ea-b4aa73b441d16380", "valid": false }, { "description": "too many dashes", "data": "2eb8-aa08-aa98-11ea-b4aa73b44-1d16380", "valid": false }, { "description": "dashes in the wrong spot", "data": "2eb8aa08aa9811eab4aa73b441d16380----", "valid": false }, { "description": "valid version 4", "data": "98d80576-482e-427f-8434-7f86890ab222", "valid": true }, { "description": "valid version 5", "data": "99c17cbb-656f-564a-940f-1a4568f03487", "valid": true }, { "description": "hypothetical version 6", "data": "99c17cbb-656f-664a-940f-1a4568f03487", "valid": true }, { "description": "hypothetical version 15", "data": "99c17cbb-656f-f64a-940f-1a4568f03487", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional/non-bmp-regex.json000066400000000000000000000047721477700171100330700ustar00rootroot00000000000000[ { "description": "Proper UTF-16 surrogate pair handling: pattern", "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "pattern": "^🐲*$" }, "tests": [ { "description": "matches empty", "data": "", "valid": true }, { "description": "matches single", "data": "🐲", "valid": true }, { "description": "matches two", "data": "🐲🐲", "valid": true }, { "description": "doesn't match one", "data": "🐉", "valid": false }, { "description": "doesn't match two", "data": "🐉🐉", "valid": false }, { "description": "doesn't match one ASCII", "data": "D", "valid": false }, { "description": "doesn't match two ASCII", "data": "DD", "valid": false } ] }, { "description": "Proper UTF-16 surrogate pair handling: patternProperties", "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "patternProperties": { "^🐲*$": { "type": "integer" } } }, "tests": [ { "description": "matches empty", "data": { "": 1 }, "valid": true }, { "description": "matches single", "data": { "🐲": 1 }, "valid": true }, { "description": "matches two", "data": { "🐲🐲": 1 }, "valid": true }, { "description": "doesn't match one", "data": { "🐲": "hello" }, "valid": false }, { "description": "doesn't match two", "data": { "🐲🐲": "hello" }, "valid": false } ] } ] refOfUnknownKeyword.json000066400000000000000000000035731477700171100343170ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/optional[ { "description": "reference of a root arbitrary keyword ", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "unknown-keyword": {"type": "integer"}, "properties": { "bar": {"$ref": "#/unknown-keyword"} } }, "tests": [ { "description": "match", "data": {"bar": 3}, "valid": true }, { "description": "mismatch", "data": {"bar": true}, "valid": false } ] }, { "description": "reference of an arbitrary keyword of a sub-schema", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": { "foo": {"unknown-keyword": {"type": "integer"}}, "bar": {"$ref": "#/properties/foo/unknown-keyword"} } }, "tests": [ { "description": "match", "data": {"bar": 3}, "valid": true }, { "description": "mismatch", "data": {"bar": true}, "valid": false } ] }, { "description": "reference internals of known non-applicator", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "/base", "examples": [ { "type": "string" } ], "$ref": "#/examples/0" }, "tests": [ { "description": "match", "data": "a string", "valid": true }, { "description": "mismatch", "data": 42, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/pattern.json000066400000000000000000000032671477700171100302400ustar00rootroot00000000000000[ { "description": "pattern validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "pattern": "^a*$" }, "tests": [ { "description": "a matching pattern is valid", "data": "aaa", "valid": true }, { "description": "a non-matching pattern is invalid", "data": "abc", "valid": false }, { "description": "ignores booleans", "data": true, "valid": true }, { "description": "ignores integers", "data": 123, "valid": true }, { "description": "ignores floats", "data": 1.0, "valid": true }, { "description": "ignores objects", "data": {}, "valid": true }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores null", "data": null, "valid": true } ] }, { "description": "pattern is not anchored", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "pattern": "a+" }, "tests": [ { "description": "matches a substring", "data": "xxaayy", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/patternProperties.json000066400000000000000000000126151477700171100323120ustar00rootroot00000000000000[ { "description": "patternProperties validates properties matching a regex", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "patternProperties": { "f.*o": {"type": "integer"} } }, "tests": [ { "description": "a single valid match is valid", "data": {"foo": 1}, "valid": true }, { "description": "multiple valid matches is valid", "data": {"foo": 1, "foooooo" : 2}, "valid": true }, { "description": "a single invalid match is invalid", "data": {"foo": "bar", "fooooo": 2}, "valid": false }, { "description": "multiple invalid matches is invalid", "data": {"foo": "bar", "foooooo" : "baz"}, "valid": false }, { "description": "ignores arrays", "data": ["foo"], "valid": true }, { "description": "ignores strings", "data": "foo", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "multiple simultaneous patternProperties are validated", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "patternProperties": { "a*": {"type": "integer"}, "aaa*": {"maximum": 20} } }, "tests": [ { "description": "a single valid match is valid", "data": {"a": 21}, "valid": true }, { "description": "a simultaneous match is valid", "data": {"aaaa": 18}, "valid": true }, { "description": "multiple matches is valid", "data": {"a": 21, "aaaa": 18}, "valid": true }, { "description": "an invalid due to one is invalid", "data": {"a": "bar"}, "valid": false }, { "description": "an invalid due to the other is invalid", "data": {"aaaa": 31}, "valid": false }, { "description": "an invalid due to both is invalid", "data": {"aaa": "foo", "aaaa": 31}, "valid": false } ] }, { "description": "regexes are not anchored by default and are case sensitive", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "patternProperties": { "[0-9]{2,}": { "type": "boolean" }, "X_": { "type": "string" } } }, "tests": [ { "description": "non recognized members are ignored", "data": { "answer 1": "42" }, "valid": true }, { "description": "recognized members are accounted for", "data": { "a31b": null }, "valid": false }, { "description": "regexes are case sensitive", "data": { "a_x_3": 3 }, "valid": true }, { "description": "regexes are case sensitive, 2", "data": { "a_X_3": 3 }, "valid": false } ] }, { "description": "patternProperties with boolean schemas", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "patternProperties": { "f.*": true, "b.*": false } }, "tests": [ { "description": "object with property matching schema true is valid", "data": {"foo": 1}, "valid": true }, { "description": "object with property matching schema false is invalid", "data": {"bar": 2}, "valid": false }, { "description": "object with both properties is invalid", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "object with a property matching both true and false is invalid", "data": {"foobar":1}, "valid": false }, { "description": "empty object is valid", "data": {}, "valid": true } ] }, { "description": "patternProperties with null valued instance properties", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "patternProperties": { "^.*bar$": {"type": "null"} } }, "tests": [ { "description": "allows null values", "data": {"foobar": null}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/prefixItems.json000066400000000000000000000055451477700171100310630ustar00rootroot00000000000000[ { "description": "a schema given for prefixItems", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "prefixItems": [ {"type": "integer"}, {"type": "string"} ] }, "tests": [ { "description": "correct types", "data": [ 1, "foo" ], "valid": true }, { "description": "wrong types", "data": [ "foo", 1 ], "valid": false }, { "description": "incomplete array of items", "data": [ 1 ], "valid": true }, { "description": "array with additional items", "data": [ 1, "foo", true ], "valid": true }, { "description": "empty array", "data": [ ], "valid": true }, { "description": "JavaScript pseudo-array is valid", "data": { "0": "invalid", "1": "valid", "length": 2 }, "valid": true } ] }, { "description": "prefixItems with boolean schemas", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "prefixItems": [true, false] }, "tests": [ { "description": "array with one item is valid", "data": [ 1 ], "valid": true }, { "description": "array with two items is invalid", "data": [ 1, "foo" ], "valid": false }, { "description": "empty array is valid", "data": [], "valid": true } ] }, { "description": "additional items are allowed by default", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "prefixItems": [{"type": "integer"}] }, "tests": [ { "description": "only the first item is validated", "data": [1, "foo", false], "valid": true } ] }, { "description": "prefixItems with null instance elements", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "prefixItems": [ { "type": "null" } ] }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/properties.json000066400000000000000000000170411477700171100307520ustar00rootroot00000000000000[ { "description": "object properties validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": { "foo": {"type": "integer"}, "bar": {"type": "string"} } }, "tests": [ { "description": "both properties present and valid is valid", "data": {"foo": 1, "bar": "baz"}, "valid": true }, { "description": "one property invalid is invalid", "data": {"foo": 1, "bar": {}}, "valid": false }, { "description": "both properties invalid is invalid", "data": {"foo": [], "bar": {}}, "valid": false }, { "description": "doesn't invalidate other properties", "data": {"quux": []}, "valid": true }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "properties, patternProperties, additionalProperties interaction", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": { "foo": {"type": "array", "maxItems": 3}, "bar": {"type": "array"} }, "patternProperties": {"f.o": {"minItems": 2}}, "additionalProperties": {"type": "integer"} }, "tests": [ { "description": "property validates property", "data": {"foo": [1, 2]}, "valid": true }, { "description": "property invalidates property", "data": {"foo": [1, 2, 3, 4]}, "valid": false }, { "description": "patternProperty invalidates property", "data": {"foo": []}, "valid": false }, { "description": "patternProperty validates nonproperty", "data": {"fxo": [1, 2]}, "valid": true }, { "description": "patternProperty invalidates nonproperty", "data": {"fxo": []}, "valid": false }, { "description": "additionalProperty ignores property", "data": {"bar": []}, "valid": true }, { "description": "additionalProperty validates others", "data": {"quux": 3}, "valid": true }, { "description": "additionalProperty invalidates others", "data": {"quux": "foo"}, "valid": false } ] }, { "description": "properties with boolean schema", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": { "foo": true, "bar": false } }, "tests": [ { "description": "no property present is valid", "data": {}, "valid": true }, { "description": "only 'true' property present is valid", "data": {"foo": 1}, "valid": true }, { "description": "only 'false' property present is invalid", "data": {"bar": 2}, "valid": false }, { "description": "both properties present is invalid", "data": {"foo": 1, "bar": 2}, "valid": false } ] }, { "description": "properties with escaped characters", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": { "foo\nbar": {"type": "number"}, "foo\"bar": {"type": "number"}, "foo\\bar": {"type": "number"}, "foo\rbar": {"type": "number"}, "foo\tbar": {"type": "number"}, "foo\fbar": {"type": "number"} } }, "tests": [ { "description": "object with all numbers is valid", "data": { "foo\nbar": 1, "foo\"bar": 1, "foo\\bar": 1, "foo\rbar": 1, "foo\tbar": 1, "foo\fbar": 1 }, "valid": true }, { "description": "object with strings is invalid", "data": { "foo\nbar": "1", "foo\"bar": "1", "foo\\bar": "1", "foo\rbar": "1", "foo\tbar": "1", "foo\fbar": "1" }, "valid": false } ] }, { "description": "properties with null valued instance properties", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": { "foo": {"type": "null"} } }, "tests": [ { "description": "allows null values", "data": {"foo": null}, "valid": true } ] }, { "description": "properties whose names are Javascript object property names", "comment": "Ensure JS implementations don't universally consider e.g. __proto__ to always be present in an object.", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": { "__proto__": {"type": "number"}, "toString": { "properties": { "length": { "type": "string" } } }, "constructor": {"type": "number"} } }, "tests": [ { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true }, { "description": "none of the properties mentioned", "data": {}, "valid": true }, { "description": "__proto__ not valid", "data": { "__proto__": "foo" }, "valid": false }, { "description": "toString not valid", "data": { "toString": { "length": 37 } }, "valid": false }, { "description": "constructor not valid", "data": { "constructor": { "length": 37 } }, "valid": false }, { "description": "all present and valid", "data": { "__proto__": 12, "toString": { "length": "foo" }, "constructor": 37 }, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/propertyDependencies.json000066400000000000000000000111301477700171100327420ustar00rootroot00000000000000[ { "description": "propertyDependencies doesn't act on non-objects", "schema": { "propertyDependencies": { "foo": {"bar": false} } }, "tests": [ { "description": "ignores booleans", "data": true, "valid": true }, { "description": "ignores integers", "data": 123, "valid": true }, { "description": "ignores floats", "data": 1.0, "valid": true }, { "description": "ignores strings", "data": "abc", "valid": true }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores null", "data": null, "valid": true } ] }, { "description": "propertyDependencies doesn't act on non-string property values", "schema": { "propertyDependencies": { "foo": {"bar": false} } }, "tests": [ { "description": "ignores booleans", "data": {"foo": false}, "valid": true }, { "description": "ignores integers", "data": {"foo": 2}, "valid": true }, { "description": "ignores floats", "data": {"foo": 1.1}, "valid": true }, { "description": "ignores objects", "data": {"foo": {}}, "valid": true }, { "description": "ignores objects wth a key of the expected value", "data": {"foo": {"bar": "baz"}}, "valid": true }, { "description": "ignores objects with the expected value nested in structure", "data": {"foo": {"baz": "bar"}}, "valid": true }, { "description": "ignores arrays", "data": {"foo": []}, "valid": true }, { "description": "ignores null", "data": {"foo": null}, "valid": true } ] }, { "description": "multiple options selects the right one", "schema": { "propertyDependencies": { "foo": { "bar": { "minProperties": 2, "maxProperties": 2 }, "baz": {"maxProperties": 1}, "qux": true, "quux": false } } }, "tests": [ { "description": "bar with exactly 2 properties is valid", "data": { "foo": "bar", "other-foo": "other-bar" }, "valid": true }, { "description": "bar with more than 2 properties is invalid", "data": { "foo": "bar", "other-foo": "other-bar", "too": "many" }, "valid": false }, { "description": "bar with fewer than 2 properties is invalid", "data": {"foo": "bar"}, "valid": false }, { "description": "baz alone is valid", "data": {"foo": "baz"}, "valid": true }, { "description": "baz with other properties is invalid", "data": { "foo": "baz", "other-foo": "other-bar" }, "valid": false }, { "description": "anything allowed with qux", "data": { "foo": "qux", "blah": ["some other property"], "more": "properties" }, "valid": true }, { "description": "quux is disallowed", "data": { "foo": "quux" }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/propertyNames.json000066400000000000000000000045201477700171100314240ustar00rootroot00000000000000[ { "description": "propertyNames validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "propertyNames": {"maxLength": 3} }, "tests": [ { "description": "all property names valid", "data": { "f": {}, "foo": {} }, "valid": true }, { "description": "some property names invalid", "data": { "foo": {}, "foobar": {} }, "valid": false }, { "description": "object without properties is valid", "data": {}, "valid": true }, { "description": "ignores arrays", "data": [1, 2, 3, 4], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "propertyNames with boolean schema true", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "propertyNames": true }, "tests": [ { "description": "object with any properties is valid", "data": {"foo": 1}, "valid": true }, { "description": "empty object is valid", "data": {}, "valid": true } ] }, { "description": "propertyNames with boolean schema false", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "propertyNames": false }, "tests": [ { "description": "object with any properties is invalid", "data": {"foo": 1}, "valid": false }, { "description": "empty object is valid", "data": {}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/ref.json000066400000000000000000000776671477700171100273560ustar00rootroot00000000000000[ { "description": "root pointer ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": { "foo": {"$ref": "#"} }, "additionalProperties": false }, "tests": [ { "description": "match", "data": {"foo": false}, "valid": true }, { "description": "recursive match", "data": {"foo": {"foo": false}}, "valid": true }, { "description": "mismatch", "data": {"bar": false}, "valid": false }, { "description": "recursive mismatch", "data": {"foo": {"bar": false}}, "valid": false } ] }, { "description": "relative pointer ref to object", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": { "foo": {"type": "integer"}, "bar": {"$ref": "#/properties/foo"} } }, "tests": [ { "description": "match", "data": {"bar": 3}, "valid": true }, { "description": "mismatch", "data": {"bar": true}, "valid": false } ] }, { "description": "relative pointer ref to array", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "prefixItems": [ {"type": "integer"}, {"$ref": "#/prefixItems/0"} ] }, "tests": [ { "description": "match array", "data": [1, 2], "valid": true }, { "description": "mismatch array", "data": [1, "foo"], "valid": false } ] }, { "description": "escaped pointer ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "tilde~field": {"type": "integer"}, "slash/field": {"type": "integer"}, "percent%field": {"type": "integer"} }, "properties": { "tilde": {"$ref": "#/$defs/tilde~0field"}, "slash": {"$ref": "#/$defs/slash~1field"}, "percent": {"$ref": "#/$defs/percent%25field"} } }, "tests": [ { "description": "slash invalid", "data": {"slash": "aoeu"}, "valid": false }, { "description": "tilde invalid", "data": {"tilde": "aoeu"}, "valid": false }, { "description": "percent invalid", "data": {"percent": "aoeu"}, "valid": false }, { "description": "slash valid", "data": {"slash": 123}, "valid": true }, { "description": "tilde valid", "data": {"tilde": 123}, "valid": true }, { "description": "percent valid", "data": {"percent": 123}, "valid": true } ] }, { "description": "nested refs", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "a": {"type": "integer"}, "b": {"$ref": "#/$defs/a"}, "c": {"$ref": "#/$defs/b"} }, "$ref": "#/$defs/c" }, "tests": [ { "description": "nested ref valid", "data": 5, "valid": true }, { "description": "nested ref invalid", "data": "a", "valid": false } ] }, { "description": "ref applies alongside sibling keywords", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "reffed": { "type": "array" } }, "properties": { "foo": { "$ref": "#/$defs/reffed", "maxItems": 2 } } }, "tests": [ { "description": "ref valid, maxItems valid", "data": { "foo": [] }, "valid": true }, { "description": "ref valid, maxItems invalid", "data": { "foo": [1, 2, 3] }, "valid": false }, { "description": "ref invalid", "data": { "foo": "string" }, "valid": false } ] }, { "description": "remote ref, containing refs itself", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "https://json-schema.org/draft/next/schema" }, "tests": [ { "description": "remote ref valid", "data": {"minLength": 1}, "valid": true }, { "description": "remote ref invalid", "data": {"minLength": -1}, "valid": false } ] }, { "description": "property named $ref that is not a reference", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": { "$ref": {"type": "string"} } }, "tests": [ { "description": "property named $ref valid", "data": {"$ref": "a"}, "valid": true }, { "description": "property named $ref invalid", "data": {"$ref": 2}, "valid": false } ] }, { "description": "property named $ref, containing an actual $ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": { "$ref": {"$ref": "#/$defs/is-string"} }, "$defs": { "is-string": { "type": "string" } } }, "tests": [ { "description": "property named $ref valid", "data": {"$ref": "a"}, "valid": true }, { "description": "property named $ref invalid", "data": {"$ref": 2}, "valid": false } ] }, { "description": "$ref to boolean schema true", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "#/$defs/bool", "$defs": { "bool": true } }, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "$ref to boolean schema false", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "#/$defs/bool", "$defs": { "bool": false } }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "Recursive references between schemas", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://localhost:1234/draft-next/tree", "description": "tree of nodes", "type": "object", "properties": { "meta": {"type": "string"}, "nodes": { "type": "array", "items": {"$ref": "node"} } }, "required": ["meta", "nodes"], "$defs": { "node": { "$id": "http://localhost:1234/draft-next/node", "description": "node", "type": "object", "properties": { "value": {"type": "number"}, "subtree": {"$ref": "tree"} }, "required": ["value"] } } }, "tests": [ { "description": "valid tree", "data": { "meta": "root", "nodes": [ { "value": 1, "subtree": { "meta": "child", "nodes": [ {"value": 1.1}, {"value": 1.2} ] } }, { "value": 2, "subtree": { "meta": "child", "nodes": [ {"value": 2.1}, {"value": 2.2} ] } } ] }, "valid": true }, { "description": "invalid tree", "data": { "meta": "root", "nodes": [ { "value": 1, "subtree": { "meta": "child", "nodes": [ {"value": "string is invalid"}, {"value": 1.2} ] } }, { "value": 2, "subtree": { "meta": "child", "nodes": [ {"value": 2.1}, {"value": 2.2} ] } } ] }, "valid": false } ] }, { "description": "refs with quote", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": { "foo\"bar": {"$ref": "#/$defs/foo%22bar"} }, "$defs": { "foo\"bar": {"type": "number"} } }, "tests": [ { "description": "object with numbers is valid", "data": { "foo\"bar": 1 }, "valid": true }, { "description": "object with strings is invalid", "data": { "foo\"bar": "1" }, "valid": false } ] }, { "description": "ref creates new scope when adjacent to keywords", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "A": { "unevaluatedProperties": false } }, "properties": { "prop1": { "type": "string" } }, "$ref": "#/$defs/A" }, "tests": [ { "description": "referenced subschema doesn't see annotations from properties", "data": { "prop1": "match" }, "valid": false } ] }, { "description": "naive replacement of $ref with its destination is not correct", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "a_string": { "type": "string" } }, "enum": [ { "$ref": "#/$defs/a_string" } ] }, "tests": [ { "description": "do not evaluate the $ref inside the enum, matching any string", "data": "this is a string", "valid": false }, { "description": "do not evaluate the $ref inside the enum, definition exact match", "data": { "type": "string" }, "valid": false }, { "description": "match the enum exactly", "data": { "$ref": "#/$defs/a_string" }, "valid": true } ] }, { "description": "refs with relative uris and defs", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://example.com/schema-relative-uri-defs1.json", "properties": { "foo": { "$id": "schema-relative-uri-defs2.json", "$defs": { "inner": { "properties": { "bar": { "type": "string" } } } }, "$ref": "#/$defs/inner" } }, "$ref": "schema-relative-uri-defs2.json" }, "tests": [ { "description": "invalid on inner field", "data": { "foo": { "bar": 1 }, "bar": "a" }, "valid": false }, { "description": "invalid on outer field", "data": { "foo": { "bar": "a" }, "bar": 1 }, "valid": false }, { "description": "valid on both fields", "data": { "foo": { "bar": "a" }, "bar": "a" }, "valid": true } ] }, { "description": "relative refs with absolute uris and defs", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://example.com/schema-refs-absolute-uris-defs1.json", "properties": { "foo": { "$id": "http://example.com/schema-refs-absolute-uris-defs2.json", "$defs": { "inner": { "properties": { "bar": { "type": "string" } } } }, "$ref": "#/$defs/inner" } }, "$ref": "schema-refs-absolute-uris-defs2.json" }, "tests": [ { "description": "invalid on inner field", "data": { "foo": { "bar": 1 }, "bar": "a" }, "valid": false }, { "description": "invalid on outer field", "data": { "foo": { "bar": "a" }, "bar": 1 }, "valid": false }, { "description": "valid on both fields", "data": { "foo": { "bar": "a" }, "bar": "a" }, "valid": true } ] }, { "description": "$id must be resolved against nearest parent, not just immediate parent", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://example.com/a.json", "$defs": { "x": { "$id": "http://example.com/b/c.json", "not": { "$defs": { "y": { "$id": "d.json", "type": "number" } } } } }, "allOf": [ { "$ref": "http://example.com/b/d.json" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] }, { "description": "order of evaluation: $id and $ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$comment": "$id must be evaluated before $ref to get the proper $ref destination", "$id": "https://example.com/draft/next/ref-and-id1/base.json", "$ref": "int.json", "$defs": { "bigint": { "$comment": "canonical uri: https://example.com/ref-and-id1/int.json", "$id": "int.json", "maximum": 10 }, "smallint": { "$comment": "canonical uri: https://example.com/ref-and-id1-int.json", "$id": "/draft/next/ref-and-id1-int.json", "maximum": 2 } } }, "tests": [ { "description": "data is valid against first definition", "data": 5, "valid": true }, { "description": "data is invalid against first definition", "data": 50, "valid": false } ] }, { "description": "order of evaluation: $id and $anchor and $ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$comment": "$id must be evaluated before $ref to get the proper $ref destination", "$id": "https://example.com/draft/next/ref-and-id2/base.json", "$ref": "#bigint", "$defs": { "bigint": { "$comment": "canonical uri: https://example.com/ref-and-id2/base.json#/$defs/bigint; another valid uri for this location: https://example.com/ref-and-id2/base.json#bigint", "$anchor": "bigint", "maximum": 10 }, "smallint": { "$comment": "canonical uri: https://example.com/ref-and-id2#/$defs/smallint; another valid uri for this location: https://example.com/ref-and-id2/#bigint", "$id": "/draft/next/ref-and-id2/", "$anchor": "bigint", "maximum": 2 } } }, "tests": [ { "description": "data is valid against first definition", "data": 5, "valid": true }, { "description": "data is invalid against first definition", "data": 50, "valid": false } ] }, { "description": "simple URN base URI with $ref via the URN", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$comment": "URIs do not have to have HTTP(s) schemes", "$id": "urn:uuid:deadbeef-1234-ffff-ffff-4321feebdaed", "minimum": 30, "properties": { "foo": {"$ref": "urn:uuid:deadbeef-1234-ffff-ffff-4321feebdaed"} } }, "tests": [ { "description": "valid under the URN IDed schema", "data": {"foo": 37}, "valid": true }, { "description": "invalid under the URN IDed schema", "data": {"foo": 12}, "valid": false } ] }, { "description": "simple URN base URI with JSON pointer", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$comment": "URIs do not have to have HTTP(s) schemes", "$id": "urn:uuid:deadbeef-1234-00ff-ff00-4321feebdaed", "properties": { "foo": {"$ref": "#/$defs/bar"} }, "$defs": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with NSS", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$comment": "RFC 8141 §2.2", "$id": "urn:example:1/406/47452/2", "properties": { "foo": {"$ref": "#/$defs/bar"} }, "$defs": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with r-component", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$comment": "RFC 8141 §2.3.1", "$id": "urn:example:foo-bar-baz-qux?+CCResolve:cc=uk", "properties": { "foo": {"$ref": "#/$defs/bar"} }, "$defs": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with q-component", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$comment": "RFC 8141 §2.3.2", "$id": "urn:example:weather?=op=map&lat=39.56&lon=-104.85&datetime=1969-07-21T02:56:15Z", "properties": { "foo": {"$ref": "#/$defs/bar"} }, "$defs": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with f-component", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$comment": "RFC 8141 §2.3.3, but we don't allow fragments", "$ref": "https://json-schema.org/draft/next/schema" }, "tests": [ { "description": "is invalid", "data": {"$id": "urn:example:foo-bar-baz-qux#somepart"}, "valid": false } ] }, { "description": "URN base URI with URN and JSON pointer ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "urn:uuid:deadbeef-1234-0000-0000-4321feebdaed", "properties": { "foo": {"$ref": "urn:uuid:deadbeef-1234-0000-0000-4321feebdaed#/$defs/bar"} }, "$defs": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with URN and anchor ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "urn:uuid:deadbeef-1234-ff00-00ff-4321feebdaed", "properties": { "foo": {"$ref": "urn:uuid:deadbeef-1234-ff00-00ff-4321feebdaed#something"} }, "$defs": { "bar": { "$anchor": "something", "type": "string" } } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN ref with nested pointer ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "urn:uuid:deadbeef-4321-ffff-ffff-1234feebdaed", "$defs": { "foo": { "$id": "urn:uuid:deadbeef-4321-ffff-ffff-1234feebdaed", "$defs": {"bar": {"type": "string"}}, "$ref": "#/$defs/bar" } } }, "tests": [ { "description": "a string is valid", "data": "bar", "valid": true }, { "description": "a non-string is invalid", "data": 12, "valid": false } ] }, { "description": "ref to if", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "http://example.com/ref/if", "if": { "$id": "http://example.com/ref/if", "type": "integer" } }, "tests": [ { "description": "a non-integer is invalid due to the $ref", "data": "foo", "valid": false }, { "description": "an integer is valid", "data": 12, "valid": true } ] }, { "description": "ref to then", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "http://example.com/ref/then", "then": { "$id": "http://example.com/ref/then", "type": "integer" } }, "tests": [ { "description": "a non-integer is invalid due to the $ref", "data": "foo", "valid": false }, { "description": "an integer is valid", "data": 12, "valid": true } ] }, { "description": "ref to else", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "http://example.com/ref/else", "else": { "$id": "http://example.com/ref/else", "type": "integer" } }, "tests": [ { "description": "a non-integer is invalid due to the $ref", "data": "foo", "valid": false }, { "description": "an integer is valid", "data": 12, "valid": true } ] }, { "description": "ref with absolute-path-reference", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://example.com/ref/absref.json", "$defs": { "a": { "$id": "http://example.com/ref/absref/foobar.json", "type": "number" }, "b": { "$id": "http://example.com/absref/foobar.json", "type": "string" } }, "$ref": "/absref/foobar.json" }, "tests": [ { "description": "a string is valid", "data": "foo", "valid": true }, { "description": "an integer is invalid", "data": 12, "valid": false } ] }, { "description": "$id with file URI still resolves pointers - *nix", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "file:///folder/file.json", "$defs": { "foo": { "type": "number" } }, "$ref": "#/$defs/foo" }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] }, { "description": "$id with file URI still resolves pointers - windows", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "file:///c:/folder/file.json", "$defs": { "foo": { "type": "number" } }, "$ref": "#/$defs/foo" }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] }, { "description": "empty tokens in $ref json-pointer", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "": { "$defs": { "": { "type": "number" } } } }, "allOf": [ { "$ref": "#/$defs//$defs/" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/refRemote.json000066400000000000000000000237461477700171100305170ustar00rootroot00000000000000[ { "description": "remote ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "http://localhost:1234/draft-next/integer.json" }, "tests": [ { "description": "remote ref valid", "data": 1, "valid": true }, { "description": "remote ref invalid", "data": "a", "valid": false } ] }, { "description": "fragment within remote ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "http://localhost:1234/draft-next/subSchemas.json#/$defs/integer" }, "tests": [ { "description": "remote fragment valid", "data": 1, "valid": true }, { "description": "remote fragment invalid", "data": "a", "valid": false } ] }, { "description": "anchor within remote ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "http://localhost:1234/draft-next/locationIndependentIdentifier.json#foo" }, "tests": [ { "description": "remote anchor valid", "data": 1, "valid": true }, { "description": "remote anchor invalid", "data": "a", "valid": false } ] }, { "description": "ref within remote ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "http://localhost:1234/draft-next/subSchemas.json#/$defs/refToInteger" }, "tests": [ { "description": "ref within ref valid", "data": 1, "valid": true }, { "description": "ref within ref invalid", "data": "a", "valid": false } ] }, { "description": "base URI change", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://localhost:1234/draft-next/", "items": { "$id": "baseUriChange/", "items": {"$ref": "folderInteger.json"} } }, "tests": [ { "description": "base URI change ref valid", "data": [[1]], "valid": true }, { "description": "base URI change ref invalid", "data": [["a"]], "valid": false } ] }, { "description": "base URI change - change folder", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://localhost:1234/draft-next/scope_change_defs1.json", "type" : "object", "properties": {"list": {"$ref": "baseUriChangeFolder/"}}, "$defs": { "baz": { "$id": "baseUriChangeFolder/", "type": "array", "items": {"$ref": "folderInteger.json"} } } }, "tests": [ { "description": "number is valid", "data": {"list": [1]}, "valid": true }, { "description": "string is invalid", "data": {"list": ["a"]}, "valid": false } ] }, { "description": "base URI change - change folder in subschema", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://localhost:1234/draft-next/scope_change_defs2.json", "type" : "object", "properties": {"list": {"$ref": "baseUriChangeFolderInSubschema/#/$defs/bar"}}, "$defs": { "baz": { "$id": "baseUriChangeFolderInSubschema/", "$defs": { "bar": { "type": "array", "items": {"$ref": "folderInteger.json"} } } } } }, "tests": [ { "description": "number is valid", "data": {"list": [1]}, "valid": true }, { "description": "string is invalid", "data": {"list": ["a"]}, "valid": false } ] }, { "description": "root ref in remote ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://localhost:1234/draft-next/object", "type": "object", "properties": { "name": {"$ref": "name-defs.json#/$defs/orNull"} } }, "tests": [ { "description": "string is valid", "data": { "name": "foo" }, "valid": true }, { "description": "null is valid", "data": { "name": null }, "valid": true }, { "description": "object is invalid", "data": { "name": { "name": null } }, "valid": false } ] }, { "description": "remote ref with ref to defs", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://localhost:1234/draft-next/schema-remote-ref-ref-defs1.json", "$ref": "ref-and-defs.json" }, "tests": [ { "description": "invalid", "data": { "bar": 1 }, "valid": false }, { "description": "valid", "data": { "bar": "a" }, "valid": true } ] }, { "description": "Location-independent identifier in remote ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "http://localhost:1234/draft-next/locationIndependentIdentifier.json#/$defs/refToInteger" }, "tests": [ { "description": "integer is valid", "data": 1, "valid": true }, { "description": "string is invalid", "data": "foo", "valid": false } ] }, { "description": "retrieved nested refs resolve relative to their URI not $id", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://localhost:1234/draft-next/some-id", "properties": { "name": {"$ref": "nested/foo-ref-string.json"} } }, "tests": [ { "description": "number is invalid", "data": { "name": {"foo": 1} }, "valid": false }, { "description": "string is valid", "data": { "name": {"foo": "a"} }, "valid": true } ] }, { "description": "remote HTTP ref with different $id", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "http://localhost:1234/different-id-ref-string.json" }, "tests": [ { "description": "number is invalid", "data": 1, "valid": false }, { "description": "string is valid", "data": "foo", "valid": true } ] }, { "description": "remote HTTP ref with different URN $id", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "http://localhost:1234/urn-ref-string.json" }, "tests": [ { "description": "number is invalid", "data": 1, "valid": false }, { "description": "string is valid", "data": "foo", "valid": true } ] }, { "description": "remote HTTP ref with nested absolute ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "http://localhost:1234/nested-absolute-ref-to-string.json" }, "tests": [ { "description": "number is invalid", "data": 1, "valid": false }, { "description": "string is valid", "data": "foo", "valid": true } ] }, { "description": "$ref to $ref finds detached $anchor", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "http://localhost:1234/draft-next/detached-ref.json#/$defs/foo" }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/required.json000066400000000000000000000110041477700171100303670ustar00rootroot00000000000000[ { "description": "required validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": { "foo": {}, "bar": {} }, "required": ["foo"] }, "tests": [ { "description": "present required property is valid", "data": {"foo": 1}, "valid": true }, { "description": "non-present required property is invalid", "data": {"bar": 1}, "valid": false }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores strings", "data": "", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "required default validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": { "foo": {} } }, "tests": [ { "description": "not required by default", "data": {}, "valid": true } ] }, { "description": "required with empty array", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": { "foo": {} }, "required": [] }, "tests": [ { "description": "property not required", "data": {}, "valid": true } ] }, { "description": "required with escaped characters", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "required": [ "foo\nbar", "foo\"bar", "foo\\bar", "foo\rbar", "foo\tbar", "foo\fbar" ] }, "tests": [ { "description": "object with all properties present is valid", "data": { "foo\nbar": 1, "foo\"bar": 1, "foo\\bar": 1, "foo\rbar": 1, "foo\tbar": 1, "foo\fbar": 1 }, "valid": true }, { "description": "object with some properties missing is invalid", "data": { "foo\nbar": "1", "foo\"bar": "1" }, "valid": false } ] }, { "description": "required properties whose names are Javascript object property names", "comment": "Ensure JS implementations don't universally consider e.g. __proto__ to always be present in an object.", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "required": ["__proto__", "toString", "constructor"] }, "tests": [ { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true }, { "description": "none of the properties mentioned", "data": {}, "valid": false }, { "description": "__proto__ present", "data": { "__proto__": "foo" }, "valid": false }, { "description": "toString present", "data": { "toString": { "length": 37 } }, "valid": false }, { "description": "constructor present", "data": { "constructor": { "length": 37 } }, "valid": false }, { "description": "all present", "data": { "__proto__": 12, "toString": { "length": "foo" }, "constructor": 37 }, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/type.json000066400000000000000000000337741477700171100275520ustar00rootroot00000000000000[ { "description": "integer type matches integers", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "integer" }, "tests": [ { "description": "an integer is an integer", "data": 1, "valid": true }, { "description": "a float with zero fractional part is an integer", "data": 1.0, "valid": true }, { "description": "a float is not an integer", "data": 1.1, "valid": false }, { "description": "a string is not an integer", "data": "foo", "valid": false }, { "description": "a string is still not an integer, even if it looks like one", "data": "1", "valid": false }, { "description": "an object is not an integer", "data": {}, "valid": false }, { "description": "an array is not an integer", "data": [], "valid": false }, { "description": "a boolean is not an integer", "data": true, "valid": false }, { "description": "null is not an integer", "data": null, "valid": false } ] }, { "description": "number type matches numbers", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "number" }, "tests": [ { "description": "an integer is a number", "data": 1, "valid": true }, { "description": "a float with zero fractional part is a number (and an integer)", "data": 1.0, "valid": true }, { "description": "a float is a number", "data": 1.1, "valid": true }, { "description": "a string is not a number", "data": "foo", "valid": false }, { "description": "a string is still not a number, even if it looks like one", "data": "1", "valid": false }, { "description": "an object is not a number", "data": {}, "valid": false }, { "description": "an array is not a number", "data": [], "valid": false }, { "description": "a boolean is not a number", "data": true, "valid": false }, { "description": "null is not a number", "data": null, "valid": false } ] }, { "description": "string type matches strings", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "string" }, "tests": [ { "description": "1 is not a string", "data": 1, "valid": false }, { "description": "a float is not a string", "data": 1.1, "valid": false }, { "description": "a string is a string", "data": "foo", "valid": true }, { "description": "a string is still a string, even if it looks like a number", "data": "1", "valid": true }, { "description": "an empty string is still a string", "data": "", "valid": true }, { "description": "an object is not a string", "data": {}, "valid": false }, { "description": "an array is not a string", "data": [], "valid": false }, { "description": "a boolean is not a string", "data": true, "valid": false }, { "description": "null is not a string", "data": null, "valid": false } ] }, { "description": "object type matches objects", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object" }, "tests": [ { "description": "an integer is not an object", "data": 1, "valid": false }, { "description": "a float is not an object", "data": 1.1, "valid": false }, { "description": "a string is not an object", "data": "foo", "valid": false }, { "description": "an object is an object", "data": {}, "valid": true }, { "description": "an array is not an object", "data": [], "valid": false }, { "description": "a boolean is not an object", "data": true, "valid": false }, { "description": "null is not an object", "data": null, "valid": false } ] }, { "description": "array type matches arrays", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "array" }, "tests": [ { "description": "an integer is not an array", "data": 1, "valid": false }, { "description": "a float is not an array", "data": 1.1, "valid": false }, { "description": "a string is not an array", "data": "foo", "valid": false }, { "description": "an object is not an array", "data": {}, "valid": false }, { "description": "an array is an array", "data": [], "valid": true }, { "description": "a boolean is not an array", "data": true, "valid": false }, { "description": "null is not an array", "data": null, "valid": false } ] }, { "description": "boolean type matches booleans", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "boolean" }, "tests": [ { "description": "an integer is not a boolean", "data": 1, "valid": false }, { "description": "zero is not a boolean", "data": 0, "valid": false }, { "description": "a float is not a boolean", "data": 1.1, "valid": false }, { "description": "a string is not a boolean", "data": "foo", "valid": false }, { "description": "an empty string is not a boolean", "data": "", "valid": false }, { "description": "an object is not a boolean", "data": {}, "valid": false }, { "description": "an array is not a boolean", "data": [], "valid": false }, { "description": "true is a boolean", "data": true, "valid": true }, { "description": "false is a boolean", "data": false, "valid": true }, { "description": "null is not a boolean", "data": null, "valid": false } ] }, { "description": "null type matches only the null object", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "null" }, "tests": [ { "description": "an integer is not null", "data": 1, "valid": false }, { "description": "a float is not null", "data": 1.1, "valid": false }, { "description": "zero is not null", "data": 0, "valid": false }, { "description": "a string is not null", "data": "foo", "valid": false }, { "description": "an empty string is not null", "data": "", "valid": false }, { "description": "an object is not null", "data": {}, "valid": false }, { "description": "an array is not null", "data": [], "valid": false }, { "description": "true is not null", "data": true, "valid": false }, { "description": "false is not null", "data": false, "valid": false }, { "description": "null is null", "data": null, "valid": true } ] }, { "description": "multiple types can be specified in an array", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": ["integer", "string"] }, "tests": [ { "description": "an integer is valid", "data": 1, "valid": true }, { "description": "a string is valid", "data": "foo", "valid": true }, { "description": "a float is invalid", "data": 1.1, "valid": false }, { "description": "an object is invalid", "data": {}, "valid": false }, { "description": "an array is invalid", "data": [], "valid": false }, { "description": "a boolean is invalid", "data": true, "valid": false }, { "description": "null is invalid", "data": null, "valid": false } ] }, { "description": "type as array with one item", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": ["string"] }, "tests": [ { "description": "string is valid", "data": "foo", "valid": true }, { "description": "number is invalid", "data": 123, "valid": false } ] }, { "description": "type: array or object", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": ["array", "object"] }, "tests": [ { "description": "array is valid", "data": [1,2,3], "valid": true }, { "description": "object is valid", "data": {"foo": 123}, "valid": true }, { "description": "number is invalid", "data": 123, "valid": false }, { "description": "string is invalid", "data": "foo", "valid": false }, { "description": "null is invalid", "data": null, "valid": false } ] }, { "description": "type: array, object or null", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": ["array", "object", "null"] }, "tests": [ { "description": "array is valid", "data": [1,2,3], "valid": true }, { "description": "object is valid", "data": {"foo": 123}, "valid": true }, { "description": "null is valid", "data": null, "valid": true }, { "description": "number is invalid", "data": 123, "valid": false }, { "description": "string is invalid", "data": "foo", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/unevaluatedItems.json000066400000000000000000000536441477700171100321060ustar00rootroot00000000000000[ { "description": "unevaluatedItems true", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "unevaluatedItems": true }, "tests": [ { "description": "with no unevaluated items", "data": [], "valid": true }, { "description": "with unevaluated items", "data": ["foo"], "valid": true } ] }, { "description": "unevaluatedItems false", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "unevaluatedItems": false }, "tests": [ { "description": "with no unevaluated items", "data": [], "valid": true }, { "description": "with unevaluated items", "data": ["foo"], "valid": false } ] }, { "description": "unevaluatedItems as schema", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "unevaluatedItems": { "type": "string" } }, "tests": [ { "description": "with no unevaluated items", "data": [], "valid": true }, { "description": "with valid unevaluated items", "data": ["foo"], "valid": true }, { "description": "with invalid unevaluated items", "data": [42], "valid": false } ] }, { "description": "unevaluatedItems with uniform items", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "items": { "type": "string" }, "unevaluatedItems": false }, "tests": [ { "description": "unevaluatedItems doesn't apply", "data": ["foo", "bar"], "valid": true } ] }, { "description": "unevaluatedItems with tuple", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "prefixItems": [ { "type": "string" } ], "unevaluatedItems": false }, "tests": [ { "description": "with no unevaluated items", "data": ["foo"], "valid": true }, { "description": "with unevaluated items", "data": ["foo", "bar"], "valid": false } ] }, { "description": "unevaluatedItems with items and prefixItems", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "prefixItems": [ { "type": "string" } ], "items": true, "unevaluatedItems": false }, "tests": [ { "description": "unevaluatedItems doesn't apply", "data": ["foo", 42], "valid": true } ] }, { "description": "unevaluatedItems with items", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "items": {"type": "number"}, "unevaluatedItems": {"type": "string"} }, "tests": [ { "description": "valid under items", "comment": "no elements are considered by unevaluatedItems", "data": [5, 6, 7, 8], "valid": true }, { "description": "invalid under items", "data": ["foo", "bar", "baz"], "valid": false } ] }, { "description": "unevaluatedItems with nested tuple", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "prefixItems": [ { "type": "string" } ], "allOf": [ { "prefixItems": [ true, { "type": "number" } ] } ], "unevaluatedItems": false }, "tests": [ { "description": "with no unevaluated items", "data": ["foo", 42], "valid": true }, { "description": "with unevaluated items", "data": ["foo", 42, true], "valid": false } ] }, { "description": "unevaluatedItems with nested items", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "unevaluatedItems": {"type": "boolean"}, "anyOf": [ { "items": {"type": "string"} }, true ] }, "tests": [ { "description": "with only (valid) additional items", "data": [true, false], "valid": true }, { "description": "with no additional items", "data": ["yes", "no"], "valid": true }, { "description": "with invalid additional item", "data": ["yes", false], "valid": false } ] }, { "description": "unevaluatedItems with nested prefixItems and items", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "allOf": [ { "prefixItems": [ { "type": "string" } ], "items": true } ], "unevaluatedItems": false }, "tests": [ { "description": "with no additional items", "data": ["foo"], "valid": true }, { "description": "with additional items", "data": ["foo", 42, true], "valid": true } ] }, { "description": "unevaluatedItems with nested unevaluatedItems", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "allOf": [ { "prefixItems": [ { "type": "string" } ] }, { "unevaluatedItems": true } ], "unevaluatedItems": false }, "tests": [ { "description": "with no additional items", "data": ["foo"], "valid": true }, { "description": "with additional items", "data": ["foo", 42, true], "valid": true } ] }, { "description": "unevaluatedItems with anyOf", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "prefixItems": [ { "const": "foo" } ], "anyOf": [ { "prefixItems": [ true, { "const": "bar" } ] }, { "prefixItems": [ true, true, { "const": "baz" } ] } ], "unevaluatedItems": false }, "tests": [ { "description": "when one schema matches and has no unevaluated items", "data": ["foo", "bar"], "valid": true }, { "description": "when one schema matches and has unevaluated items", "data": ["foo", "bar", 42], "valid": false }, { "description": "when two schemas match and has no unevaluated items", "data": ["foo", "bar", "baz"], "valid": true }, { "description": "when two schemas match and has unevaluated items", "data": ["foo", "bar", "baz", 42], "valid": false } ] }, { "description": "unevaluatedItems with oneOf", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "prefixItems": [ { "const": "foo" } ], "oneOf": [ { "prefixItems": [ true, { "const": "bar" } ] }, { "prefixItems": [ true, { "const": "baz" } ] } ], "unevaluatedItems": false }, "tests": [ { "description": "with no unevaluated items", "data": ["foo", "bar"], "valid": true }, { "description": "with unevaluated items", "data": ["foo", "bar", 42], "valid": false } ] }, { "description": "unevaluatedItems with not", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "prefixItems": [ { "const": "foo" } ], "not": { "not": { "prefixItems": [ true, { "const": "bar" } ] } }, "unevaluatedItems": false }, "tests": [ { "description": "with unevaluated items", "data": ["foo", "bar"], "valid": false } ] }, { "description": "unevaluatedItems with if/then/else", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "prefixItems": [ { "const": "foo" } ], "if": { "prefixItems": [ true, { "const": "bar" } ] }, "then": { "prefixItems": [ true, true, { "const": "then" } ] }, "else": { "prefixItems": [ true, true, true, { "const": "else" } ] }, "unevaluatedItems": false }, "tests": [ { "description": "when if matches and it has no unevaluated items", "data": ["foo", "bar", "then"], "valid": true }, { "description": "when if matches and it has unevaluated items", "data": ["foo", "bar", "then", "else"], "valid": false }, { "description": "when if doesn't match and it has no unevaluated items", "data": ["foo", 42, 42, "else"], "valid": true }, { "description": "when if doesn't match and it has unevaluated items", "data": ["foo", 42, 42, "else", 42], "valid": false } ] }, { "description": "unevaluatedItems with boolean schemas", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "allOf": [true], "unevaluatedItems": false }, "tests": [ { "description": "with no unevaluated items", "data": [], "valid": true }, { "description": "with unevaluated items", "data": ["foo"], "valid": false } ] }, { "description": "unevaluatedItems with $ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$ref": "#/$defs/bar", "prefixItems": [ { "type": "string" } ], "unevaluatedItems": false, "$defs": { "bar": { "prefixItems": [ true, { "type": "string" } ] } } }, "tests": [ { "description": "with no unevaluated items", "data": ["foo", "bar"], "valid": true }, { "description": "with unevaluated items", "data": ["foo", "bar", "baz"], "valid": false } ] }, { "description": "unevaluatedItems with $dynamicRef", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "https://example.com/derived", "$ref": "/baseSchema", "$defs": { "derived": { "$dynamicAnchor": "addons", "prefixItems": [ true, { "type": "string" } ] }, "baseSchema": { "$id": "/baseSchema", "$comment": "unevaluatedItems comes first so it's more likely to catch bugs with implementations that are sensitive to keyword ordering", "unevaluatedItems": false, "type": "array", "prefixItems": [ { "type": "string" } ], "$dynamicRef": "#addons" } } }, "tests": [ { "description": "with no unevaluated items", "data": ["foo", "bar"], "valid": true }, { "description": "with unevaluated items", "data": ["foo", "bar", "baz"], "valid": false } ] }, { "description": "unevaluatedItems can't see inside cousins", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "allOf": [ { "prefixItems": [ true ] }, { "unevaluatedItems": false } ] }, "tests": [ { "description": "always fails", "data": [ 1 ], "valid": false } ] }, { "description": "item is evaluated in an uncle schema to unevaluatedItems", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": { "foo": { "prefixItems": [ { "type": "string" } ], "unevaluatedItems": false } }, "anyOf": [ { "properties": { "foo": { "prefixItems": [ true, { "type": "string" } ] } } } ] }, "tests": [ { "description": "no extra items", "data": { "foo": [ "test" ] }, "valid": true }, { "description": "uncle keyword evaluation is not significant", "data": { "foo": [ "test", "test" ] }, "valid": false } ] }, { "description": "unevaluatedItems depends on adjacent contains", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "prefixItems": [true], "contains": {"type": "string"}, "unevaluatedItems": false }, "tests": [ { "description": "second item is evaluated by contains", "data": [ 1, "foo" ], "valid": true }, { "description": "contains fails, second item is not evaluated", "data": [ 1, 2 ], "valid": false }, { "description": "contains passes, second item is not evaluated", "data": [ 1, 2, "foo" ], "valid": false } ] }, { "description": "unevaluatedItems depends on multiple nested contains", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "allOf": [ { "contains": { "multipleOf": 2 } }, { "contains": { "multipleOf": 3 } } ], "unevaluatedItems": { "multipleOf": 5 } }, "tests": [ { "description": "5 not evaluated, passes unevaluatedItems", "data": [ 2, 3, 4, 5, 6 ], "valid": true }, { "description": "7 not evaluated, fails unevaluatedItems", "data": [ 2, 3, 4, 7, 8 ], "valid": false } ] }, { "description": "unevaluatedItems and contains interact to control item dependency relationship", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "if": { "contains": {"const": "a"} }, "then": { "if": { "contains": {"const": "b"} }, "then": { "if": { "contains": {"const": "c"} } } }, "unevaluatedItems": false }, "tests": [ { "description": "empty array is valid", "data": [], "valid": true }, { "description": "only a's are valid", "data": [ "a", "a" ], "valid": true }, { "description": "a's and b's are valid", "data": [ "a", "b", "a", "b", "a" ], "valid": true }, { "description": "a's, b's and c's are valid", "data": [ "c", "a", "c", "c", "b", "a" ], "valid": true }, { "description": "only b's are invalid", "data": [ "b", "b" ], "valid": false }, { "description": "only c's are invalid", "data": [ "c", "c" ], "valid": false }, { "description": "only b's and c's are invalid", "data": [ "c", "b", "c", "b", "c" ], "valid": false }, { "description": "only a's and c's are invalid", "data": [ "c", "a", "c", "a", "c" ], "valid": false } ] }, { "description": "non-array instances are valid", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "unevaluatedItems": false }, "tests": [ { "description": "ignores booleans", "data": true, "valid": true }, { "description": "ignores integers", "data": 123, "valid": true }, { "description": "ignores floats", "data": 1.0, "valid": true }, { "description": "ignores objects", "data": {}, "valid": true }, { "description": "ignores strings", "data": "foo", "valid": true }, { "description": "ignores null", "data": null, "valid": true } ] }, { "description": "unevaluatedItems with null instance elements", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "unevaluatedItems": { "type": "null" } }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] }, { "description": "unevaluatedItems can see annotations from if without then and else", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "if": { "prefixItems": [{"const": "a"}] }, "unevaluatedItems": false }, "tests": [ { "description": "valid in case if is evaluated", "data": [ "a" ], "valid": true }, { "description": "invalid in case if is evaluated", "data": [ "b" ], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/unevaluatedProperties.json000066400000000000000000001327151477700171100331560ustar00rootroot00000000000000[ { "description": "unevaluatedProperties true", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "unevaluatedProperties": true }, "tests": [ { "description": "with no unevaluated properties", "data": {}, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo" }, "valid": true } ] }, { "description": "unevaluatedProperties schema", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "unevaluatedProperties": { "type": "string", "minLength": 3 } }, "tests": [ { "description": "with no unevaluated properties", "data": {}, "valid": true }, { "description": "with valid unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with invalid unevaluated properties", "data": { "foo": "fo" }, "valid": false } ] }, { "description": "unevaluatedProperties false", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": {}, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo" }, "valid": false } ] }, { "description": "unevaluatedProperties with adjacent properties", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "unevaluatedProperties with adjacent patternProperties", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "patternProperties": { "^foo": { "type": "string" } }, "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "unevaluatedProperties with adjacent additionalProperties", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "additionalProperties": true, "unevaluatedProperties": false }, "tests": [ { "description": "with no additional properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with additional properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true } ] }, { "description": "unevaluatedProperties with nested properties", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "properties": { "bar": { "type": "string" } } } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no additional properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with additional properties", "data": { "foo": "foo", "bar": "bar", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with nested patternProperties", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "patternProperties": { "^bar": { "type": "string" } } } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no additional properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with additional properties", "data": { "foo": "foo", "bar": "bar", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with nested additionalProperties", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "additionalProperties": true } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no additional properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with additional properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true } ] }, { "description": "unevaluatedProperties with nested unevaluatedProperties", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "unevaluatedProperties": true } ], "unevaluatedProperties": { "type": "string", "maxLength": 2 } }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true } ] }, { "description": "unevaluatedProperties with anyOf", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "anyOf": [ { "properties": { "bar": { "const": "bar" } }, "required": ["bar"] }, { "properties": { "baz": { "const": "baz" } }, "required": ["baz"] }, { "properties": { "quux": { "const": "quux" } }, "required": ["quux"] } ], "unevaluatedProperties": false }, "tests": [ { "description": "when one matches and has no unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "when one matches and has unevaluated properties", "data": { "foo": "foo", "bar": "bar", "baz": "not-baz" }, "valid": false }, { "description": "when two match and has no unevaluated properties", "data": { "foo": "foo", "bar": "bar", "baz": "baz" }, "valid": true }, { "description": "when two match and has unevaluated properties", "data": { "foo": "foo", "bar": "bar", "baz": "baz", "quux": "not-quux" }, "valid": false } ] }, { "description": "unevaluatedProperties with oneOf", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "oneOf": [ { "properties": { "bar": { "const": "bar" } }, "required": ["bar"] }, { "properties": { "baz": { "const": "baz" } }, "required": ["baz"] } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar", "quux": "quux" }, "valid": false } ] }, { "description": "unevaluatedProperties with not", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "not": { "not": { "properties": { "bar": { "const": "bar" } }, "required": ["bar"] } }, "unevaluatedProperties": false }, "tests": [ { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "unevaluatedProperties with if/then/else", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "if": { "properties": { "foo": { "const": "then" } }, "required": ["foo"] }, "then": { "properties": { "bar": { "type": "string" } }, "required": ["bar"] }, "else": { "properties": { "baz": { "type": "string" } }, "required": ["baz"] }, "unevaluatedProperties": false }, "tests": [ { "description": "when if is true and has no unevaluated properties", "data": { "foo": "then", "bar": "bar" }, "valid": true }, { "description": "when if is true and has unevaluated properties", "data": { "foo": "then", "bar": "bar", "baz": "baz" }, "valid": false }, { "description": "when if is false and has no unevaluated properties", "data": { "baz": "baz" }, "valid": true }, { "description": "when if is false and has unevaluated properties", "data": { "foo": "else", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with if/then/else, then not defined", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "if": { "properties": { "foo": { "const": "then" } }, "required": ["foo"] }, "else": { "properties": { "baz": { "type": "string" } }, "required": ["baz"] }, "unevaluatedProperties": false }, "tests": [ { "description": "when if is true and has no unevaluated properties", "data": { "foo": "then", "bar": "bar" }, "valid": false }, { "description": "when if is true and has unevaluated properties", "data": { "foo": "then", "bar": "bar", "baz": "baz" }, "valid": false }, { "description": "when if is false and has no unevaluated properties", "data": { "baz": "baz" }, "valid": true }, { "description": "when if is false and has unevaluated properties", "data": { "foo": "else", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with if/then/else, else not defined", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "if": { "properties": { "foo": { "const": "then" } }, "required": ["foo"] }, "then": { "properties": { "bar": { "type": "string" } }, "required": ["bar"] }, "unevaluatedProperties": false }, "tests": [ { "description": "when if is true and has no unevaluated properties", "data": { "foo": "then", "bar": "bar" }, "valid": true }, { "description": "when if is true and has unevaluated properties", "data": { "foo": "then", "bar": "bar", "baz": "baz" }, "valid": false }, { "description": "when if is false and has no unevaluated properties", "data": { "baz": "baz" }, "valid": false }, { "description": "when if is false and has unevaluated properties", "data": { "foo": "else", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with dependentSchemas", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "dependentSchemas": { "foo": { "properties": { "bar": { "const": "bar" } }, "required": ["bar"] } }, "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with unevaluated properties", "data": { "bar": "bar" }, "valid": false } ] }, { "description": "unevaluatedProperties with boolean schemas", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [true], "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with unevaluated properties", "data": { "bar": "bar" }, "valid": false } ] }, { "description": "unevaluatedProperties with $ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "$ref": "#/$defs/bar", "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": false, "$defs": { "bar": { "properties": { "bar": { "type": "string" } } } } }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with $dynamicRef", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$id": "https://example.com/derived", "$ref": "/baseSchema", "$defs": { "derived": { "$dynamicAnchor": "addons", "properties": { "bar": { "type": "string" } } }, "baseSchema": { "$id": "/baseSchema", "$comment": "unevaluatedProperties comes first so it's more likely to catch bugs with implementations that are sensitive to keyword ordering", "unevaluatedProperties": false, "type": "object", "properties": { "foo": { "type": "string" } }, "$dynamicRef": "#addons" } } }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties can't see inside cousins", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "allOf": [ { "properties": { "foo": true } }, { "unevaluatedProperties": false } ] }, "tests": [ { "description": "always fails", "data": { "foo": 1 }, "valid": false } ] }, { "description": "unevaluatedProperties can't see inside cousins (reverse order)", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "allOf": [ { "unevaluatedProperties": false }, { "properties": { "foo": true } } ] }, "tests": [ { "description": "always fails", "data": { "foo": 1 }, "valid": false } ] }, { "description": "nested unevaluatedProperties, outer false, inner true, properties outside", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "unevaluatedProperties": true } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true } ] }, { "description": "nested unevaluatedProperties, outer false, inner true, properties inside", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "allOf": [ { "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": true } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true } ] }, { "description": "nested unevaluatedProperties, outer true, inner false, properties outside", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "unevaluatedProperties": false } ], "unevaluatedProperties": true }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": false }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "nested unevaluatedProperties, outer true, inner false, properties inside", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "allOf": [ { "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": false } ], "unevaluatedProperties": true }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "cousin unevaluatedProperties, true and false, true with properties", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "allOf": [ { "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": true }, { "unevaluatedProperties": false } ] }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": false }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "cousin unevaluatedProperties, true and false, false with properties", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "allOf": [ { "unevaluatedProperties": true }, { "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": false } ] }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "property is evaluated in an uncle schema to unevaluatedProperties", "comment": "see https://stackoverflow.com/questions/66936884/deeply-nested-unevaluatedproperties-and-their-expectations", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "properties": { "foo": { "type": "object", "properties": { "bar": { "type": "string" } }, "unevaluatedProperties": false } }, "anyOf": [ { "properties": { "foo": { "properties": { "faz": { "type": "string" } } } } } ] }, "tests": [ { "description": "no extra properties", "data": { "foo": { "bar": "test" } }, "valid": true }, { "description": "uncle keyword evaluation is not significant", "data": { "foo": { "bar": "test", "faz": "test" } }, "valid": false } ] }, { "description": "in-place applicator siblings, allOf has unevaluated", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "allOf": [ { "properties": { "foo": true }, "unevaluatedProperties": false } ], "anyOf": [ { "properties": { "bar": true } } ] }, "tests": [ { "description": "base case: both properties present", "data": { "foo": 1, "bar": 1 }, "valid": false }, { "description": "in place applicator siblings, bar is missing", "data": { "foo": 1 }, "valid": true }, { "description": "in place applicator siblings, foo is missing", "data": { "bar": 1 }, "valid": false } ] }, { "description": "in-place applicator siblings, anyOf has unevaluated", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "allOf": [ { "properties": { "foo": true } } ], "anyOf": [ { "properties": { "bar": true }, "unevaluatedProperties": false } ] }, "tests": [ { "description": "base case: both properties present", "data": { "foo": 1, "bar": 1 }, "valid": false }, { "description": "in place applicator siblings, bar is missing", "data": { "foo": 1 }, "valid": false }, { "description": "in place applicator siblings, foo is missing", "data": { "bar": 1 }, "valid": true } ] }, { "description": "unevaluatedProperties + single cyclic ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "type": "object", "properties": { "x": { "$ref": "#" } }, "unevaluatedProperties": false }, "tests": [ { "description": "Empty is valid", "data": {}, "valid": true }, { "description": "Single is valid", "data": { "x": {} }, "valid": true }, { "description": "Unevaluated on 1st level is invalid", "data": { "x": {}, "y": {} }, "valid": false }, { "description": "Nested is valid", "data": { "x": { "x": {} } }, "valid": true }, { "description": "Unevaluated on 2nd level is invalid", "data": { "x": { "x": {}, "y": {} } }, "valid": false }, { "description": "Deep nested is valid", "data": { "x": { "x": { "x": {} } } }, "valid": true }, { "description": "Unevaluated on 3rd level is invalid", "data": { "x": { "x": { "x": {}, "y": {} } } }, "valid": false } ] }, { "description": "unevaluatedProperties + ref inside allOf / oneOf", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "one": { "properties": { "a": true } }, "two": { "required": ["x"], "properties": { "x": true } } }, "allOf": [ { "$ref": "#/$defs/one" }, { "properties": { "b": true } }, { "oneOf": [ { "$ref": "#/$defs/two" }, { "required": ["y"], "properties": { "y": true } } ] } ], "unevaluatedProperties": false }, "tests": [ { "description": "Empty is invalid (no x or y)", "data": {}, "valid": false }, { "description": "a and b are invalid (no x or y)", "data": { "a": 1, "b": 1 }, "valid": false }, { "description": "x and y are invalid", "data": { "x": 1, "y": 1 }, "valid": false }, { "description": "a and x are valid", "data": { "a": 1, "x": 1 }, "valid": true }, { "description": "a and y are valid", "data": { "a": 1, "y": 1 }, "valid": true }, { "description": "a and b and x are valid", "data": { "a": 1, "b": 1, "x": 1 }, "valid": true }, { "description": "a and b and y are valid", "data": { "a": 1, "b": 1, "y": 1 }, "valid": true }, { "description": "a and b and x and y are invalid", "data": { "a": 1, "b": 1, "x": 1, "y": 1 }, "valid": false } ] }, { "description": "dynamic evaluation inside nested refs", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "one": { "oneOf": [ { "$ref": "#/$defs/two" }, { "required": ["b"], "properties": { "b": true } }, { "required": ["xx"], "patternProperties": { "x": true } }, { "required": ["all"], "unevaluatedProperties": true } ] }, "two": { "oneOf": [ { "required": ["c"], "properties": { "c": true } }, { "required": ["d"], "properties": { "d": true } } ] } }, "oneOf": [ { "$ref": "#/$defs/one" }, { "required": ["a"], "properties": { "a": true } } ], "unevaluatedProperties": false }, "tests": [ { "description": "Empty is invalid", "data": {}, "valid": false }, { "description": "a is valid", "data": { "a": 1 }, "valid": true }, { "description": "b is valid", "data": { "b": 1 }, "valid": true }, { "description": "c is valid", "data": { "c": 1 }, "valid": true }, { "description": "d is valid", "data": { "d": 1 }, "valid": true }, { "description": "a + b is invalid", "data": { "a": 1, "b": 1 }, "valid": false }, { "description": "a + c is invalid", "data": { "a": 1, "c": 1 }, "valid": false }, { "description": "a + d is invalid", "data": { "a": 1, "d": 1 }, "valid": false }, { "description": "b + c is invalid", "data": { "b": 1, "c": 1 }, "valid": false }, { "description": "b + d is invalid", "data": { "b": 1, "d": 1 }, "valid": false }, { "description": "c + d is invalid", "data": { "c": 1, "d": 1 }, "valid": false }, { "description": "xx is valid", "data": { "xx": 1 }, "valid": true }, { "description": "xx + foox is valid", "data": { "xx": 1, "foox": 1 }, "valid": true }, { "description": "xx + foo is invalid", "data": { "xx": 1, "foo": 1 }, "valid": false }, { "description": "xx + a is invalid", "data": { "xx": 1, "a": 1 }, "valid": false }, { "description": "xx + b is invalid", "data": { "xx": 1, "b": 1 }, "valid": false }, { "description": "xx + c is invalid", "data": { "xx": 1, "c": 1 }, "valid": false }, { "description": "xx + d is invalid", "data": { "xx": 1, "d": 1 }, "valid": false }, { "description": "all is valid", "data": { "all": 1 }, "valid": true }, { "description": "all + foo is valid", "data": { "all": 1, "foo": 1 }, "valid": true }, { "description": "all + a is invalid", "data": { "all": 1, "a": 1 }, "valid": false } ] }, { "description": "non-object instances are valid", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "unevaluatedProperties": false }, "tests": [ { "description": "ignores booleans", "data": true, "valid": true }, { "description": "ignores integers", "data": 123, "valid": true }, { "description": "ignores floats", "data": 1.0, "valid": true }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores strings", "data": "foo", "valid": true }, { "description": "ignores null", "data": null, "valid": true } ] }, { "description": "unevaluatedProperties with null valued instance properties", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "unevaluatedProperties": { "type": "null" } }, "tests": [ { "description": "allows null valued properties", "data": {"foo": null}, "valid": true } ] }, { "description": "unevaluatedProperties can see inside propertyDependencies", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "properties": { "foo": { "type": "string" } }, "propertyDependencies": { "foo": { "foo1": { "properties": { "bar": true } } } }, "unevaluatedProperties": false }, "tests": [ { "description": "allows bar if foo = foo1", "data": { "foo": "foo1", "bar": 42 }, "valid": true }, { "description": "disallows bar if foo != foo1", "data": { "foo": "foo2", "bar": 42 }, "valid": false }, { "description": "disallows bar if foo is absent", "data": { "bar": 42 }, "valid": false } ] }, { "description": "unevaluatedProperties not affected by propertyNames", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "propertyNames": {"maxLength": 1}, "unevaluatedProperties": { "type": "number" } }, "tests": [ { "description": "allows only number properties", "data": {"a": 1}, "valid": true }, { "description": "string property is invalid", "data": {"a": "b"}, "valid": false } ] }, { "description": "unevaluatedProperties can see annotations from if without then and else", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "if": { "patternProperties": { "foo": { "type": "string" } } }, "unevaluatedProperties": false }, "tests": [ { "description": "valid in case if is evaluated", "data": { "foo": "a" }, "valid": true }, { "description": "invalid in case if is evaluated", "data": { "bar": "a" }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/uniqueItems.json000066400000000000000000000342101477700171100310630ustar00rootroot00000000000000[ { "description": "uniqueItems validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "uniqueItems": true }, "tests": [ { "description": "unique array of integers is valid", "data": [1, 2], "valid": true }, { "description": "non-unique array of integers is invalid", "data": [1, 1], "valid": false }, { "description": "non-unique array of more than two integers is invalid", "data": [1, 2, 1], "valid": false }, { "description": "numbers are unique if mathematically unequal", "data": [1.0, 1.00, 1], "valid": false }, { "description": "false is not equal to zero", "data": [0, false], "valid": true }, { "description": "true is not equal to one", "data": [1, true], "valid": true }, { "description": "unique array of strings is valid", "data": ["foo", "bar", "baz"], "valid": true }, { "description": "non-unique array of strings is invalid", "data": ["foo", "bar", "foo"], "valid": false }, { "description": "unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "baz"}], "valid": true }, { "description": "non-unique array of objects is invalid", "data": [{"foo": "bar"}, {"foo": "bar"}], "valid": false }, { "description": "property order of array of objects is ignored", "data": [{"foo": "bar", "bar": "foo"}, {"bar": "foo", "foo": "bar"}], "valid": false }, { "description": "unique array of nested objects is valid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : false}}} ], "valid": true }, { "description": "non-unique array of nested objects is invalid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : true}}} ], "valid": false }, { "description": "unique array of arrays is valid", "data": [["foo"], ["bar"]], "valid": true }, { "description": "non-unique array of arrays is invalid", "data": [["foo"], ["foo"]], "valid": false }, { "description": "non-unique array of more than two arrays is invalid", "data": [["foo"], ["bar"], ["foo"]], "valid": false }, { "description": "1 and true are unique", "data": [1, true], "valid": true }, { "description": "0 and false are unique", "data": [0, false], "valid": true }, { "description": "[1] and [true] are unique", "data": [[1], [true]], "valid": true }, { "description": "[0] and [false] are unique", "data": [[0], [false]], "valid": true }, { "description": "nested [1] and [true] are unique", "data": [[[1], "foo"], [[true], "foo"]], "valid": true }, { "description": "nested [0] and [false] are unique", "data": [[[0], "foo"], [[false], "foo"]], "valid": true }, { "description": "unique heterogeneous types are valid", "data": [{}, [1], true, null, 1, "{}"], "valid": true }, { "description": "non-unique heterogeneous types are invalid", "data": [{}, [1], true, null, {}, 1], "valid": false }, { "description": "different objects are unique", "data": [{"a": 1, "b": 2}, {"a": 2, "b": 1}], "valid": true }, { "description": "objects are non-unique despite key order", "data": [{"a": 1, "b": 2}, {"b": 2, "a": 1}], "valid": false }, { "description": "{\"a\": false} and {\"a\": 0} are unique", "data": [{"a": false}, {"a": 0}], "valid": true }, { "description": "{\"a\": true} and {\"a\": 1} are unique", "data": [{"a": true}, {"a": 1}], "valid": true } ] }, { "description": "uniqueItems with an array of items", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "prefixItems": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": true }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is not valid", "data": [false, false], "valid": false }, { "description": "[true, true] from items array is not valid", "data": [true, true], "valid": false }, { "description": "unique array extended from [false, true] is valid", "data": [false, true, "foo", "bar"], "valid": true }, { "description": "unique array extended from [true, false] is valid", "data": [true, false, "foo", "bar"], "valid": true }, { "description": "non-unique array extended from [false, true] is not valid", "data": [false, true, "foo", "foo"], "valid": false }, { "description": "non-unique array extended from [true, false] is not valid", "data": [true, false, "foo", "foo"], "valid": false } ] }, { "description": "uniqueItems with an array of items and additionalItems=false", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "prefixItems": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": true, "items": false }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is not valid", "data": [false, false], "valid": false }, { "description": "[true, true] from items array is not valid", "data": [true, true], "valid": false }, { "description": "extra items are invalid even if unique", "data": [false, true, null], "valid": false } ] }, { "description": "uniqueItems=false validation", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "uniqueItems": false }, "tests": [ { "description": "unique array of integers is valid", "data": [1, 2], "valid": true }, { "description": "non-unique array of integers is valid", "data": [1, 1], "valid": true }, { "description": "numbers are unique if mathematically unequal", "data": [1.0, 1.00, 1], "valid": true }, { "description": "false is not equal to zero", "data": [0, false], "valid": true }, { "description": "true is not equal to one", "data": [1, true], "valid": true }, { "description": "unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "baz"}], "valid": true }, { "description": "non-unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "bar"}], "valid": true }, { "description": "unique array of nested objects is valid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : false}}} ], "valid": true }, { "description": "non-unique array of nested objects is valid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : true}}} ], "valid": true }, { "description": "unique array of arrays is valid", "data": [["foo"], ["bar"]], "valid": true }, { "description": "non-unique array of arrays is valid", "data": [["foo"], ["foo"]], "valid": true }, { "description": "1 and true are unique", "data": [1, true], "valid": true }, { "description": "0 and false are unique", "data": [0, false], "valid": true }, { "description": "unique heterogeneous types are valid", "data": [{}, [1], true, null, 1], "valid": true }, { "description": "non-unique heterogeneous types are valid", "data": [{}, [1], true, null, {}, 1], "valid": true } ] }, { "description": "uniqueItems=false with an array of items", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "prefixItems": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": false }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is valid", "data": [false, false], "valid": true }, { "description": "[true, true] from items array is valid", "data": [true, true], "valid": true }, { "description": "unique array extended from [false, true] is valid", "data": [false, true, "foo", "bar"], "valid": true }, { "description": "unique array extended from [true, false] is valid", "data": [true, false, "foo", "bar"], "valid": true }, { "description": "non-unique array extended from [false, true] is valid", "data": [false, true, "foo", "foo"], "valid": true }, { "description": "non-unique array extended from [true, false] is valid", "data": [true, false, "foo", "foo"], "valid": true } ] }, { "description": "uniqueItems=false with an array of items and additionalItems=false", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "prefixItems": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": false, "items": false }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is valid", "data": [false, false], "valid": true }, { "description": "[true, true] from items array is valid", "data": [true, true], "valid": true }, { "description": "extra items are invalid even if unique", "data": [false, true, null], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/unknownKeyword.json000066400000000000000000000041001477700171100316120ustar00rootroot00000000000000[ { "description": "$id inside an unknown keyword is not a real identifier", "comment": "the implementation must not be confused by an $id in locations we do not know how to parse", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "id_in_unknown0": { "not": { "array_of_schemas": [ { "$id": "https://localhost:1234/draft-next/unknownKeyword/my_identifier.json", "type": "null" } ] } }, "real_id_in_schema": { "$id": "https://localhost:1234/draft-next/unknownKeyword/my_identifier.json", "type": "string" }, "id_in_unknown1": { "not": { "object_of_schemas": { "foo": { "$id": "https://localhost:1234/draft-next/unknownKeyword/my_identifier.json", "type": "integer" } } } } }, "anyOf": [ { "$ref": "#/$defs/id_in_unknown0" }, { "$ref": "#/$defs/id_in_unknown1" }, { "$ref": "https://localhost:1234/draft-next/unknownKeyword/my_identifier.json" } ] }, "tests": [ { "description": "type matches second anyOf, which has a real schema in it", "data": "a string", "valid": true }, { "description": "type matches non-schema in first anyOf", "data": null, "valid": false }, { "description": "type matches non-schema in third anyOf", "data": 1, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft-next/vocabulary.json000066400000000000000000000032701477700171100307240ustar00rootroot00000000000000[ { "description": "schema that uses custom metaschema with with no validation vocabulary", "schema": { "$id": "https://schema/using/no/validation", "$schema": "http://localhost:1234/draft-next/metaschema-no-validation.json", "properties": { "badProperty": false, "numberProperty": { "minimum": 10 } } }, "tests": [ { "description": "applicator vocabulary still works", "data": { "badProperty": "this property should not exist" }, "valid": false }, { "description": "no validation: valid number", "data": { "numberProperty": 20 }, "valid": true }, { "description": "no validation: invalid number, but it still validates", "data": { "numberProperty": 1 }, "valid": true } ] }, { "description": "ignore unrecognized optional vocabulary", "schema": { "$schema": "http://localhost:1234/draft-next/metaschema-optional-vocabulary.json", "type": "number" }, "tests": [ { "description": "string value", "data": "foobar", "valid": false }, { "description": "number value", "data": 20, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/000077500000000000000000000000001477700171100254465ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/additionalItems.json000066400000000000000000000150411477700171100314540ustar00rootroot00000000000000[ { "description": "additionalItems as schema", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": [{}], "additionalItems": {"type": "integer"} }, "tests": [ { "description": "additional items match schema", "data": [ null, 2, 3, 4 ], "valid": true }, { "description": "additional items do not match schema", "data": [ null, 2, 3, "foo" ], "valid": false } ] }, { "description": "when items is schema, additionalItems does nothing", "schema": { "$schema":"https://json-schema.org/draft/2019-09/schema", "items": { "type": "integer" }, "additionalItems": { "type": "string" } }, "tests": [ { "description": "valid with a array of type integers", "data": [1,2,3], "valid": true }, { "description": "invalid with a array of mixed types", "data": [1,"2","3"], "valid": false } ] }, { "description": "when items is schema, boolean additionalItems does nothing", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": {}, "additionalItems": false }, "tests": [ { "description": "all items match schema", "data": [ 1, 2, 3, 4, 5 ], "valid": true } ] }, { "description": "array of items with no additionalItems permitted", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": [{}, {}, {}], "additionalItems": false }, "tests": [ { "description": "empty array", "data": [ ], "valid": true }, { "description": "fewer number of items present (1)", "data": [ 1 ], "valid": true }, { "description": "fewer number of items present (2)", "data": [ 1, 2 ], "valid": true }, { "description": "equal number of items present", "data": [ 1, 2, 3 ], "valid": true }, { "description": "additional items are not permitted", "data": [ 1, 2, 3, 4 ], "valid": false } ] }, { "description": "additionalItems as false without items", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "additionalItems": false }, "tests": [ { "description": "items defaults to empty schema so everything is valid", "data": [ 1, 2, 3, 4, 5 ], "valid": true }, { "description": "ignores non-arrays", "data": {"foo" : "bar"}, "valid": true } ] }, { "description": "additionalItems are allowed by default", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": [{"type": "integer"}] }, "tests": [ { "description": "only the first item is validated", "data": [1, "foo", false], "valid": true } ] }, { "description": "additionalItems does not look in applicators, valid case", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [ { "items": [ { "type": "integer" } ] } ], "additionalItems": { "type": "boolean" } }, "tests": [ { "description": "items defined in allOf are not examined", "data": [ 1, null ], "valid": true } ] }, { "description": "additionalItems does not look in applicators, invalid case", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [ { "items": [ { "type": "integer" }, { "type": "string" } ] } ], "items": [ {"type": "integer" } ], "additionalItems": { "type": "boolean" } }, "tests": [ { "description": "items defined in allOf are not examined", "data": [ 1, "hello" ], "valid": false } ] }, { "description": "items validation adjusts the starting index for additionalItems", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": [ { "type": "string" } ], "additionalItems": { "type": "integer" } }, "tests": [ { "description": "valid items", "data": [ "x", 2, 3 ], "valid": true }, { "description": "wrong type of second item", "data": [ "x", "y" ], "valid": false } ] }, { "description": "additionalItems with heterogeneous array", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": [{}], "additionalItems": false }, "tests": [ { "description": "heterogeneous invalid instance", "data": [ "foo", "bar", 37 ], "valid": false }, { "description": "valid instance", "data": [ null ], "valid": true } ] }, { "description": "additionalItems with null instance elements", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "additionalItems": { "type": "null" } }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/additionalProperties.json000066400000000000000000000115211477700171100325260ustar00rootroot00000000000000[ { "description": "additionalProperties being false does not allow other properties", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": {"foo": {}, "bar": {}}, "patternProperties": { "^v": {} }, "additionalProperties": false }, "tests": [ { "description": "no additional properties is valid", "data": {"foo": 1}, "valid": true }, { "description": "an additional property is invalid", "data": {"foo" : 1, "bar" : 2, "quux" : "boom"}, "valid": false }, { "description": "ignores arrays", "data": [1, 2, 3], "valid": true }, { "description": "ignores strings", "data": "foobarbaz", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true }, { "description": "patternProperties are not additional properties", "data": {"foo":1, "vroom": 2}, "valid": true } ] }, { "description": "non-ASCII pattern with additionalProperties", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "patternProperties": {"^á": {}}, "additionalProperties": false }, "tests": [ { "description": "matching the pattern is valid", "data": {"ármányos": 2}, "valid": true }, { "description": "not matching the pattern is invalid", "data": {"élmény": 2}, "valid": false } ] }, { "description": "additionalProperties with schema", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": {"foo": {}, "bar": {}}, "additionalProperties": {"type": "boolean"} }, "tests": [ { "description": "no additional properties is valid", "data": {"foo": 1}, "valid": true }, { "description": "an additional valid property is valid", "data": {"foo" : 1, "bar" : 2, "quux" : true}, "valid": true }, { "description": "an additional invalid property is invalid", "data": {"foo" : 1, "bar" : 2, "quux" : 12}, "valid": false } ] }, { "description": "additionalProperties can exist by itself", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "additionalProperties": {"type": "boolean"} }, "tests": [ { "description": "an additional valid property is valid", "data": {"foo" : true}, "valid": true }, { "description": "an additional invalid property is invalid", "data": {"foo" : 1}, "valid": false } ] }, { "description": "additionalProperties are allowed by default", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": {"foo": {}, "bar": {}} }, "tests": [ { "description": "additional properties are allowed", "data": {"foo": 1, "bar": 2, "quux": true}, "valid": true } ] }, { "description": "additionalProperties does not look in applicators", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [ {"properties": {"foo": {}}} ], "additionalProperties": {"type": "boolean"} }, "tests": [ { "description": "properties defined in allOf are not examined", "data": {"foo": 1, "bar": true}, "valid": false } ] }, { "description": "additionalProperties with null valued instance properties", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "additionalProperties": { "type": "null" } }, "tests": [ { "description": "allows null values", "data": {"foo": null}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/allOf.json000066400000000000000000000207751477700171100274110ustar00rootroot00000000000000[ { "description": "allOf", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [ { "properties": { "bar": {"type": "integer"} }, "required": ["bar"] }, { "properties": { "foo": {"type": "string"} }, "required": ["foo"] } ] }, "tests": [ { "description": "allOf", "data": {"foo": "baz", "bar": 2}, "valid": true }, { "description": "mismatch second", "data": {"foo": "baz"}, "valid": false }, { "description": "mismatch first", "data": {"bar": 2}, "valid": false }, { "description": "wrong type", "data": {"foo": "baz", "bar": "quux"}, "valid": false } ] }, { "description": "allOf with base schema", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": {"bar": {"type": "integer"}}, "required": ["bar"], "allOf" : [ { "properties": { "foo": {"type": "string"} }, "required": ["foo"] }, { "properties": { "baz": {"type": "null"} }, "required": ["baz"] } ] }, "tests": [ { "description": "valid", "data": {"foo": "quux", "bar": 2, "baz": null}, "valid": true }, { "description": "mismatch base schema", "data": {"foo": "quux", "baz": null}, "valid": false }, { "description": "mismatch first allOf", "data": {"bar": 2, "baz": null}, "valid": false }, { "description": "mismatch second allOf", "data": {"foo": "quux", "bar": 2}, "valid": false }, { "description": "mismatch both", "data": {"bar": 2}, "valid": false } ] }, { "description": "allOf simple types", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [ {"maximum": 30}, {"minimum": 20} ] }, "tests": [ { "description": "valid", "data": 25, "valid": true }, { "description": "mismatch one", "data": 35, "valid": false } ] }, { "description": "allOf with boolean schemas, all true", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [true, true] }, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "allOf with boolean schemas, some false", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [true, false] }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "allOf with boolean schemas, all false", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [false, false] }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "allOf with one empty schema", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [ {} ] }, "tests": [ { "description": "any data is valid", "data": 1, "valid": true } ] }, { "description": "allOf with two empty schemas", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [ {}, {} ] }, "tests": [ { "description": "any data is valid", "data": 1, "valid": true } ] }, { "description": "allOf with the first empty schema", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [ {}, { "type": "number" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "string is invalid", "data": "foo", "valid": false } ] }, { "description": "allOf with the last empty schema", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [ { "type": "number" }, {} ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "string is invalid", "data": "foo", "valid": false } ] }, { "description": "nested allOf, to check validation semantics", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [ { "allOf": [ { "type": "null" } ] } ] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "anything non-null is invalid", "data": 123, "valid": false } ] }, { "description": "allOf combined with anyOf, oneOf", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [ { "multipleOf": 2 } ], "anyOf": [ { "multipleOf": 3 } ], "oneOf": [ { "multipleOf": 5 } ] }, "tests": [ { "description": "allOf: false, anyOf: false, oneOf: false", "data": 1, "valid": false }, { "description": "allOf: false, anyOf: false, oneOf: true", "data": 5, "valid": false }, { "description": "allOf: false, anyOf: true, oneOf: false", "data": 3, "valid": false }, { "description": "allOf: false, anyOf: true, oneOf: true", "data": 15, "valid": false }, { "description": "allOf: true, anyOf: false, oneOf: false", "data": 2, "valid": false }, { "description": "allOf: true, anyOf: false, oneOf: true", "data": 10, "valid": false }, { "description": "allOf: true, anyOf: true, oneOf: false", "data": 6, "valid": false }, { "description": "allOf: true, anyOf: true, oneOf: true", "data": 30, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/anchor.json000066400000000000000000000160461477700171100276220ustar00rootroot00000000000000[ { "description": "Location-independent identifier", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "#foo", "$defs": { "A": { "$anchor": "foo", "type": "integer" } } }, "tests": [ { "data": 1, "description": "match", "valid": true }, { "data": "a", "description": "mismatch", "valid": false } ] }, { "description": "Location-independent identifier with absolute URI", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://localhost:1234/draft2019-09/bar#foo", "$defs": { "A": { "$id": "http://localhost:1234/draft2019-09/bar", "$anchor": "foo", "type": "integer" } } }, "tests": [ { "data": 1, "description": "match", "valid": true }, { "data": "a", "description": "mismatch", "valid": false } ] }, { "description": "Location-independent identifier with base URI change in subschema", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:1234/draft2019-09/root", "$ref": "http://localhost:1234/draft2019-09/nested.json#foo", "$defs": { "A": { "$id": "nested.json", "$defs": { "B": { "$anchor": "foo", "type": "integer" } } } } }, "tests": [ { "data": 1, "description": "match", "valid": true }, { "data": "a", "description": "mismatch", "valid": false } ] }, { "description": "$anchor inside an enum is not a real identifier", "comment": "the implementation must not be confused by an $anchor buried in the enum", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$defs": { "anchor_in_enum": { "enum": [ { "$anchor": "my_anchor", "type": "null" } ] }, "real_identifier_in_schema": { "$anchor": "my_anchor", "type": "string" }, "zzz_anchor_in_const": { "const": { "$anchor": "my_anchor", "type": "null" } } }, "anyOf": [ { "$ref": "#/$defs/anchor_in_enum" }, { "$ref": "#my_anchor" } ] }, "tests": [ { "description": "exact match to enum, and type matches", "data": { "$anchor": "my_anchor", "type": "null" }, "valid": true }, { "description": "in implementations that strip $anchor, this may match either $def", "data": { "type": "null" }, "valid": false }, { "description": "match $ref to $anchor", "data": "a string to match #/$defs/anchor_in_enum", "valid": true }, { "description": "no match on enum or $ref to $anchor", "data": 1, "valid": false } ] }, { "description": "same $anchor with different base uri", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:1234/draft2019-09/foobar", "$defs": { "A": { "$id": "child1", "allOf": [ { "$id": "child2", "$anchor": "my_anchor", "type": "number" }, { "$anchor": "my_anchor", "type": "string" } ] } }, "$ref": "child1#my_anchor" }, "tests": [ { "description": "$ref resolves to /$defs/A/allOf/1", "data": "a", "valid": true }, { "description": "$ref does not resolve to /$defs/A/allOf/0", "data": 1, "valid": false } ] }, { "description": "non-schema object containing an $anchor property", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$defs": { "const_not_anchor": { "const": { "$anchor": "not_a_real_anchor" } } }, "if": { "const": "skip not_a_real_anchor" }, "then": true, "else" : { "$ref": "#/$defs/const_not_anchor" } }, "tests": [ { "description": "skip traversing definition for a valid result", "data": "skip not_a_real_anchor", "valid": true }, { "description": "const at const_not_anchor does not match", "data": 1, "valid": false } ] }, { "description": "invalid anchors", "comment": "Section 8.2.3", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "https://json-schema.org/draft/2019-09/schema" }, "tests": [ { "description": "MUST start with a letter (and not #)", "data": { "$anchor" : "#foo" }, "valid": false }, { "description": "JSON pointers are not valid", "data": { "$anchor" : "/a/b" }, "valid": false }, { "description": "invalid with valid beginning", "data": { "$anchor" : "foo#something" }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/anyOf.json000066400000000000000000000125251477700171100274220ustar00rootroot00000000000000[ { "description": "anyOf", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "anyOf": [ { "type": "integer" }, { "minimum": 2 } ] }, "tests": [ { "description": "first anyOf valid", "data": 1, "valid": true }, { "description": "second anyOf valid", "data": 2.5, "valid": true }, { "description": "both anyOf valid", "data": 3, "valid": true }, { "description": "neither anyOf valid", "data": 1.5, "valid": false } ] }, { "description": "anyOf with base schema", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "string", "anyOf" : [ { "maxLength": 2 }, { "minLength": 4 } ] }, "tests": [ { "description": "mismatch base schema", "data": 3, "valid": false }, { "description": "one anyOf valid", "data": "foobar", "valid": true }, { "description": "both anyOf invalid", "data": "foo", "valid": false } ] }, { "description": "anyOf with boolean schemas, all true", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "anyOf": [true, true] }, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "anyOf with boolean schemas, some true", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "anyOf": [true, false] }, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "anyOf with boolean schemas, all false", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "anyOf": [false, false] }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "anyOf complex types", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "anyOf": [ { "properties": { "bar": {"type": "integer"} }, "required": ["bar"] }, { "properties": { "foo": {"type": "string"} }, "required": ["foo"] } ] }, "tests": [ { "description": "first anyOf valid (complex)", "data": {"bar": 2}, "valid": true }, { "description": "second anyOf valid (complex)", "data": {"foo": "baz"}, "valid": true }, { "description": "both anyOf valid (complex)", "data": {"foo": "baz", "bar": 2}, "valid": true }, { "description": "neither anyOf valid (complex)", "data": {"foo": 2, "bar": "quux"}, "valid": false } ] }, { "description": "anyOf with one empty schema", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "anyOf": [ { "type": "number" }, {} ] }, "tests": [ { "description": "string is valid", "data": "foo", "valid": true }, { "description": "number is valid", "data": 123, "valid": true } ] }, { "description": "nested anyOf, to check validation semantics", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "anyOf": [ { "anyOf": [ { "type": "null" } ] } ] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "anything non-null is invalid", "data": 123, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/boolean_schema.json000066400000000000000000000054021477700171100313010ustar00rootroot00000000000000[ { "description": "boolean schema 'true'", "schema": true, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "string is valid", "data": "foo", "valid": true }, { "description": "boolean true is valid", "data": true, "valid": true }, { "description": "boolean false is valid", "data": false, "valid": true }, { "description": "null is valid", "data": null, "valid": true }, { "description": "object is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "empty object is valid", "data": {}, "valid": true }, { "description": "array is valid", "data": ["foo"], "valid": true }, { "description": "empty array is valid", "data": [], "valid": true } ] }, { "description": "boolean schema 'false'", "schema": false, "tests": [ { "description": "number is invalid", "data": 1, "valid": false }, { "description": "string is invalid", "data": "foo", "valid": false }, { "description": "boolean true is invalid", "data": true, "valid": false }, { "description": "boolean false is invalid", "data": false, "valid": false }, { "description": "null is invalid", "data": null, "valid": false }, { "description": "object is invalid", "data": {"foo": "bar"}, "valid": false }, { "description": "empty object is invalid", "data": {}, "valid": false }, { "description": "array is invalid", "data": ["foo"], "valid": false }, { "description": "empty array is invalid", "data": [], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/const.json000066400000000000000000000253451477700171100275000ustar00rootroot00000000000000[ { "description": "const validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "const": 2 }, "tests": [ { "description": "same value is valid", "data": 2, "valid": true }, { "description": "another value is invalid", "data": 5, "valid": false }, { "description": "another type is invalid", "data": "a", "valid": false } ] }, { "description": "const with object", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "const": {"foo": "bar", "baz": "bax"} }, "tests": [ { "description": "same object is valid", "data": {"foo": "bar", "baz": "bax"}, "valid": true }, { "description": "same object with different property order is valid", "data": {"baz": "bax", "foo": "bar"}, "valid": true }, { "description": "another object is invalid", "data": {"foo": "bar"}, "valid": false }, { "description": "another type is invalid", "data": [1, 2], "valid": false } ] }, { "description": "const with array", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "const": [{ "foo": "bar" }] }, "tests": [ { "description": "same array is valid", "data": [{"foo": "bar"}], "valid": true }, { "description": "another array item is invalid", "data": [2], "valid": false }, { "description": "array with additional items is invalid", "data": [1, 2, 3], "valid": false } ] }, { "description": "const with null", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "const": null }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "not null is invalid", "data": 0, "valid": false } ] }, { "description": "const with false does not match 0", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "const": false }, "tests": [ { "description": "false is valid", "data": false, "valid": true }, { "description": "integer zero is invalid", "data": 0, "valid": false }, { "description": "float zero is invalid", "data": 0.0, "valid": false } ] }, { "description": "const with true does not match 1", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "const": true }, "tests": [ { "description": "true is valid", "data": true, "valid": true }, { "description": "integer one is invalid", "data": 1, "valid": false }, { "description": "float one is invalid", "data": 1.0, "valid": false } ] }, { "description": "const with [false] does not match [0]", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "const": [false] }, "tests": [ { "description": "[false] is valid", "data": [false], "valid": true }, { "description": "[0] is invalid", "data": [0], "valid": false }, { "description": "[0.0] is invalid", "data": [0.0], "valid": false } ] }, { "description": "const with [true] does not match [1]", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "const": [true] }, "tests": [ { "description": "[true] is valid", "data": [true], "valid": true }, { "description": "[1] is invalid", "data": [1], "valid": false }, { "description": "[1.0] is invalid", "data": [1.0], "valid": false } ] }, { "description": "const with {\"a\": false} does not match {\"a\": 0}", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "const": {"a": false} }, "tests": [ { "description": "{\"a\": false} is valid", "data": {"a": false}, "valid": true }, { "description": "{\"a\": 0} is invalid", "data": {"a": 0}, "valid": false }, { "description": "{\"a\": 0.0} is invalid", "data": {"a": 0.0}, "valid": false } ] }, { "description": "const with {\"a\": true} does not match {\"a\": 1}", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "const": {"a": true} }, "tests": [ { "description": "{\"a\": true} is valid", "data": {"a": true}, "valid": true }, { "description": "{\"a\": 1} is invalid", "data": {"a": 1}, "valid": false }, { "description": "{\"a\": 1.0} is invalid", "data": {"a": 1.0}, "valid": false } ] }, { "description": "const with 0 does not match other zero-like types", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "const": 0 }, "tests": [ { "description": "false is invalid", "data": false, "valid": false }, { "description": "integer zero is valid", "data": 0, "valid": true }, { "description": "float zero is valid", "data": 0.0, "valid": true }, { "description": "empty object is invalid", "data": {}, "valid": false }, { "description": "empty array is invalid", "data": [], "valid": false }, { "description": "empty string is invalid", "data": "", "valid": false } ] }, { "description": "const with 1 does not match true", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "const": 1 }, "tests": [ { "description": "true is invalid", "data": true, "valid": false }, { "description": "integer one is valid", "data": 1, "valid": true }, { "description": "float one is valid", "data": 1.0, "valid": true } ] }, { "description": "const with -2.0 matches integer and float types", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "const": -2.0 }, "tests": [ { "description": "integer -2 is valid", "data": -2, "valid": true }, { "description": "integer 2 is invalid", "data": 2, "valid": false }, { "description": "float -2.0 is valid", "data": -2.0, "valid": true }, { "description": "float 2.0 is invalid", "data": 2.0, "valid": false }, { "description": "float -2.00001 is invalid", "data": -2.00001, "valid": false } ] }, { "description": "float and integers are equal up to 64-bit representation limits", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "const": 9007199254740992 }, "tests": [ { "description": "integer is valid", "data": 9007199254740992, "valid": true }, { "description": "integer minus one is invalid", "data": 9007199254740991, "valid": false }, { "description": "float is valid", "data": 9007199254740992.0, "valid": true }, { "description": "float minus one is invalid", "data": 9007199254740991.0, "valid": false } ] }, { "description": "nul characters in strings", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "const": "hello\u0000there" }, "tests": [ { "description": "match string with nul", "data": "hello\u0000there", "valid": true }, { "description": "do not match string lacking nul", "data": "hellothere", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/contains.json000066400000000000000000000120661477700171100301640ustar00rootroot00000000000000[ { "description": "contains keyword validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "contains": {"minimum": 5} }, "tests": [ { "description": "array with item matching schema (5) is valid", "data": [3, 4, 5], "valid": true }, { "description": "array with item matching schema (6) is valid", "data": [3, 4, 6], "valid": true }, { "description": "array with two items matching schema (5, 6) is valid", "data": [3, 4, 5, 6], "valid": true }, { "description": "array without items matching schema is invalid", "data": [2, 3, 4], "valid": false }, { "description": "empty array is invalid", "data": [], "valid": false }, { "description": "not array is valid", "data": {}, "valid": true } ] }, { "description": "contains keyword with const keyword", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "contains": { "const": 5 } }, "tests": [ { "description": "array with item 5 is valid", "data": [3, 4, 5], "valid": true }, { "description": "array with two items 5 is valid", "data": [3, 4, 5, 5], "valid": true }, { "description": "array without item 5 is invalid", "data": [1, 2, 3, 4], "valid": false } ] }, { "description": "contains keyword with boolean schema true", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "contains": true }, "tests": [ { "description": "any non-empty array is valid", "data": ["foo"], "valid": true }, { "description": "empty array is invalid", "data": [], "valid": false } ] }, { "description": "contains keyword with boolean schema false", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "contains": false }, "tests": [ { "description": "any non-empty array is invalid", "data": ["foo"], "valid": false }, { "description": "empty array is invalid", "data": [], "valid": false }, { "description": "non-arrays are valid", "data": "contains does not apply to strings", "valid": true } ] }, { "description": "items + contains", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": { "multipleOf": 2 }, "contains": { "multipleOf": 3 } }, "tests": [ { "description": "matches items, does not match contains", "data": [ 2, 4, 8 ], "valid": false }, { "description": "does not match items, matches contains", "data": [ 3, 6, 9 ], "valid": false }, { "description": "matches both items and contains", "data": [ 6, 12 ], "valid": true }, { "description": "matches neither items nor contains", "data": [ 1, 5 ], "valid": false } ] }, { "description": "contains with false if subschema", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "contains": { "if": false, "else": true } }, "tests": [ { "description": "any non-empty array is valid", "data": ["foo"], "valid": true }, { "description": "empty array is invalid", "data": [], "valid": false } ] }, { "description": "contains with null instance elements", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "contains": { "type": "null" } }, "tests": [ { "description": "allows null items", "data": [ null ], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/content.json000066400000000000000000000104551477700171100300200ustar00rootroot00000000000000[ { "description": "validation of string-encoded content based on media type", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "contentMediaType": "application/json" }, "tests": [ { "description": "a valid JSON document", "data": "{\"foo\": \"bar\"}", "valid": true }, { "description": "an invalid JSON document; validates true", "data": "{:}", "valid": true }, { "description": "ignores non-strings", "data": 100, "valid": true } ] }, { "description": "validation of binary string-encoding", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "contentEncoding": "base64" }, "tests": [ { "description": "a valid base64 string", "data": "eyJmb28iOiAiYmFyIn0K", "valid": true }, { "description": "an invalid base64 string (% is not a valid character); validates true", "data": "eyJmb28iOi%iYmFyIn0K", "valid": true }, { "description": "ignores non-strings", "data": 100, "valid": true } ] }, { "description": "validation of binary-encoded media type documents", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "contentMediaType": "application/json", "contentEncoding": "base64" }, "tests": [ { "description": "a valid base64-encoded JSON document", "data": "eyJmb28iOiAiYmFyIn0K", "valid": true }, { "description": "a validly-encoded invalid JSON document; validates true", "data": "ezp9Cg==", "valid": true }, { "description": "an invalid base64 string that is valid JSON; validates true", "data": "{}", "valid": true }, { "description": "ignores non-strings", "data": 100, "valid": true } ] }, { "description": "validation of binary-encoded media type documents with schema", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "contentMediaType": "application/json", "contentEncoding": "base64", "contentSchema": { "type": "object", "required": ["foo"], "properties": { "foo": { "type": "string" } } } }, "tests": [ { "description": "a valid base64-encoded JSON document", "data": "eyJmb28iOiAiYmFyIn0K", "valid": true }, { "description": "another valid base64-encoded JSON document", "data": "eyJib28iOiAyMCwgImZvbyI6ICJiYXoifQ==", "valid": true }, { "description": "an invalid base64-encoded JSON document; validates true", "data": "eyJib28iOiAyMH0=", "valid": true }, { "description": "an empty object as a base64-encoded JSON document; validates true", "data": "e30=", "valid": true }, { "description": "an empty array as a base64-encoded JSON document", "data": "W10=", "valid": true }, { "description": "a validly-encoded invalid JSON document; validates true", "data": "ezp9Cg==", "valid": true }, { "description": "an invalid base64 string that is valid JSON; validates true", "data": "{}", "valid": true }, { "description": "ignores non-strings", "data": 100, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/default.json000066400000000000000000000046141477700171100277720ustar00rootroot00000000000000[ { "description": "invalid type for default", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "foo": { "type": "integer", "default": [] } } }, "tests": [ { "description": "valid when property is specified", "data": {"foo": 13}, "valid": true }, { "description": "still valid when the invalid default is used", "data": {}, "valid": true } ] }, { "description": "invalid string value for default", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "bar": { "type": "string", "minLength": 4, "default": "bad" } } }, "tests": [ { "description": "valid when property is specified", "data": {"bar": "good"}, "valid": true }, { "description": "still valid when the invalid default is used", "data": {}, "valid": true } ] }, { "description": "the default keyword does not do anything if the property is missing", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "alpha": { "type": "number", "maximum": 3, "default": 5 } } }, "tests": [ { "description": "an explicit property value is checked against maximum (passing)", "data": { "alpha": 1 }, "valid": true }, { "description": "an explicit property value is checked against maximum (failing)", "data": { "alpha": 5 }, "valid": false }, { "description": "missing properties are not filled in with the default", "data": {}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/defs.json000066400000000000000000000011751477700171100272660ustar00rootroot00000000000000[ { "description": "validate definition against metaschema", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "https://json-schema.org/draft/2019-09/schema" }, "tests": [ { "description": "valid definition schema", "data": {"$defs": {"foo": {"type": "integer"}}}, "valid": true }, { "description": "invalid definition schema", "data": {"$defs": {"foo": {"type": 1}}}, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/dependentRequired.json000066400000000000000000000103061477700171100320100ustar00rootroot00000000000000[ { "description": "single dependency", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "dependentRequired": {"bar": ["foo"]} }, "tests": [ { "description": "neither", "data": {}, "valid": true }, { "description": "nondependant", "data": {"foo": 1}, "valid": true }, { "description": "with dependency", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "missing dependency", "data": {"bar": 2}, "valid": false }, { "description": "ignores arrays", "data": ["bar"], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "empty dependents", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "dependentRequired": {"bar": []} }, "tests": [ { "description": "empty object", "data": {}, "valid": true }, { "description": "object with one property", "data": {"bar": 2}, "valid": true }, { "description": "non-object is valid", "data": 1, "valid": true } ] }, { "description": "multiple dependents required", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "dependentRequired": {"quux": ["foo", "bar"]} }, "tests": [ { "description": "neither", "data": {}, "valid": true }, { "description": "nondependants", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "with dependencies", "data": {"foo": 1, "bar": 2, "quux": 3}, "valid": true }, { "description": "missing dependency", "data": {"foo": 1, "quux": 2}, "valid": false }, { "description": "missing other dependency", "data": {"bar": 1, "quux": 2}, "valid": false }, { "description": "missing both dependencies", "data": {"quux": 1}, "valid": false } ] }, { "description": "dependencies with escaped characters", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "dependentRequired": { "foo\nbar": ["foo\rbar"], "foo\"bar": ["foo'bar"] } }, "tests": [ { "description": "CRLF", "data": { "foo\nbar": 1, "foo\rbar": 2 }, "valid": true }, { "description": "quoted quotes", "data": { "foo'bar": 1, "foo\"bar": 2 }, "valid": true }, { "description": "CRLF missing dependent", "data": { "foo\nbar": 1, "foo": 2 }, "valid": false }, { "description": "quoted quotes missing dependent", "data": { "foo\"bar": 2 }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/dependentSchemas.json000066400000000000000000000115551477700171100316220ustar00rootroot00000000000000[ { "description": "single dependency", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "dependentSchemas": { "bar": { "properties": { "foo": {"type": "integer"}, "bar": {"type": "integer"} } } } }, "tests": [ { "description": "valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "no dependency", "data": {"foo": "quux"}, "valid": true }, { "description": "wrong type", "data": {"foo": "quux", "bar": 2}, "valid": false }, { "description": "wrong type other", "data": {"foo": 2, "bar": "quux"}, "valid": false }, { "description": "wrong type both", "data": {"foo": "quux", "bar": "quux"}, "valid": false }, { "description": "ignores arrays", "data": ["bar"], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "boolean subschemas", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "dependentSchemas": { "foo": true, "bar": false } }, "tests": [ { "description": "object with property having schema true is valid", "data": {"foo": 1}, "valid": true }, { "description": "object with property having schema false is invalid", "data": {"bar": 2}, "valid": false }, { "description": "object with both properties is invalid", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "empty object is valid", "data": {}, "valid": true } ] }, { "description": "dependencies with escaped characters", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "dependentSchemas": { "foo\tbar": {"minProperties": 4}, "foo'bar": {"required": ["foo\"bar"]} } }, "tests": [ { "description": "quoted tab", "data": { "foo\tbar": 1, "a": 2, "b": 3, "c": 4 }, "valid": true }, { "description": "quoted quote", "data": { "foo'bar": {"foo\"bar": 1} }, "valid": false }, { "description": "quoted tab invalid under dependent schema", "data": { "foo\tbar": 1, "a": 2 }, "valid": false }, { "description": "quoted quote invalid under dependent schema", "data": {"foo'bar": 1}, "valid": false } ] }, { "description": "dependent subschema incompatible with root", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "foo": {} }, "dependentSchemas": { "foo": { "properties": { "bar": {} }, "additionalProperties": false } } }, "tests": [ { "description": "matches root", "data": {"foo": 1}, "valid": false }, { "description": "matches dependency", "data": {"bar": 1}, "valid": true }, { "description": "matches both", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "no dependency", "data": {"baz": 1}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/enum.json000066400000000000000000000164251477700171100273150ustar00rootroot00000000000000[ { "description": "simple enum validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "enum": [1, 2, 3] }, "tests": [ { "description": "one of the enum is valid", "data": 1, "valid": true }, { "description": "something else is invalid", "data": 4, "valid": false } ] }, { "description": "heterogeneous enum validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "enum": [6, "foo", [], true, {"foo": 12}] }, "tests": [ { "description": "one of the enum is valid", "data": [], "valid": true }, { "description": "something else is invalid", "data": null, "valid": false }, { "description": "objects are deep compared", "data": {"foo": false}, "valid": false }, { "description": "valid object matches", "data": {"foo": 12}, "valid": true }, { "description": "extra properties in object is invalid", "data": {"foo": 12, "boo": 42}, "valid": false } ] }, { "description": "heterogeneous enum-with-null validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "enum": [6, null] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "number is valid", "data": 6, "valid": true }, { "description": "something else is invalid", "data": "test", "valid": false } ] }, { "description": "enums in properties", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type":"object", "properties": { "foo": {"enum":["foo"]}, "bar": {"enum":["bar"]} }, "required": ["bar"] }, "tests": [ { "description": "both properties are valid", "data": {"foo":"foo", "bar":"bar"}, "valid": true }, { "description": "wrong foo value", "data": {"foo":"foot", "bar":"bar"}, "valid": false }, { "description": "wrong bar value", "data": {"foo":"foo", "bar":"bart"}, "valid": false }, { "description": "missing optional property is valid", "data": {"bar":"bar"}, "valid": true }, { "description": "missing required property is invalid", "data": {"foo":"foo"}, "valid": false }, { "description": "missing all properties is invalid", "data": {}, "valid": false } ] }, { "description": "enum with escaped characters", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "enum": ["foo\nbar", "foo\rbar"] }, "tests": [ { "description": "member 1 is valid", "data": "foo\nbar", "valid": true }, { "description": "member 2 is valid", "data": "foo\rbar", "valid": true }, { "description": "another string is invalid", "data": "abc", "valid": false } ] }, { "description": "enum with false does not match 0", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "enum": [false] }, "tests": [ { "description": "false is valid", "data": false, "valid": true }, { "description": "integer zero is invalid", "data": 0, "valid": false }, { "description": "float zero is invalid", "data": 0.0, "valid": false } ] }, { "description": "enum with true does not match 1", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "enum": [true] }, "tests": [ { "description": "true is valid", "data": true, "valid": true }, { "description": "integer one is invalid", "data": 1, "valid": false }, { "description": "float one is invalid", "data": 1.0, "valid": false } ] }, { "description": "enum with 0 does not match false", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "enum": [0] }, "tests": [ { "description": "false is invalid", "data": false, "valid": false }, { "description": "integer zero is valid", "data": 0, "valid": true }, { "description": "float zero is valid", "data": 0.0, "valid": true } ] }, { "description": "enum with 1 does not match true", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "enum": [1] }, "tests": [ { "description": "true is invalid", "data": true, "valid": false }, { "description": "integer one is valid", "data": 1, "valid": true }, { "description": "float one is valid", "data": 1.0, "valid": true } ] }, { "description": "nul characters in strings", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "enum": [ "hello\u0000there" ] }, "tests": [ { "description": "match string with nul", "data": "hello\u0000there", "valid": true }, { "description": "do not match string lacking nul", "data": "hellothere", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/exclusiveMaximum.json000066400000000000000000000015161477700171100317110ustar00rootroot00000000000000[ { "description": "exclusiveMaximum validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "exclusiveMaximum": 3.0 }, "tests": [ { "description": "below the exclusiveMaximum is valid", "data": 2.2, "valid": true }, { "description": "boundary point is invalid", "data": 3.0, "valid": false }, { "description": "above the exclusiveMaximum is invalid", "data": 3.5, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/exclusiveMinimum.json000066400000000000000000000015161477700171100317070ustar00rootroot00000000000000[ { "description": "exclusiveMinimum validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "exclusiveMinimum": 1.1 }, "tests": [ { "description": "above the exclusiveMinimum is valid", "data": 1.2, "valid": true }, { "description": "boundary point is invalid", "data": 1.1, "valid": false }, { "description": "below the exclusiveMinimum is invalid", "data": 0.6, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/format.json000066400000000000000000000526301477700171100276370ustar00rootroot00000000000000[ { "description": "email format", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "email" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "idn-email format", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "idn-email" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "regex format", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "regex" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "ipv4 format", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "ipv4" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "ipv6 format", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "ipv6" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "idn-hostname format", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "idn-hostname" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "hostname format", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "hostname" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "date format", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "date" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "date-time format", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "date-time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "time format", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "json-pointer format", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "json-pointer" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "relative-json-pointer format", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "relative-json-pointer" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "iri format", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "iri" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "iri-reference format", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "iri-reference" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "uri format", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "uri" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "uri-reference format", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "uri-reference" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "uri-template format", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "uri-template" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "uuid format", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "uuid" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "duration format", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "duration" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/id.json000066400000000000000000000240661477700171100267450ustar00rootroot00000000000000[ { "description": "Invalid use of fragments in location-independent $id", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "https://json-schema.org/draft/2019-09/schema" }, "tests": [ { "description": "Identifier name", "data": { "$ref": "#foo", "$defs": { "A": { "$id": "#foo", "type": "integer" } } }, "valid": false }, { "description": "Identifier name and no ref", "data": { "$defs": { "A": { "$id": "#foo" } } }, "valid": false }, { "description": "Identifier path", "data": { "$ref": "#/a/b", "$defs": { "A": { "$id": "#/a/b", "type": "integer" } } }, "valid": false }, { "description": "Identifier name with absolute URI", "data": { "$ref": "http://localhost:1234/draft2019-09/bar#foo", "$defs": { "A": { "$id": "http://localhost:1234/draft2019-09/bar#foo", "type": "integer" } } }, "valid": false }, { "description": "Identifier path with absolute URI", "data": { "$ref": "http://localhost:1234/draft2019-09/bar#/a/b", "$defs": { "A": { "$id": "http://localhost:1234/draft2019-09/bar#/a/b", "type": "integer" } } }, "valid": false }, { "description": "Identifier name with base URI change in subschema", "data": { "$id": "http://localhost:1234/draft2019-09/root", "$ref": "http://localhost:1234/draft2019-09/nested.json#foo", "$defs": { "A": { "$id": "nested.json", "$defs": { "B": { "$id": "#foo", "type": "integer" } } } } }, "valid": false }, { "description": "Identifier path with base URI change in subschema", "data": { "$id": "http://localhost:1234/draft2019-09/root", "$ref": "http://localhost:1234/draft2019-09/nested.json#/a/b", "$defs": { "A": { "$id": "nested.json", "$defs": { "B": { "$id": "#/a/b", "type": "integer" } } } } }, "valid": false } ] }, { "description": "Valid use of empty fragments in location-independent $id", "comment": "These are allowed but discouraged", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "https://json-schema.org/draft/2019-09/schema" }, "tests": [ { "description": "Identifier name with absolute URI", "data": { "$ref": "http://localhost:1234/draft2019-09/bar", "$defs": { "A": { "$id": "http://localhost:1234/draft2019-09/bar#", "type": "integer" } } }, "valid": true }, { "description": "Identifier name with base URI change in subschema", "data": { "$id": "http://localhost:1234/draft2019-09/root", "$ref": "http://localhost:1234/draft2019-09/nested.json#/$defs/B", "$defs": { "A": { "$id": "nested.json", "$defs": { "B": { "$id": "#", "type": "integer" } } } } }, "valid": true } ] }, { "description": "Unnormalized $ids are allowed but discouraged", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "https://json-schema.org/draft/2019-09/schema" }, "tests": [ { "description": "Unnormalized identifier", "data": { "$ref": "http://localhost:1234/draft2019-09/foo/baz", "$defs": { "A": { "$id": "http://localhost:1234/draft2019-09/foo/bar/../baz", "type": "integer" } } }, "valid": true }, { "description": "Unnormalized identifier and no ref", "data": { "$defs": { "A": { "$id": "http://localhost:1234/draft2019-09/foo/bar/../baz", "type": "integer" } } }, "valid": true }, { "description": "Unnormalized identifier with empty fragment", "data": { "$ref": "http://localhost:1234/draft2019-09/foo/baz", "$defs": { "A": { "$id": "http://localhost:1234/draft2019-09/foo/bar/../baz#", "type": "integer" } } }, "valid": true }, { "description": "Unnormalized identifier with empty fragment and no ref", "data": { "$defs": { "A": { "$id": "http://localhost:1234/draft2019-09/foo/bar/../baz#", "type": "integer" } } }, "valid": true } ] }, { "description": "$id inside an enum is not a real identifier", "comment": "the implementation must not be confused by an $id buried in the enum", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$defs": { "id_in_enum": { "enum": [ { "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", "type": "null" } ] }, "real_id_in_schema": { "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", "type": "string" }, "zzz_id_in_const": { "const": { "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", "type": "null" } } }, "anyOf": [ { "$ref": "#/$defs/id_in_enum" }, { "$ref": "https://localhost:1234/draft2019-09/id/my_identifier.json" } ] }, "tests": [ { "description": "exact match to enum, and type matches", "data": { "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", "type": "null" }, "valid": true }, { "description": "match $ref to $id", "data": "a string to match #/$defs/id_in_enum", "valid": true }, { "description": "no match on enum or $ref to $id", "data": 1, "valid": false } ] }, { "description": "non-schema object containing an $id property", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$defs": { "const_not_id": { "const": { "$id": "not_a_real_id" } } }, "if": { "const": "skip not_a_real_id" }, "then": true, "else" : { "$ref": "#/$defs/const_not_id" } }, "tests": [ { "description": "skip traversing definition for a valid result", "data": "skip not_a_real_id", "valid": true }, { "description": "const at const_not_id does not match", "data": 1, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/if-then-else.json000066400000000000000000000166301477700171100306270ustar00rootroot00000000000000[ { "description": "ignore if without then or else", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "if": { "const": 0 } }, "tests": [ { "description": "valid when valid against lone if", "data": 0, "valid": true }, { "description": "valid when invalid against lone if", "data": "hello", "valid": true } ] }, { "description": "ignore then without if", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "then": { "const": 0 } }, "tests": [ { "description": "valid when valid against lone then", "data": 0, "valid": true }, { "description": "valid when invalid against lone then", "data": "hello", "valid": true } ] }, { "description": "ignore else without if", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "else": { "const": 0 } }, "tests": [ { "description": "valid when valid against lone else", "data": 0, "valid": true }, { "description": "valid when invalid against lone else", "data": "hello", "valid": true } ] }, { "description": "if and then without else", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "if": { "exclusiveMaximum": 0 }, "then": { "minimum": -10 } }, "tests": [ { "description": "valid through then", "data": -1, "valid": true }, { "description": "invalid through then", "data": -100, "valid": false }, { "description": "valid when if test fails", "data": 3, "valid": true } ] }, { "description": "if and else without then", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "if": { "exclusiveMaximum": 0 }, "else": { "multipleOf": 2 } }, "tests": [ { "description": "valid when if test passes", "data": -1, "valid": true }, { "description": "valid through else", "data": 4, "valid": true }, { "description": "invalid through else", "data": 3, "valid": false } ] }, { "description": "validate against correct branch, then vs else", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "if": { "exclusiveMaximum": 0 }, "then": { "minimum": -10 }, "else": { "multipleOf": 2 } }, "tests": [ { "description": "valid through then", "data": -1, "valid": true }, { "description": "invalid through then", "data": -100, "valid": false }, { "description": "valid through else", "data": 4, "valid": true }, { "description": "invalid through else", "data": 3, "valid": false } ] }, { "description": "non-interference across combined schemas", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [ { "if": { "exclusiveMaximum": 0 } }, { "then": { "minimum": -10 } }, { "else": { "multipleOf": 2 } } ] }, "tests": [ { "description": "valid, but would have been invalid through then", "data": -100, "valid": true }, { "description": "valid, but would have been invalid through else", "data": 3, "valid": true } ] }, { "description": "if with boolean schema true", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "if": true, "then": { "const": "then" }, "else": { "const": "else" } }, "tests": [ { "description": "boolean schema true in if always chooses the then path (valid)", "data": "then", "valid": true }, { "description": "boolean schema true in if always chooses the then path (invalid)", "data": "else", "valid": false } ] }, { "description": "if with boolean schema false", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "if": false, "then": { "const": "then" }, "else": { "const": "else" } }, "tests": [ { "description": "boolean schema false in if always chooses the else path (invalid)", "data": "then", "valid": false }, { "description": "boolean schema false in if always chooses the else path (valid)", "data": "else", "valid": true } ] }, { "description": "if appears at the end when serialized (keyword processing sequence)", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "then": { "const": "yes" }, "else": { "const": "other" }, "if": { "maxLength": 4 } }, "tests": [ { "description": "yes redirects to then and passes", "data": "yes", "valid": true }, { "description": "other redirects to else and passes", "data": "other", "valid": true }, { "description": "no redirects to then and fails", "data": "no", "valid": false }, { "description": "invalid redirects to else and fails", "data": "invalid", "valid": false } ] } ] infinite-loop-detection.json000066400000000000000000000020331477700171100330100ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09[ { "description": "evaluating the same schema location against the same data location twice is not a sign of an infinite loop", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$defs": { "int": { "type": "integer" } }, "allOf": [ { "properties": { "foo": { "$ref": "#/$defs/int" } } }, { "additionalProperties": { "$ref": "#/$defs/int" } } ] }, "tests": [ { "description": "passing case", "data": { "foo": 1 }, "valid": true }, { "description": "failing case", "data": { "foo": "a string" }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/items.json000066400000000000000000000210231477700171100274600ustar00rootroot00000000000000[ { "description": "a schema given for items", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": {"type": "integer"} }, "tests": [ { "description": "valid items", "data": [ 1, 2, 3 ], "valid": true }, { "description": "wrong type of items", "data": [1, "x"], "valid": false }, { "description": "ignores non-arrays", "data": {"foo" : "bar"}, "valid": true }, { "description": "JavaScript pseudo-array is valid", "data": { "0": "invalid", "length": 1 }, "valid": true } ] }, { "description": "an array of schemas for items", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": [ {"type": "integer"}, {"type": "string"} ] }, "tests": [ { "description": "correct types", "data": [ 1, "foo" ], "valid": true }, { "description": "wrong types", "data": [ "foo", 1 ], "valid": false }, { "description": "incomplete array of items", "data": [ 1 ], "valid": true }, { "description": "array with additional items", "data": [ 1, "foo", true ], "valid": true }, { "description": "empty array", "data": [ ], "valid": true }, { "description": "JavaScript pseudo-array is valid", "data": { "0": "invalid", "1": "valid", "length": 2 }, "valid": true } ] }, { "description": "items with boolean schema (true)", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": true }, "tests": [ { "description": "any array is valid", "data": [ 1, "foo", true ], "valid": true }, { "description": "empty array is valid", "data": [], "valid": true } ] }, { "description": "items with boolean schema (false)", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": false }, "tests": [ { "description": "any non-empty array is invalid", "data": [ 1, "foo", true ], "valid": false }, { "description": "empty array is valid", "data": [], "valid": true } ] }, { "description": "items with boolean schemas", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": [true, false] }, "tests": [ { "description": "array with one item is valid", "data": [ 1 ], "valid": true }, { "description": "array with two items is invalid", "data": [ 1, "foo" ], "valid": false }, { "description": "empty array is valid", "data": [], "valid": true } ] }, { "description": "items and subitems", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$defs": { "item": { "type": "array", "additionalItems": false, "items": [ { "$ref": "#/$defs/sub-item" }, { "$ref": "#/$defs/sub-item" } ] }, "sub-item": { "type": "object", "required": ["foo"] } }, "type": "array", "additionalItems": false, "items": [ { "$ref": "#/$defs/item" }, { "$ref": "#/$defs/item" }, { "$ref": "#/$defs/item" } ] }, "tests": [ { "description": "valid items", "data": [ [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": true }, { "description": "too many items", "data": [ [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "too many sub-items", "data": [ [ {"foo": null}, {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "wrong item", "data": [ {"foo": null}, [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "wrong sub-item", "data": [ [ {}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "fewer items is valid", "data": [ [ {"foo": null} ], [ {"foo": null} ] ], "valid": true } ] }, { "description": "nested items", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "array", "items": { "type": "array", "items": { "type": "array", "items": { "type": "array", "items": { "type": "number" } } } } }, "tests": [ { "description": "valid nested array", "data": [[[[1]], [[2],[3]]], [[[4], [5], [6]]]], "valid": true }, { "description": "nested array with invalid type", "data": [[[["1"]], [[2],[3]]], [[[4], [5], [6]]]], "valid": false }, { "description": "not deep enough", "data": [[[1], [2],[3]], [[4], [5], [6]]], "valid": false } ] }, { "description": "single-form items with null instance elements", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": { "type": "null" } }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] }, { "description": "array-form items with null instance elements", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": [ { "type": "null" } ] }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/maxContains.json000066400000000000000000000057461477700171100306410ustar00rootroot00000000000000[ { "description": "maxContains without contains is ignored", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "maxContains": 1 }, "tests": [ { "description": "one item valid against lone maxContains", "data": [ 1 ], "valid": true }, { "description": "two items still valid against lone maxContains", "data": [ 1, 2 ], "valid": true } ] }, { "description": "maxContains with contains", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "contains": {"const": 1}, "maxContains": 1 }, "tests": [ { "description": "empty data", "data": [ ], "valid": false }, { "description": "all elements match, valid maxContains", "data": [ 1 ], "valid": true }, { "description": "all elements match, invalid maxContains", "data": [ 1, 1 ], "valid": false }, { "description": "some elements match, valid maxContains", "data": [ 1, 2 ], "valid": true }, { "description": "some elements match, invalid maxContains", "data": [ 1, 2, 1 ], "valid": false } ] }, { "description": "maxContains with contains, value with a decimal", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "contains": {"const": 1}, "maxContains": 1.0 }, "tests": [ { "description": "one element matches, valid maxContains", "data": [ 1 ], "valid": true }, { "description": "too many elements match, invalid maxContains", "data": [ 1, 1 ], "valid": false } ] }, { "description": "minContains < maxContains", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "contains": {"const": 1}, "minContains": 1, "maxContains": 3 }, "tests": [ { "description": "actual < minContains < maxContains", "data": [ ], "valid": false }, { "description": "minContains < actual < maxContains", "data": [ 1, 1 ], "valid": true }, { "description": "minContains < maxContains < actual", "data": [ 1, 1, 1, 1 ], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/maxItems.json000066400000000000000000000024471477700171100301370ustar00rootroot00000000000000[ { "description": "maxItems validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "maxItems": 2 }, "tests": [ { "description": "shorter is valid", "data": [1], "valid": true }, { "description": "exact length is valid", "data": [1, 2], "valid": true }, { "description": "too long is invalid", "data": [1, 2, 3], "valid": false }, { "description": "ignores non-arrays", "data": "foobar", "valid": true } ] }, { "description": "maxItems validation with a decimal", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "maxItems": 2.0 }, "tests": [ { "description": "shorter is valid", "data": [1], "valid": true }, { "description": "too long is invalid", "data": [1, 2, 3], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/maxLength.json000066400000000000000000000027431477700171100302760ustar00rootroot00000000000000[ { "description": "maxLength validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "maxLength": 2 }, "tests": [ { "description": "shorter is valid", "data": "f", "valid": true }, { "description": "exact length is valid", "data": "fo", "valid": true }, { "description": "too long is invalid", "data": "foo", "valid": false }, { "description": "ignores non-strings", "data": 100, "valid": true }, { "description": "two supplementary Unicode code points is long enough", "data": "\uD83D\uDCA9\uD83D\uDCA9", "valid": true } ] }, { "description": "maxLength validation with a decimal", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "maxLength": 2.0 }, "tests": [ { "description": "shorter is valid", "data": "f", "valid": true }, { "description": "too long is invalid", "data": "foo", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/maxProperties.json000066400000000000000000000043001477700171100312000ustar00rootroot00000000000000[ { "description": "maxProperties validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "maxProperties": 2 }, "tests": [ { "description": "shorter is valid", "data": {"foo": 1}, "valid": true }, { "description": "exact length is valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "too long is invalid", "data": {"foo": 1, "bar": 2, "baz": 3}, "valid": false }, { "description": "ignores arrays", "data": [1, 2, 3], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "maxProperties validation with a decimal", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "maxProperties": 2.0 }, "tests": [ { "description": "shorter is valid", "data": {"foo": 1}, "valid": true }, { "description": "too long is invalid", "data": {"foo": 1, "bar": 2, "baz": 3}, "valid": false } ] }, { "description": "maxProperties = 0 means the object is empty", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "maxProperties": 0 }, "tests": [ { "description": "no properties is valid", "data": {}, "valid": true }, { "description": "one property is invalid", "data": { "foo": 1 }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/maximum.json000066400000000000000000000031761477700171100300250ustar00rootroot00000000000000[ { "description": "maximum validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "maximum": 3.0 }, "tests": [ { "description": "below the maximum is valid", "data": 2.6, "valid": true }, { "description": "boundary point is valid", "data": 3.0, "valid": true }, { "description": "above the maximum is invalid", "data": 3.5, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] }, { "description": "maximum validation with unsigned integer", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "maximum": 300 }, "tests": [ { "description": "below the maximum is invalid", "data": 299.97, "valid": true }, { "description": "boundary point integer is valid", "data": 300, "valid": true }, { "description": "boundary point float is valid", "data": 300.00, "valid": true }, { "description": "above the maximum is invalid", "data": 300.5, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/minContains.json000066400000000000000000000147401477700171100306310ustar00rootroot00000000000000[ { "description": "minContains without contains is ignored", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "minContains": 1 }, "tests": [ { "description": "one item valid against lone minContains", "data": [ 1 ], "valid": true }, { "description": "zero items still valid against lone minContains", "data": [], "valid": true } ] }, { "description": "minContains=1 with contains", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "contains": {"const": 1}, "minContains": 1 }, "tests": [ { "description": "empty data", "data": [ ], "valid": false }, { "description": "no elements match", "data": [ 2 ], "valid": false }, { "description": "single element matches, valid minContains", "data": [ 1 ], "valid": true }, { "description": "some elements match, valid minContains", "data": [ 1, 2 ], "valid": true }, { "description": "all elements match, valid minContains", "data": [ 1, 1 ], "valid": true } ] }, { "description": "minContains=2 with contains", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "contains": {"const": 1}, "minContains": 2 }, "tests": [ { "description": "empty data", "data": [ ], "valid": false }, { "description": "all elements match, invalid minContains", "data": [ 1 ], "valid": false }, { "description": "some elements match, invalid minContains", "data": [ 1, 2 ], "valid": false }, { "description": "all elements match, valid minContains (exactly as needed)", "data": [ 1, 1 ], "valid": true }, { "description": "all elements match, valid minContains (more than needed)", "data": [ 1, 1, 1 ], "valid": true }, { "description": "some elements match, valid minContains", "data": [ 1, 2, 1 ], "valid": true } ] }, { "description": "minContains=2 with contains with a decimal value", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "contains": {"const": 1}, "minContains": 2.0 }, "tests": [ { "description": "one element matches, invalid minContains", "data": [ 1 ], "valid": false }, { "description": "both elements match, valid minContains", "data": [ 1, 1 ], "valid": true } ] }, { "description": "maxContains = minContains", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "contains": {"const": 1}, "maxContains": 2, "minContains": 2 }, "tests": [ { "description": "empty data", "data": [ ], "valid": false }, { "description": "all elements match, invalid minContains", "data": [ 1 ], "valid": false }, { "description": "all elements match, invalid maxContains", "data": [ 1, 1, 1 ], "valid": false }, { "description": "all elements match, valid maxContains and minContains", "data": [ 1, 1 ], "valid": true } ] }, { "description": "maxContains < minContains", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "contains": {"const": 1}, "maxContains": 1, "minContains": 3 }, "tests": [ { "description": "empty data", "data": [ ], "valid": false }, { "description": "invalid minContains", "data": [ 1 ], "valid": false }, { "description": "invalid maxContains", "data": [ 1, 1, 1 ], "valid": false }, { "description": "invalid maxContains and minContains", "data": [ 1, 1 ], "valid": false } ] }, { "description": "minContains = 0 with no maxContains", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "contains": {"const": 1}, "minContains": 0 }, "tests": [ { "description": "empty data", "data": [ ], "valid": true }, { "description": "minContains = 0 makes contains always pass", "data": [ 2 ], "valid": true } ] }, { "description": "minContains = 0 with maxContains", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "contains": {"const": 1}, "minContains": 0, "maxContains": 1 }, "tests": [ { "description": "empty data", "data": [ ], "valid": true }, { "description": "not more than maxContains", "data": [ 1 ], "valid": true }, { "description": "too many", "data": [ 1, 1 ], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/minItems.json000066400000000000000000000024261477700171100301320ustar00rootroot00000000000000[ { "description": "minItems validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "minItems": 1 }, "tests": [ { "description": "longer is valid", "data": [1, 2], "valid": true }, { "description": "exact length is valid", "data": [1], "valid": true }, { "description": "too short is invalid", "data": [], "valid": false }, { "description": "ignores non-arrays", "data": "", "valid": true } ] }, { "description": "minItems validation with a decimal", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "minItems": 1.0 }, "tests": [ { "description": "longer is valid", "data": [1, 2], "valid": true }, { "description": "too short is invalid", "data": [], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/minLength.json000066400000000000000000000027311477700171100302710ustar00rootroot00000000000000[ { "description": "minLength validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "minLength": 2 }, "tests": [ { "description": "longer is valid", "data": "foo", "valid": true }, { "description": "exact length is valid", "data": "fo", "valid": true }, { "description": "too short is invalid", "data": "f", "valid": false }, { "description": "ignores non-strings", "data": 1, "valid": true }, { "description": "one supplementary Unicode code point is not long enough", "data": "\uD83D\uDCA9", "valid": false } ] }, { "description": "minLength validation with a decimal", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "minLength": 2.0 }, "tests": [ { "description": "longer is valid", "data": "foo", "valid": true }, { "description": "too short is invalid", "data": "f", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/minProperties.json000066400000000000000000000031451477700171100312040ustar00rootroot00000000000000[ { "description": "minProperties validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "minProperties": 1 }, "tests": [ { "description": "longer is valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "exact length is valid", "data": {"foo": 1}, "valid": true }, { "description": "too short is invalid", "data": {}, "valid": false }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores strings", "data": "", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "minProperties validation with a decimal", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "minProperties": 1.0 }, "tests": [ { "description": "longer is valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "too short is invalid", "data": {}, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/minimum.json000066400000000000000000000041041477700171100300130ustar00rootroot00000000000000[ { "description": "minimum validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "minimum": 1.1 }, "tests": [ { "description": "above the minimum is valid", "data": 2.6, "valid": true }, { "description": "boundary point is valid", "data": 1.1, "valid": true }, { "description": "below the minimum is invalid", "data": 0.6, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] }, { "description": "minimum validation with signed integer", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "minimum": -2 }, "tests": [ { "description": "negative above the minimum is valid", "data": -1, "valid": true }, { "description": "positive above the minimum is valid", "data": 0, "valid": true }, { "description": "boundary point is valid", "data": -2, "valid": true }, { "description": "boundary point with float is valid", "data": -2.0, "valid": true }, { "description": "float below the minimum is invalid", "data": -2.0001, "valid": false }, { "description": "int below the minimum is invalid", "data": -3, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/multipleOf.json000066400000000000000000000051451477700171100304660ustar00rootroot00000000000000[ { "description": "by int", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "multipleOf": 2 }, "tests": [ { "description": "int by int", "data": 10, "valid": true }, { "description": "int by int fail", "data": 7, "valid": false }, { "description": "ignores non-numbers", "data": "foo", "valid": true } ] }, { "description": "by number", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "multipleOf": 1.5 }, "tests": [ { "description": "zero is multiple of anything", "data": 0, "valid": true }, { "description": "4.5 is multiple of 1.5", "data": 4.5, "valid": true }, { "description": "35 is not multiple of 1.5", "data": 35, "valid": false } ] }, { "description": "by small number", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "multipleOf": 0.0001 }, "tests": [ { "description": "0.0075 is multiple of 0.0001", "data": 0.0075, "valid": true }, { "description": "0.00751 is not multiple of 0.0001", "data": 0.00751, "valid": false } ] }, { "description": "float division = inf", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "integer", "multipleOf": 0.123456789 }, "tests": [ { "description": "always invalid, but naive implementations may raise an overflow error", "data": 1e308, "valid": false } ] }, { "description": "small multiple of large integer", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "integer", "multipleOf": 1e-8 }, "tests": [ { "description": "any integer is a multiple of 1e-8", "data": 12391239123, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/not.json000066400000000000000000000101501477700171100271360ustar00rootroot00000000000000[ { "description": "not", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "not": {"type": "integer"} }, "tests": [ { "description": "allowed", "data": "foo", "valid": true }, { "description": "disallowed", "data": 1, "valid": false } ] }, { "description": "not multiple types", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "not": {"type": ["integer", "boolean"]} }, "tests": [ { "description": "valid", "data": "foo", "valid": true }, { "description": "mismatch", "data": 1, "valid": false }, { "description": "other mismatch", "data": true, "valid": false } ] }, { "description": "not more complex schema", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "not": { "type": "object", "properties": { "foo": { "type": "string" } } } }, "tests": [ { "description": "match", "data": 1, "valid": true }, { "description": "other match", "data": {"foo": 1}, "valid": true }, { "description": "mismatch", "data": {"foo": "bar"}, "valid": false } ] }, { "description": "forbidden property", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "foo": { "not": {} } } }, "tests": [ { "description": "property present", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "property absent", "data": {"bar": 1, "baz": 2}, "valid": true } ] }, { "description": "not with boolean schema true", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "not": true }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "not with boolean schema false", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "not": false }, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "collect annotations inside a 'not', even if collection is disabled", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "not": { "$comment": "this subschema must still produce annotations internally, even though the 'not' will ultimately discard them", "anyOf": [ true, { "properties": { "foo": true } } ], "unevaluatedProperties": false } }, "tests": [ { "description": "unevaluated property", "data": { "bar": 1 }, "valid": true }, { "description": "annotations are still collected inside a 'not'", "data": { "foo": 1 }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/oneOf.json000066400000000000000000000176701477700171100274220ustar00rootroot00000000000000[ { "description": "oneOf", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "oneOf": [ { "type": "integer" }, { "minimum": 2 } ] }, "tests": [ { "description": "first oneOf valid", "data": 1, "valid": true }, { "description": "second oneOf valid", "data": 2.5, "valid": true }, { "description": "both oneOf valid", "data": 3, "valid": false }, { "description": "neither oneOf valid", "data": 1.5, "valid": false } ] }, { "description": "oneOf with base schema", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "string", "oneOf" : [ { "minLength": 2 }, { "maxLength": 4 } ] }, "tests": [ { "description": "mismatch base schema", "data": 3, "valid": false }, { "description": "one oneOf valid", "data": "foobar", "valid": true }, { "description": "both oneOf valid", "data": "foo", "valid": false } ] }, { "description": "oneOf with boolean schemas, all true", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "oneOf": [true, true, true] }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "oneOf with boolean schemas, one true", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "oneOf": [true, false, false] }, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "oneOf with boolean schemas, more than one true", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "oneOf": [true, true, false] }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "oneOf with boolean schemas, all false", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "oneOf": [false, false, false] }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "oneOf complex types", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "oneOf": [ { "properties": { "bar": {"type": "integer"} }, "required": ["bar"] }, { "properties": { "foo": {"type": "string"} }, "required": ["foo"] } ] }, "tests": [ { "description": "first oneOf valid (complex)", "data": {"bar": 2}, "valid": true }, { "description": "second oneOf valid (complex)", "data": {"foo": "baz"}, "valid": true }, { "description": "both oneOf valid (complex)", "data": {"foo": "baz", "bar": 2}, "valid": false }, { "description": "neither oneOf valid (complex)", "data": {"foo": 2, "bar": "quux"}, "valid": false } ] }, { "description": "oneOf with empty schema", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "oneOf": [ { "type": "number" }, {} ] }, "tests": [ { "description": "one valid - valid", "data": "foo", "valid": true }, { "description": "both valid - invalid", "data": 123, "valid": false } ] }, { "description": "oneOf with required", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "oneOf": [ { "required": ["foo", "bar"] }, { "required": ["foo", "baz"] } ] }, "tests": [ { "description": "both invalid - invalid", "data": {"bar": 2}, "valid": false }, { "description": "first valid - valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "second valid - valid", "data": {"foo": 1, "baz": 3}, "valid": true }, { "description": "both valid - invalid", "data": {"foo": 1, "bar": 2, "baz" : 3}, "valid": false } ] }, { "description": "oneOf with missing optional property", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "oneOf": [ { "properties": { "bar": true, "baz": true }, "required": ["bar"] }, { "properties": { "foo": true }, "required": ["foo"] } ] }, "tests": [ { "description": "first oneOf valid", "data": {"bar": 8}, "valid": true }, { "description": "second oneOf valid", "data": {"foo": "foo"}, "valid": true }, { "description": "both oneOf valid", "data": {"foo": "foo", "bar": 8}, "valid": false }, { "description": "neither oneOf valid", "data": {"baz": "quux"}, "valid": false } ] }, { "description": "nested oneOf, to check validation semantics", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "oneOf": [ { "oneOf": [ { "type": "null" } ] } ] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "anything non-null is invalid", "data": 123, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/000077500000000000000000000000001477700171100272735ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/bignum.json000066400000000000000000000065261477700171100314600ustar00rootroot00000000000000[ { "description": "integer", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "integer" }, "tests": [ { "description": "a bignum is an integer", "data": 12345678910111213141516171819202122232425262728293031, "valid": true }, { "description": "a negative bignum is an integer", "data": -12345678910111213141516171819202122232425262728293031, "valid": true } ] }, { "description": "number", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "number" }, "tests": [ { "description": "a bignum is a number", "data": 98249283749234923498293171823948729348710298301928331, "valid": true }, { "description": "a negative bignum is a number", "data": -98249283749234923498293171823948729348710298301928331, "valid": true } ] }, { "description": "string", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "string" }, "tests": [ { "description": "a bignum is not a string", "data": 98249283749234923498293171823948729348710298301928331, "valid": false } ] }, { "description": "maximum integer comparison", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "maximum": 18446744073709551615 }, "tests": [ { "description": "comparison works for high numbers", "data": 18446744073709551600, "valid": true } ] }, { "description": "float comparison with high precision", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "exclusiveMaximum": 972783798187987123879878123.18878137 }, "tests": [ { "description": "comparison works for high numbers", "data": 972783798187987123879878123.188781371, "valid": false } ] }, { "description": "minimum integer comparison", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "minimum": -18446744073709551615 }, "tests": [ { "description": "comparison works for very negative numbers", "data": -18446744073709551600, "valid": true } ] }, { "description": "float comparison with high precision on negative numbers", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "exclusiveMinimum": -972783798187987123879878123.18878137 }, "tests": [ { "description": "comparison works for very negative numbers", "data": -972783798187987123879878123.188781371, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/cross-draft.json000066400000000000000000000026221477700171100324170ustar00rootroot00000000000000[ { "description": "refs to future drafts are processed as future drafts", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "array", "$ref": "http://localhost:1234/draft2020-12/prefixItems.json" }, "tests": [ { "description": "first item not a string is invalid", "comment": "if the implementation is not processing the $ref as a 2020-12 schema, this test will fail", "data": [1, 2, 3], "valid": false }, { "description": "first item is a string is valid", "data": ["a string", 1, 2, 3], "valid": true } ] }, { "description": "refs to historic drafts are processed as historic drafts", "schema": { "type": "object", "allOf": [ { "properties": { "foo": true } }, { "$ref": "http://localhost:1234/draft7/ignore-dependentRequired.json" } ] }, "tests": [ { "description": "missing bar is valid", "comment": "if the implementation is not processing the $ref as a draft 7 schema, this test will fail", "data": {"foo": "any value"}, "valid": true } ] } ] dependencies-compatibility.json000066400000000000000000000177201477700171100354130ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional[ { "description": "single dependency", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "dependencies": {"bar": ["foo"]} }, "tests": [ { "description": "neither", "data": {}, "valid": true }, { "description": "nondependant", "data": {"foo": 1}, "valid": true }, { "description": "with dependency", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "missing dependency", "data": {"bar": 2}, "valid": false }, { "description": "ignores arrays", "data": ["bar"], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "empty dependents", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "dependencies": {"bar": []} }, "tests": [ { "description": "empty object", "data": {}, "valid": true }, { "description": "object with one property", "data": {"bar": 2}, "valid": true }, { "description": "non-object is valid", "data": 1, "valid": true } ] }, { "description": "multiple dependents required", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "dependencies": {"quux": ["foo", "bar"]} }, "tests": [ { "description": "neither", "data": {}, "valid": true }, { "description": "nondependants", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "with dependencies", "data": {"foo": 1, "bar": 2, "quux": 3}, "valid": true }, { "description": "missing dependency", "data": {"foo": 1, "quux": 2}, "valid": false }, { "description": "missing other dependency", "data": {"bar": 1, "quux": 2}, "valid": false }, { "description": "missing both dependencies", "data": {"quux": 1}, "valid": false } ] }, { "description": "dependencies with escaped characters", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "dependencies": { "foo\nbar": ["foo\rbar"], "foo\"bar": ["foo'bar"] } }, "tests": [ { "description": "CRLF", "data": { "foo\nbar": 1, "foo\rbar": 2 }, "valid": true }, { "description": "quoted quotes", "data": { "foo'bar": 1, "foo\"bar": 2 }, "valid": true }, { "description": "CRLF missing dependent", "data": { "foo\nbar": 1, "foo": 2 }, "valid": false }, { "description": "quoted quotes missing dependent", "data": { "foo\"bar": 2 }, "valid": false } ] }, { "description": "single schema dependency", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "dependencies": { "bar": { "properties": { "foo": {"type": "integer"}, "bar": {"type": "integer"} } } } }, "tests": [ { "description": "valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "no dependency", "data": {"foo": "quux"}, "valid": true }, { "description": "wrong type", "data": {"foo": "quux", "bar": 2}, "valid": false }, { "description": "wrong type other", "data": {"foo": 2, "bar": "quux"}, "valid": false }, { "description": "wrong type both", "data": {"foo": "quux", "bar": "quux"}, "valid": false }, { "description": "ignores arrays", "data": ["bar"], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "boolean subschemas", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "dependencies": { "foo": true, "bar": false } }, "tests": [ { "description": "object with property having schema true is valid", "data": {"foo": 1}, "valid": true }, { "description": "object with property having schema false is invalid", "data": {"bar": 2}, "valid": false }, { "description": "object with both properties is invalid", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "empty object is valid", "data": {}, "valid": true } ] }, { "description": "schema dependencies with escaped characters", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "dependencies": { "foo\tbar": {"minProperties": 4}, "foo'bar": {"required": ["foo\"bar"]} } }, "tests": [ { "description": "quoted tab", "data": { "foo\tbar": 1, "a": 2, "b": 3, "c": 4 }, "valid": true }, { "description": "quoted quote", "data": { "foo'bar": {"foo\"bar": 1} }, "valid": false }, { "description": "quoted tab invalid under dependent schema", "data": { "foo\tbar": 1, "a": 2 }, "valid": false }, { "description": "quoted quote invalid under dependent schema", "data": {"foo'bar": 1}, "valid": false } ] } ] ecmascript-regex.json000066400000000000000000000470611477700171100333610ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional[ { "description": "ECMA 262 regex $ does not match trailing newline", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "string", "pattern": "^abc$" }, "tests": [ { "description": "matches in Python, but not in ECMA 262", "data": "abc\\n", "valid": false }, { "description": "matches", "data": "abc", "valid": true } ] }, { "description": "ECMA 262 regex converts \\t to horizontal tab", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "string", "pattern": "^\\t$" }, "tests": [ { "description": "does not match", "data": "\\t", "valid": false }, { "description": "matches", "data": "\u0009", "valid": true } ] }, { "description": "ECMA 262 regex escapes control codes with \\c and upper letter", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "string", "pattern": "^\\cC$" }, "tests": [ { "description": "does not match", "data": "\\cC", "valid": false }, { "description": "matches", "data": "\u0003", "valid": true } ] }, { "description": "ECMA 262 regex escapes control codes with \\c and lower letter", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "string", "pattern": "^\\cc$" }, "tests": [ { "description": "does not match", "data": "\\cc", "valid": false }, { "description": "matches", "data": "\u0003", "valid": true } ] }, { "description": "ECMA 262 \\d matches ascii digits only", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "string", "pattern": "^\\d$" }, "tests": [ { "description": "ASCII zero matches", "data": "0", "valid": true }, { "description": "NKO DIGIT ZERO does not match (unlike e.g. Python)", "data": "߀", "valid": false }, { "description": "NKO DIGIT ZERO (as \\u escape) does not match", "data": "\u07c0", "valid": false } ] }, { "description": "ECMA 262 \\D matches everything but ascii digits", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "string", "pattern": "^\\D$" }, "tests": [ { "description": "ASCII zero does not match", "data": "0", "valid": false }, { "description": "NKO DIGIT ZERO matches (unlike e.g. Python)", "data": "߀", "valid": true }, { "description": "NKO DIGIT ZERO (as \\u escape) matches", "data": "\u07c0", "valid": true } ] }, { "description": "ECMA 262 \\w matches ascii letters only", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "string", "pattern": "^\\w$" }, "tests": [ { "description": "ASCII 'a' matches", "data": "a", "valid": true }, { "description": "latin-1 e-acute does not match (unlike e.g. Python)", "data": "é", "valid": false } ] }, { "description": "ECMA 262 \\W matches everything but ascii letters", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "string", "pattern": "^\\W$" }, "tests": [ { "description": "ASCII 'a' does not match", "data": "a", "valid": false }, { "description": "latin-1 e-acute matches (unlike e.g. Python)", "data": "é", "valid": true } ] }, { "description": "ECMA 262 \\s matches whitespace", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "string", "pattern": "^\\s$" }, "tests": [ { "description": "ASCII space matches", "data": " ", "valid": true }, { "description": "Character tabulation matches", "data": "\t", "valid": true }, { "description": "Line tabulation matches", "data": "\u000b", "valid": true }, { "description": "Form feed matches", "data": "\u000c", "valid": true }, { "description": "latin-1 non-breaking-space matches", "data": "\u00a0", "valid": true }, { "description": "zero-width whitespace matches", "data": "\ufeff", "valid": true }, { "description": "line feed matches (line terminator)", "data": "\u000a", "valid": true }, { "description": "paragraph separator matches (line terminator)", "data": "\u2029", "valid": true }, { "description": "EM SPACE matches (Space_Separator)", "data": "\u2003", "valid": true }, { "description": "Non-whitespace control does not match", "data": "\u0001", "valid": false }, { "description": "Non-whitespace does not match", "data": "\u2013", "valid": false } ] }, { "description": "ECMA 262 \\S matches everything but whitespace", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "string", "pattern": "^\\S$" }, "tests": [ { "description": "ASCII space does not match", "data": " ", "valid": false }, { "description": "Character tabulation does not match", "data": "\t", "valid": false }, { "description": "Line tabulation does not match", "data": "\u000b", "valid": false }, { "description": "Form feed does not match", "data": "\u000c", "valid": false }, { "description": "latin-1 non-breaking-space does not match", "data": "\u00a0", "valid": false }, { "description": "zero-width whitespace does not match", "data": "\ufeff", "valid": false }, { "description": "line feed does not match (line terminator)", "data": "\u000a", "valid": false }, { "description": "paragraph separator does not match (line terminator)", "data": "\u2029", "valid": false }, { "description": "EM SPACE does not match (Space_Separator)", "data": "\u2003", "valid": false }, { "description": "Non-whitespace control matches", "data": "\u0001", "valid": true }, { "description": "Non-whitespace matches", "data": "\u2013", "valid": true } ] }, { "description": "patterns always use unicode semantics with pattern", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "pattern": "\\p{Letter}cole" }, "tests": [ { "description": "ascii character in json string", "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", "valid": true }, { "description": "literal unicode character in json string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": true }, { "description": "unicode character in hex format in string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": true }, { "description": "unicode matching is case-sensitive", "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", "valid": false } ] }, { "description": "\\w in patterns matches [A-Za-z0-9_], not unicode letters", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "pattern": "\\wcole" }, "tests": [ { "description": "ascii character in json string", "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", "valid": true }, { "description": "literal unicode character in json string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "unicode character in hex format in string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "unicode matching is case-sensitive", "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", "valid": false } ] }, { "description": "pattern with ASCII ranges", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "pattern": "[a-z]cole" }, "tests": [ { "description": "literal unicode character in json string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "unicode character in hex format in string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "ascii characters match", "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", "valid": true } ] }, { "description": "\\d in pattern matches [0-9], not unicode digits", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "pattern": "^\\d+$" }, "tests": [ { "description": "ascii digits", "data": "42", "valid": true }, { "description": "ascii non-digits", "data": "-%#", "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": "৪২", "valid": false } ] }, { "description": "pattern with non-ASCII digits", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "pattern": "^\\p{digit}+$" }, "tests": [ { "description": "ascii digits", "data": "42", "valid": true }, { "description": "ascii non-digits", "data": "-%#", "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": "৪২", "valid": true } ] }, { "description": "patterns always use unicode semantics with patternProperties", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "patternProperties": { "\\p{Letter}cole": true }, "additionalProperties": false }, "tests": [ { "description": "ascii character in json string", "data": { "l'ecole": "pas de vraie vie" }, "valid": true }, { "description": "literal unicode character in json string", "data": { "l'école": "pas de vraie vie" }, "valid": true }, { "description": "unicode character in hex format in string", "data": { "l'\u00e9cole": "pas de vraie vie" }, "valid": true }, { "description": "unicode matching is case-sensitive", "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, "valid": false } ] }, { "description": "\\w in patternProperties matches [A-Za-z0-9_], not unicode letters", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "patternProperties": { "\\wcole": true }, "additionalProperties": false }, "tests": [ { "description": "ascii character in json string", "data": { "l'ecole": "pas de vraie vie" }, "valid": true }, { "description": "literal unicode character in json string", "data": { "l'école": "pas de vraie vie" }, "valid": false }, { "description": "unicode character in hex format in string", "data": { "l'\u00e9cole": "pas de vraie vie" }, "valid": false }, { "description": "unicode matching is case-sensitive", "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, "valid": false } ] }, { "description": "patternProperties with ASCII ranges", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "patternProperties": { "[a-z]cole": true }, "additionalProperties": false }, "tests": [ { "description": "literal unicode character in json string", "data": { "l'école": "pas de vraie vie" }, "valid": false }, { "description": "unicode character in hex format in string", "data": { "l'\u00e9cole": "pas de vraie vie" }, "valid": false }, { "description": "ascii characters match", "data": { "l'ecole": "pas de vraie vie" }, "valid": true } ] }, { "description": "\\d in patternProperties matches [0-9], not unicode digits", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "patternProperties": { "^\\d+$": true }, "additionalProperties": false }, "tests": [ { "description": "ascii digits", "data": { "42": "life, the universe, and everything" }, "valid": true }, { "description": "ascii non-digits", "data": { "-%#": "spending the year dead for tax reasons" }, "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": { "৪২": "khajit has wares if you have coin" }, "valid": false } ] }, { "description": "patternProperties with non-ASCII digits", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "patternProperties": { "^\\p{digit}+$": true }, "additionalProperties": false }, "tests": [ { "description": "ascii digits", "data": { "42": "life, the universe, and everything" }, "valid": true }, { "description": "ascii non-digits", "data": { "-%#": "spending the year dead for tax reasons" }, "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": { "৪২": "khajit has wares if you have coin" }, "valid": true } ] } ] float-overflow.json000066400000000000000000000007061477700171100330600ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional[ { "description": "all integers are multiples of 0.5, if overflow is handled", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "integer", "multipleOf": 0.5 }, "tests": [ { "description": "valid if optional overflow handling is implemented", "data": 1e308, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/000077500000000000000000000000001477700171100305635ustar00rootroot00000000000000date-time.json000066400000000000000000000112131477700171100332460ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format[ { "description": "validation of date-time strings", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "date-time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid date-time string", "data": "1963-06-19T08:30:06.283185Z", "valid": true }, { "description": "a valid date-time string without second fraction", "data": "1963-06-19T08:30:06Z", "valid": true }, { "description": "a valid date-time string with plus offset", "data": "1937-01-01T12:00:27.87+00:20", "valid": true }, { "description": "a valid date-time string with minus offset", "data": "1990-12-31T15:59:50.123-08:00", "valid": true }, { "description": "a valid date-time with a leap second, UTC", "data": "1998-12-31T23:59:60Z", "valid": true }, { "description": "a valid date-time with a leap second, with minus offset", "data": "1998-12-31T15:59:60.123-08:00", "valid": true }, { "description": "an invalid date-time past leap second, UTC", "data": "1998-12-31T23:59:61Z", "valid": false }, { "description": "an invalid date-time with leap second on a wrong minute, UTC", "data": "1998-12-31T23:58:60Z", "valid": false }, { "description": "an invalid date-time with leap second on a wrong hour, UTC", "data": "1998-12-31T22:59:60Z", "valid": false }, { "description": "an invalid day in date-time string", "data": "1990-02-31T15:59:59.123-08:00", "valid": false }, { "description": "an invalid offset in date-time string", "data": "1990-12-31T15:59:59-24:00", "valid": false }, { "description": "an invalid closing Z after time-zone offset", "data": "1963-06-19T08:30:06.28123+01:00Z", "valid": false }, { "description": "an invalid date-time string", "data": "06/19/1963 08:30:06 PST", "valid": false }, { "description": "case-insensitive T and Z", "data": "1963-06-19t08:30:06.283185z", "valid": true }, { "description": "only RFC3339 not all of ISO 8601 are valid", "data": "2013-350T01:01:01", "valid": false }, { "description": "invalid non-padded month dates", "data": "1963-6-19T08:30:06.283185Z", "valid": false }, { "description": "invalid non-padded day dates", "data": "1963-06-1T08:30:06.283185Z", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4) in date portion", "data": "1963-06-1৪T00:00:00Z", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4) in time portion", "data": "1963-06-11T0৪:00:00Z", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/date.json000066400000000000000000000202051477700171100323720ustar00rootroot00000000000000[ { "description": "validation of date strings", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "date" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid date string", "data": "1963-06-19", "valid": true }, { "description": "a valid date string with 31 days in January", "data": "2020-01-31", "valid": true }, { "description": "a invalid date string with 32 days in January", "data": "2020-01-32", "valid": false }, { "description": "a valid date string with 28 days in February (normal)", "data": "2021-02-28", "valid": true }, { "description": "a invalid date string with 29 days in February (normal)", "data": "2021-02-29", "valid": false }, { "description": "a valid date string with 29 days in February (leap)", "data": "2020-02-29", "valid": true }, { "description": "a invalid date string with 30 days in February (leap)", "data": "2020-02-30", "valid": false }, { "description": "a valid date string with 31 days in March", "data": "2020-03-31", "valid": true }, { "description": "a invalid date string with 32 days in March", "data": "2020-03-32", "valid": false }, { "description": "a valid date string with 30 days in April", "data": "2020-04-30", "valid": true }, { "description": "a invalid date string with 31 days in April", "data": "2020-04-31", "valid": false }, { "description": "a valid date string with 31 days in May", "data": "2020-05-31", "valid": true }, { "description": "a invalid date string with 32 days in May", "data": "2020-05-32", "valid": false }, { "description": "a valid date string with 30 days in June", "data": "2020-06-30", "valid": true }, { "description": "a invalid date string with 31 days in June", "data": "2020-06-31", "valid": false }, { "description": "a valid date string with 31 days in July", "data": "2020-07-31", "valid": true }, { "description": "a invalid date string with 32 days in July", "data": "2020-07-32", "valid": false }, { "description": "a valid date string with 31 days in August", "data": "2020-08-31", "valid": true }, { "description": "a invalid date string with 32 days in August", "data": "2020-08-32", "valid": false }, { "description": "a valid date string with 30 days in September", "data": "2020-09-30", "valid": true }, { "description": "a invalid date string with 31 days in September", "data": "2020-09-31", "valid": false }, { "description": "a valid date string with 31 days in October", "data": "2020-10-31", "valid": true }, { "description": "a invalid date string with 32 days in October", "data": "2020-10-32", "valid": false }, { "description": "a valid date string with 30 days in November", "data": "2020-11-30", "valid": true }, { "description": "a invalid date string with 31 days in November", "data": "2020-11-31", "valid": false }, { "description": "a valid date string with 31 days in December", "data": "2020-12-31", "valid": true }, { "description": "a invalid date string with 32 days in December", "data": "2020-12-32", "valid": false }, { "description": "a invalid date string with invalid month", "data": "2020-13-01", "valid": false }, { "description": "an invalid date string", "data": "06/19/1963", "valid": false }, { "description": "only RFC3339 not all of ISO 8601 are valid", "data": "2013-350", "valid": false }, { "description": "non-padded month dates are not valid", "data": "1998-1-20", "valid": false }, { "description": "non-padded day dates are not valid", "data": "1998-01-1", "valid": false }, { "description": "invalid month", "data": "1998-13-01", "valid": false }, { "description": "invalid month-day combination", "data": "1998-04-31", "valid": false }, { "description": "2021 is not a leap year", "data": "2021-02-29", "valid": false }, { "description": "2020 is a leap year", "data": "2020-02-29", "valid": true }, { "description": "invalid non-ASCII '৪' (a Bengali 4)", "data": "1963-06-1৪", "valid": false }, { "description": "ISO8601 / non-RFC3339: YYYYMMDD without dashes (2023-03-28)", "data": "20230328", "valid": false }, { "description": "ISO8601 / non-RFC3339: week number implicit day of week (2023-01-02)", "data": "2023-W01", "valid": false }, { "description": "ISO8601 / non-RFC3339: week number with day of week (2023-03-28)", "data": "2023-W13-2", "valid": false }, { "description": "ISO8601 / non-RFC3339: week number rollover to next year (2023-01-01)", "data": "2022W527", "valid": false } ] } ] duration.json000066400000000000000000000077201477700171100332320ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format[ { "description": "validation of duration strings", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "duration" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid duration string", "data": "P4DT12H30M5S", "valid": true }, { "description": "an invalid duration string", "data": "PT1D", "valid": false }, { "description": "no elements present", "data": "P", "valid": false }, { "description": "no time elements present", "data": "P1YT", "valid": false }, { "description": "no date or time elements present", "data": "PT", "valid": false }, { "description": "elements out of order", "data": "P2D1Y", "valid": false }, { "description": "missing time separator", "data": "P1D2H", "valid": false }, { "description": "time element in the date position", "data": "P2S", "valid": false }, { "description": "four years duration", "data": "P4Y", "valid": true }, { "description": "zero time, in seconds", "data": "PT0S", "valid": true }, { "description": "zero time, in days", "data": "P0D", "valid": true }, { "description": "one month duration", "data": "P1M", "valid": true }, { "description": "one minute duration", "data": "PT1M", "valid": true }, { "description": "one and a half days, in hours", "data": "PT36H", "valid": true }, { "description": "one and a half days, in days and hours", "data": "P1DT12H", "valid": true }, { "description": "two weeks", "data": "P2W", "valid": true }, { "description": "weeks cannot be combined with other units", "data": "P1Y2W", "valid": false }, { "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "P২Y", "valid": false }, { "description": "element without unit", "data": "P1", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/email.json000066400000000000000000000052371477700171100325540ustar00rootroot00000000000000[ { "description": "validation of e-mail addresses", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "email" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid e-mail address", "data": "joe.bloggs@example.com", "valid": true }, { "description": "an invalid e-mail address", "data": "2962", "valid": false }, { "description": "tilde in local part is valid", "data": "te~st@example.com", "valid": true }, { "description": "tilde before local part is valid", "data": "~test@example.com", "valid": true }, { "description": "tilde after local part is valid", "data": "test~@example.com", "valid": true }, { "description": "dot before local part is not valid", "data": ".test@example.com", "valid": false }, { "description": "dot after local part is not valid", "data": "test.@example.com", "valid": false }, { "description": "two separated dots inside local part are valid", "data": "te.s.t@example.com", "valid": true }, { "description": "two subsequent dots inside local part are not valid", "data": "te..st@example.com", "valid": false } ] } ] hostname.json000066400000000000000000000077611477700171100332300ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format[ { "description": "validation of host names", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "hostname" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid host name", "data": "www.example.com", "valid": true }, { "description": "a valid punycoded IDN hostname", "data": "xn--4gbwdl.xn--wgbh1c", "valid": true }, { "description": "a host name starting with an illegal character", "data": "-a-host-name-that-starts-with--", "valid": false }, { "description": "a host name containing illegal characters", "data": "not_a_valid_host_name", "valid": false }, { "description": "a host name with a component too long", "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", "valid": false }, { "description": "starts with hyphen", "data": "-hostname", "valid": false }, { "description": "ends with hyphen", "data": "hostname-", "valid": false }, { "description": "starts with underscore", "data": "_hostname", "valid": false }, { "description": "ends with underscore", "data": "hostname_", "valid": false }, { "description": "contains underscore", "data": "host_name", "valid": false }, { "description": "maximum label length", "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.com", "valid": true }, { "description": "exceeds maximum label length", "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl.com", "valid": false }, { "description": "single label", "data": "hostname", "valid": true }, { "description": "single label with hyphen", "data": "host-name", "valid": true }, { "description": "single label with digits", "data": "h0stn4me", "valid": true }, { "description": "single label starting with digit", "data": "1host", "valid": true }, { "description": "single label ending with digit", "data": "hostnam3", "valid": true } ] } ] idn-email.json000066400000000000000000000035071477700171100332430ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format[ { "description": "validation of an internationalized e-mail addresses", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "idn-email" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid idn e-mail (example@example.test in Hangul)", "data": "실례@실례.테스트", "valid": true }, { "description": "an invalid idn e-mail address", "data": "2962", "valid": false }, { "description": "a valid e-mail address", "data": "joe.bloggs@example.com", "valid": true }, { "description": "an invalid e-mail address", "data": "2962", "valid": false } ] } ] idn-hostname.json000066400000000000000000000363761477700171100340040ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format[ { "description": "validation of internationalized host names", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "idn-hostname" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid host name (example.test in Hangul)", "data": "실례.테스트", "valid": true }, { "description": "illegal first char U+302E Hangul single dot tone mark", "data": "〮실례.테스트", "valid": false }, { "description": "contains illegal char U+302E Hangul single dot tone mark", "data": "실〮례.테스트", "valid": false }, { "description": "a host name with a component too long", "data": "실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실례례테스트례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례테스트례례실례.테스트", "valid": false }, { "description": "invalid label, correct Punycode", "comment": "https://tools.ietf.org/html/rfc5890#section-2.3.2.1 https://tools.ietf.org/html/rfc5891#section-4.4 https://tools.ietf.org/html/rfc3492#section-7.1", "data": "-> $1.00 <--", "valid": false }, { "description": "valid Chinese Punycode", "comment": "https://tools.ietf.org/html/rfc5890#section-2.3.2.1 https://tools.ietf.org/html/rfc5891#section-4.4", "data": "xn--ihqwcrb4cv8a8dqg056pqjye", "valid": true }, { "description": "invalid Punycode", "comment": "https://tools.ietf.org/html/rfc5891#section-4.4 https://tools.ietf.org/html/rfc5890#section-2.3.2.1", "data": "xn--X", "valid": false }, { "description": "U-label contains \"--\" in the 3rd and 4th position", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1 https://tools.ietf.org/html/rfc5890#section-2.3.2.1", "data": "XN--aa---o47jg78q", "valid": false }, { "description": "U-label starts with a dash", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", "data": "-hello", "valid": false }, { "description": "U-label ends with a dash", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", "data": "hello-", "valid": false }, { "description": "U-label starts and ends with a dash", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", "data": "-hello-", "valid": false }, { "description": "Begins with a Spacing Combining Mark", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", "data": "\u0903hello", "valid": false }, { "description": "Begins with a Nonspacing Mark", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", "data": "\u0300hello", "valid": false }, { "description": "Begins with an Enclosing Mark", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", "data": "\u0488hello", "valid": false }, { "description": "Exceptions that are PVALID, left-to-right chars", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", "data": "\u00df\u03c2\u0f0b\u3007", "valid": true }, { "description": "Exceptions that are PVALID, right-to-left chars", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", "data": "\u06fd\u06fe", "valid": true }, { "description": "Exceptions that are DISALLOWED, right-to-left chars", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", "data": "\u0640\u07fa", "valid": false }, { "description": "Exceptions that are DISALLOWED, left-to-right chars", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6 Note: The two combining marks (U+302E and U+302F) are in the middle and not at the start", "data": "\u3031\u3032\u3033\u3034\u3035\u302e\u302f\u303b", "valid": false }, { "description": "MIDDLE DOT with no preceding 'l'", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", "data": "a\u00b7l", "valid": false }, { "description": "MIDDLE DOT with nothing preceding", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", "data": "\u00b7l", "valid": false }, { "description": "MIDDLE DOT with no following 'l'", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", "data": "l\u00b7a", "valid": false }, { "description": "MIDDLE DOT with nothing following", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", "data": "l\u00b7", "valid": false }, { "description": "MIDDLE DOT with surrounding 'l's", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", "data": "l\u00b7l", "valid": true }, { "description": "Greek KERAIA not followed by Greek", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", "data": "\u03b1\u0375S", "valid": false }, { "description": "Greek KERAIA not followed by anything", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", "data": "\u03b1\u0375", "valid": false }, { "description": "Greek KERAIA followed by Greek", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", "data": "\u03b1\u0375\u03b2", "valid": true }, { "description": "Hebrew GERESH not preceded by Hebrew", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", "data": "A\u05f3\u05d1", "valid": false }, { "description": "Hebrew GERESH not preceded by anything", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", "data": "\u05f3\u05d1", "valid": false }, { "description": "Hebrew GERESH preceded by Hebrew", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", "data": "\u05d0\u05f3\u05d1", "valid": true }, { "description": "Hebrew GERSHAYIM not preceded by Hebrew", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", "data": "A\u05f4\u05d1", "valid": false }, { "description": "Hebrew GERSHAYIM not preceded by anything", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", "data": "\u05f4\u05d1", "valid": false }, { "description": "Hebrew GERSHAYIM preceded by Hebrew", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", "data": "\u05d0\u05f4\u05d1", "valid": true }, { "description": "KATAKANA MIDDLE DOT with no Hiragana, Katakana, or Han", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", "data": "def\u30fbabc", "valid": false }, { "description": "KATAKANA MIDDLE DOT with no other characters", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", "data": "\u30fb", "valid": false }, { "description": "KATAKANA MIDDLE DOT with Hiragana", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", "data": "\u30fb\u3041", "valid": true }, { "description": "KATAKANA MIDDLE DOT with Katakana", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", "data": "\u30fb\u30a1", "valid": true }, { "description": "KATAKANA MIDDLE DOT with Han", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", "data": "\u30fb\u4e08", "valid": true }, { "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", "data": "\u0660\u06f0", "valid": false }, { "description": "Arabic-Indic digits not mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", "data": "\u0628\u0660\u0628", "valid": true }, { "description": "Extended Arabic-Indic digits not mixed with Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.9", "data": "\u06f00", "valid": true }, { "description": "ZERO WIDTH JOINER not preceded by Virama", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", "data": "\u0915\u200d\u0937", "valid": false }, { "description": "ZERO WIDTH JOINER not preceded by anything", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", "data": "\u200d\u0937", "valid": false }, { "description": "ZERO WIDTH JOINER preceded by Virama", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", "data": "\u0915\u094d\u200d\u0937", "valid": true }, { "description": "ZERO WIDTH NON-JOINER preceded by Virama", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1", "data": "\u0915\u094d\u200c\u0937", "valid": true }, { "description": "ZERO WIDTH NON-JOINER not preceded by Virama but matches regexp", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1 https://www.w3.org/TR/alreq/#h_disjoining_enforcement", "data": "\u0628\u064a\u200c\u0628\u064a", "valid": true }, { "description": "single label", "data": "hostname", "valid": true }, { "description": "single label with hyphen", "data": "host-name", "valid": true }, { "description": "single label with digits", "data": "h0stn4me", "valid": true }, { "description": "single label starting with digit", "data": "1host", "valid": true }, { "description": "single label ending with digit", "data": "hostnam3", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/ipv4.json000066400000000000000000000060151477700171100323420ustar00rootroot00000000000000[ { "description": "validation of IP addresses", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "ipv4" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid IP address", "data": "192.168.0.1", "valid": true }, { "description": "an IP address with too many components", "data": "127.0.0.0.1", "valid": false }, { "description": "an IP address with out-of-range values", "data": "256.256.256.256", "valid": false }, { "description": "an IP address without 4 components", "data": "127.0", "valid": false }, { "description": "an IP address as an integer", "data": "0x7f000001", "valid": false }, { "description": "an IP address as an integer (decimal)", "data": "2130706433", "valid": false }, { "description": "invalid leading zeroes, as they are treated as octals", "comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/", "data": "087.10.0.1", "valid": false }, { "description": "value without leading zero is valid", "data": "87.10.0.1", "valid": true }, { "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২7.0.0.1", "valid": false }, { "description": "netmask is not a part of ipv4 address", "data": "192.168.1.0/24", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/ipv6.json000066400000000000000000000155721477700171100323540ustar00rootroot00000000000000[ { "description": "validation of IPv6 addresses", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "ipv6" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid IPv6 address", "data": "::1", "valid": true }, { "description": "an IPv6 address with out-of-range values", "data": "12345::", "valid": false }, { "description": "trailing 4 hex symbols is valid", "data": "::abef", "valid": true }, { "description": "trailing 5 hex symbols is invalid", "data": "::abcef", "valid": false }, { "description": "an IPv6 address with too many components", "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", "valid": false }, { "description": "an IPv6 address containing illegal characters", "data": "::laptop", "valid": false }, { "description": "no digits is valid", "data": "::", "valid": true }, { "description": "leading colons is valid", "data": "::42:ff:1", "valid": true }, { "description": "trailing colons is valid", "data": "d6::", "valid": true }, { "description": "missing leading octet is invalid", "data": ":2:3:4:5:6:7:8", "valid": false }, { "description": "missing trailing octet is invalid", "data": "1:2:3:4:5:6:7:", "valid": false }, { "description": "missing leading octet with omitted octets later", "data": ":2:3:4::8", "valid": false }, { "description": "single set of double colons in the middle is valid", "data": "1:d6::42", "valid": true }, { "description": "two sets of double colons is invalid", "data": "1::d6::42", "valid": false }, { "description": "mixed format with the ipv4 section as decimal octets", "data": "1::d6:192.168.0.1", "valid": true }, { "description": "mixed format with double colons between the sections", "data": "1:2::192.168.0.1", "valid": true }, { "description": "mixed format with ipv4 section with octet out of range", "data": "1::2:192.168.256.1", "valid": false }, { "description": "mixed format with ipv4 section with a hex octet", "data": "1::2:192.168.ff.1", "valid": false }, { "description": "mixed format with leading double colons (ipv4-mapped ipv6 address)", "data": "::ffff:192.168.0.1", "valid": true }, { "description": "triple colons is invalid", "data": "1:2:3:4:5:::8", "valid": false }, { "description": "8 octets", "data": "1:2:3:4:5:6:7:8", "valid": true }, { "description": "insufficient octets without double colons", "data": "1:2:3:4:5:6:7", "valid": false }, { "description": "no colons is invalid", "data": "1", "valid": false }, { "description": "ipv4 is not ipv6", "data": "127.0.0.1", "valid": false }, { "description": "ipv4 segment must have 4 octets", "data": "1:2:3:4:1.2.3", "valid": false }, { "description": "leading whitespace is invalid", "data": " ::1", "valid": false }, { "description": "trailing whitespace is invalid", "data": "::1 ", "valid": false }, { "description": "netmask is not a part of ipv6 address", "data": "fe80::/64", "valid": false }, { "description": "zone id is not a part of ipv6 address", "data": "fe80::a%eth1", "valid": false }, { "description": "a long valid ipv6", "data": "1000:1000:1000:1000:1000:1000:255.255.255.255", "valid": true }, { "description": "a long invalid ipv6, below length limit, first", "data": "100:100:100:100:100:100:255.255.255.255.255", "valid": false }, { "description": "a long invalid ipv6, below length limit, second", "data": "100:100:100:100:100:100:100:255.255.255.255", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4)", "data": "1:2:3:4:5:6:7:৪", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4) in the IPv4 portion", "data": "1:2::192.16৪.0.1", "valid": false } ] } ] iri-reference.json000066400000000000000000000044451477700171100341250ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format[ { "description": "validation of IRI References", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "iri-reference" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid IRI", "data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx", "valid": true }, { "description": "a valid protocol-relative IRI Reference", "data": "//ƒøø.ßår/?∂éœ=πîx#πîüx", "valid": true }, { "description": "a valid relative IRI Reference", "data": "/âππ", "valid": true }, { "description": "an invalid IRI Reference", "data": "\\\\WINDOWS\\filëßåré", "valid": false }, { "description": "a valid IRI Reference", "data": "âππ", "valid": true }, { "description": "a valid IRI fragment", "data": "#ƒrägmênt", "valid": true }, { "description": "an invalid IRI fragment", "data": "#ƒräg\\mênt", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/iri.json000066400000000000000000000054571477700171100322540ustar00rootroot00000000000000[ { "description": "validation of IRIs", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "iri" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid IRI with anchor tag", "data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx", "valid": true }, { "description": "a valid IRI with anchor tag and parentheses", "data": "http://ƒøø.com/blah_(wîkïpédiå)_blah#ßité-1", "valid": true }, { "description": "a valid IRI with URL-encoded stuff", "data": "http://ƒøø.ßår/?q=Test%20URL-encoded%20stuff", "valid": true }, { "description": "a valid IRI with many special characters", "data": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", "valid": true }, { "description": "a valid IRI based on IPv6", "data": "http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]", "valid": true }, { "description": "an invalid IRI based on IPv6", "data": "http://2001:0db8:85a3:0000:0000:8a2e:0370:7334", "valid": false }, { "description": "an invalid relative IRI Reference", "data": "/abc", "valid": false }, { "description": "an invalid IRI", "data": "\\\\WINDOWS\\filëßåré", "valid": false }, { "description": "an invalid IRI though valid IRI reference", "data": "âππ", "valid": false } ] } ] json-pointer.json000066400000000000000000000152161477700171100340330ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format[ { "description": "validation of JSON-pointers (JSON String Representation)", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "json-pointer" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid JSON-pointer", "data": "/foo/bar~0/baz~1/%a", "valid": true }, { "description": "not a valid JSON-pointer (~ not escaped)", "data": "/foo/bar~", "valid": false }, { "description": "valid JSON-pointer with empty segment", "data": "/foo//bar", "valid": true }, { "description": "valid JSON-pointer with the last empty segment", "data": "/foo/bar/", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #1", "data": "", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #2", "data": "/foo", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #3", "data": "/foo/0", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #4", "data": "/", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #5", "data": "/a~1b", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #6", "data": "/c%d", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #7", "data": "/e^f", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #8", "data": "/g|h", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #9", "data": "/i\\j", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #10", "data": "/k\"l", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #11", "data": "/ ", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #12", "data": "/m~0n", "valid": true }, { "description": "valid JSON-pointer used adding to the last array position", "data": "/foo/-", "valid": true }, { "description": "valid JSON-pointer (- used as object member name)", "data": "/foo/-/bar", "valid": true }, { "description": "valid JSON-pointer (multiple escaped characters)", "data": "/~1~0~0~1~1", "valid": true }, { "description": "valid JSON-pointer (escaped with fraction part) #1", "data": "/~1.1", "valid": true }, { "description": "valid JSON-pointer (escaped with fraction part) #2", "data": "/~0.1", "valid": true }, { "description": "not a valid JSON-pointer (URI Fragment Identifier) #1", "data": "#", "valid": false }, { "description": "not a valid JSON-pointer (URI Fragment Identifier) #2", "data": "#/", "valid": false }, { "description": "not a valid JSON-pointer (URI Fragment Identifier) #3", "data": "#a", "valid": false }, { "description": "not a valid JSON-pointer (some escaped, but not all) #1", "data": "/~0~", "valid": false }, { "description": "not a valid JSON-pointer (some escaped, but not all) #2", "data": "/~0/~", "valid": false }, { "description": "not a valid JSON-pointer (wrong escape character) #1", "data": "/~2", "valid": false }, { "description": "not a valid JSON-pointer (wrong escape character) #2", "data": "/~-1", "valid": false }, { "description": "not a valid JSON-pointer (multiple characters not escaped)", "data": "/~~", "valid": false }, { "description": "not a valid JSON-pointer (isn't empty nor starts with /) #1", "data": "a", "valid": false }, { "description": "not a valid JSON-pointer (isn't empty nor starts with /) #2", "data": "0", "valid": false }, { "description": "not a valid JSON-pointer (isn't empty nor starts with /) #3", "data": "a/a", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/regex.json000066400000000000000000000027511477700171100325750ustar00rootroot00000000000000[ { "description": "validation of regular expressions", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "regex" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid regular expression", "data": "([abc])+\\s+$", "valid": true }, { "description": "a regular expression with unclosed parens is invalid", "data": "^(abc]", "valid": false } ] } ] relative-json-pointer.json000066400000000000000000000060761477700171100356500ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format[ { "description": "validation of Relative JSON Pointers (RJP)", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "relative-json-pointer" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid upwards RJP", "data": "1", "valid": true }, { "description": "a valid downwards RJP", "data": "0/foo/bar", "valid": true }, { "description": "a valid up and then down RJP, with array index", "data": "2/0/baz/1/zip", "valid": true }, { "description": "a valid RJP taking the member or index name", "data": "0#", "valid": true }, { "description": "an invalid RJP that is a valid JSON Pointer", "data": "/foo/bar", "valid": false }, { "description": "negative prefix", "data": "-1/foo/bar", "valid": false }, { "description": "explicit positive prefix", "data": "+1/foo/bar", "valid": false }, { "description": "## is not a valid json-pointer", "data": "0##", "valid": false }, { "description": "zero cannot be followed by other digits, plus json-pointer", "data": "01/a", "valid": false }, { "description": "zero cannot be followed by other digits, plus octothorpe", "data": "01#", "valid": false }, { "description": "empty string", "data": "", "valid": false }, { "description": "multi-digit integer prefix", "data": "120/foo/bar", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/time.json000066400000000000000000000176401477700171100324240ustar00rootroot00000000000000[ { "description": "validation of time strings", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid time string", "data": "08:30:06Z", "valid": true }, { "description": "invalid time string with extra leading zeros", "data": "008:030:006Z", "valid": false }, { "description": "invalid time string with no leading zero for single digit", "data": "8:3:6Z", "valid": false }, { "description": "hour, minute, second must be two digits", "data": "8:0030:6Z", "valid": false }, { "description": "a valid time string with leap second, Zulu", "data": "23:59:60Z", "valid": true }, { "description": "invalid leap second, Zulu (wrong hour)", "data": "22:59:60Z", "valid": false }, { "description": "invalid leap second, Zulu (wrong minute)", "data": "23:58:60Z", "valid": false }, { "description": "valid leap second, zero time-offset", "data": "23:59:60+00:00", "valid": true }, { "description": "invalid leap second, zero time-offset (wrong hour)", "data": "22:59:60+00:00", "valid": false }, { "description": "invalid leap second, zero time-offset (wrong minute)", "data": "23:58:60+00:00", "valid": false }, { "description": "valid leap second, positive time-offset", "data": "01:29:60+01:30", "valid": true }, { "description": "valid leap second, large positive time-offset", "data": "23:29:60+23:30", "valid": true }, { "description": "invalid leap second, positive time-offset (wrong hour)", "data": "23:59:60+01:00", "valid": false }, { "description": "invalid leap second, positive time-offset (wrong minute)", "data": "23:59:60+00:30", "valid": false }, { "description": "valid leap second, negative time-offset", "data": "15:59:60-08:00", "valid": true }, { "description": "valid leap second, large negative time-offset", "data": "00:29:60-23:30", "valid": true }, { "description": "invalid leap second, negative time-offset (wrong hour)", "data": "23:59:60-01:00", "valid": false }, { "description": "invalid leap second, negative time-offset (wrong minute)", "data": "23:59:60-00:30", "valid": false }, { "description": "a valid time string with second fraction", "data": "23:20:50.52Z", "valid": true }, { "description": "a valid time string with precise second fraction", "data": "08:30:06.283185Z", "valid": true }, { "description": "a valid time string with plus offset", "data": "08:30:06+00:20", "valid": true }, { "description": "a valid time string with minus offset", "data": "08:30:06-08:00", "valid": true }, { "description": "hour, minute in time-offset must be two digits", "data": "08:30:06-8:000", "valid": false }, { "description": "a valid time string with case-insensitive Z", "data": "08:30:06z", "valid": true }, { "description": "an invalid time string with invalid hour", "data": "24:00:00Z", "valid": false }, { "description": "an invalid time string with invalid minute", "data": "00:60:00Z", "valid": false }, { "description": "an invalid time string with invalid second", "data": "00:00:61Z", "valid": false }, { "description": "an invalid time string with invalid leap second (wrong hour)", "data": "22:59:60Z", "valid": false }, { "description": "an invalid time string with invalid leap second (wrong minute)", "data": "23:58:60Z", "valid": false }, { "description": "an invalid time string with invalid time numoffset hour", "data": "01:02:03+24:00", "valid": false }, { "description": "an invalid time string with invalid time numoffset minute", "data": "01:02:03+00:60", "valid": false }, { "description": "an invalid time string with invalid time with both Z and numoffset", "data": "01:02:03Z+00:30", "valid": false }, { "description": "an invalid offset indicator", "data": "08:30:06 PST", "valid": false }, { "description": "only RFC3339 not all of ISO 8601 are valid", "data": "01:01:01,1111", "valid": false }, { "description": "no time offset", "data": "12:00:00", "valid": false }, { "description": "no time offset with second fraction", "data": "12:00:00.52", "valid": false }, { "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২:00:00Z", "valid": false }, { "description": "offset not starting with plus or minus", "data": "08:30:06#00:20", "valid": false }, { "description": "contains letters", "data": "ab:cd:ef", "valid": false } ] } ] unknown.json000066400000000000000000000024161477700171100331010ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format[ { "description": "unknown format", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "unknown" }, "tests": [ { "description": "unknown formats ignore integers", "data": 12, "valid": true }, { "description": "unknown formats ignore floats", "data": 13.7, "valid": true }, { "description": "unknown formats ignore objects", "data": {}, "valid": true }, { "description": "unknown formats ignore arrays", "data": [], "valid": true }, { "description": "unknown formats ignore booleans", "data": false, "valid": true }, { "description": "unknown formats ignore nulls", "data": null, "valid": true }, { "description": "unknown formats ignore strings", "data": "string", "valid": true } ] } ] uri-reference.json000066400000000000000000000043721477700171100341400ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format[ { "description": "validation of URI References", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "uri-reference" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid URI", "data": "http://foo.bar/?baz=qux#quux", "valid": true }, { "description": "a valid protocol-relative URI Reference", "data": "//foo.bar/?baz=qux#quux", "valid": true }, { "description": "a valid relative URI Reference", "data": "/abc", "valid": true }, { "description": "an invalid URI Reference", "data": "\\\\WINDOWS\\fileshare", "valid": false }, { "description": "a valid URI Reference", "data": "abc", "valid": true }, { "description": "a valid URI fragment", "data": "#fragment", "valid": true }, { "description": "an invalid URI fragment", "data": "#frag\\ment", "valid": false } ] } ] uri-template.json000066400000000000000000000035641477700171100340170ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format[ { "description": "format: uri-template", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "uri-template" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid uri-template", "data": "http://example.com/dictionary/{term:1}/{term}", "valid": true }, { "description": "an invalid uri-template", "data": "http://example.com/dictionary/{term:1}/{term", "valid": false }, { "description": "a valid uri-template without variables", "data": "http://example.com/dictionary", "valid": true }, { "description": "a valid relative uri-template", "data": "dictionary/{term:1}/{term}", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/uri.json000066400000000000000000000111671477700171100322630ustar00rootroot00000000000000[ { "description": "validation of URIs", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "uri" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid URL with anchor tag", "data": "http://foo.bar/?baz=qux#quux", "valid": true }, { "description": "a valid URL with anchor tag and parentheses", "data": "http://foo.com/blah_(wikipedia)_blah#cite-1", "valid": true }, { "description": "a valid URL with URL-encoded stuff", "data": "http://foo.bar/?q=Test%20URL-encoded%20stuff", "valid": true }, { "description": "a valid puny-coded URL ", "data": "http://xn--nw2a.xn--j6w193g/", "valid": true }, { "description": "a valid URL with many special characters", "data": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", "valid": true }, { "description": "a valid URL based on IPv4", "data": "http://223.255.255.254", "valid": true }, { "description": "a valid URL with ftp scheme", "data": "ftp://ftp.is.co.za/rfc/rfc1808.txt", "valid": true }, { "description": "a valid URL for a simple text file", "data": "http://www.ietf.org/rfc/rfc2396.txt", "valid": true }, { "description": "a valid URL ", "data": "ldap://[2001:db8::7]/c=GB?objectClass?one", "valid": true }, { "description": "a valid mailto URI", "data": "mailto:John.Doe@example.com", "valid": true }, { "description": "a valid newsgroup URI", "data": "news:comp.infosystems.www.servers.unix", "valid": true }, { "description": "a valid tel URI", "data": "tel:+1-816-555-1212", "valid": true }, { "description": "a valid URN", "data": "urn:oasis:names:specification:docbook:dtd:xml:4.1.2", "valid": true }, { "description": "an invalid protocol-relative URI Reference", "data": "//foo.bar/?baz=qux#quux", "valid": false }, { "description": "an invalid relative URI Reference", "data": "/abc", "valid": false }, { "description": "an invalid URI", "data": "\\\\WINDOWS\\fileshare", "valid": false }, { "description": "an invalid URI though valid URI reference", "data": "abc", "valid": false }, { "description": "an invalid URI with spaces", "data": "http:// shouldfail.com", "valid": false }, { "description": "an invalid URI with spaces and missing scheme", "data": ":// should fail", "valid": false }, { "description": "an invalid URI with comma in scheme", "data": "bar,baz:foo", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/uuid.json000066400000000000000000000072571477700171100324370ustar00rootroot00000000000000[ { "description": "uuid format", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "format": "uuid" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "all upper-case", "data": "2EB8AA08-AA98-11EA-B4AA-73B441D16380", "valid": true }, { "description": "all lower-case", "data": "2eb8aa08-aa98-11ea-b4aa-73b441d16380", "valid": true }, { "description": "mixed case", "data": "2eb8aa08-AA98-11ea-B4Aa-73B441D16380", "valid": true }, { "description": "all zeroes is valid", "data": "00000000-0000-0000-0000-000000000000", "valid": true }, { "description": "wrong length", "data": "2eb8aa08-aa98-11ea-b4aa-73b441d1638", "valid": false }, { "description": "missing section", "data": "2eb8aa08-aa98-11ea-73b441d16380", "valid": false }, { "description": "bad characters (not hex)", "data": "2eb8aa08-aa98-11ea-b4ga-73b441d16380", "valid": false }, { "description": "no dashes", "data": "2eb8aa08aa9811eab4aa73b441d16380", "valid": false }, { "description": "too few dashes", "data": "2eb8aa08aa98-11ea-b4aa73b441d16380", "valid": false }, { "description": "too many dashes", "data": "2eb8-aa08-aa98-11ea-b4aa73b44-1d16380", "valid": false }, { "description": "dashes in the wrong spot", "data": "2eb8aa08aa9811eab4aa73b441d16380----", "valid": false }, { "description": "valid version 4", "data": "98d80576-482e-427f-8434-7f86890ab222", "valid": true }, { "description": "valid version 5", "data": "99c17cbb-656f-564a-940f-1a4568f03487", "valid": true }, { "description": "hypothetical version 6", "data": "99c17cbb-656f-664a-940f-1a4568f03487", "valid": true }, { "description": "hypothetical version 15", "data": "99c17cbb-656f-f64a-940f-1a4568f03487", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/no-schema.json000066400000000000000000000012361477700171100320420ustar00rootroot00000000000000[ { "description": "validation without $schema", "comment": "minLength is the same across all drafts", "schema": { "minLength": 2 }, "tests": [ { "description": "a 3-character string is valid", "data": "foo", "valid": true }, { "description": "a 1-character string is not valid", "data": "a", "valid": false }, { "description": "a non-string is valid", "data": 5, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/non-bmp-regex.json000066400000000000000000000050001477700171100326370ustar00rootroot00000000000000[ { "description": "Proper UTF-16 surrogate pair handling: pattern", "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "pattern": "^🐲*$" }, "tests": [ { "description": "matches empty", "data": "", "valid": true }, { "description": "matches single", "data": "🐲", "valid": true }, { "description": "matches two", "data": "🐲🐲", "valid": true }, { "description": "doesn't match one", "data": "🐉", "valid": false }, { "description": "doesn't match two", "data": "🐉🐉", "valid": false }, { "description": "doesn't match one ASCII", "data": "D", "valid": false }, { "description": "doesn't match two ASCII", "data": "DD", "valid": false } ] }, { "description": "Proper UTF-16 surrogate pair handling: patternProperties", "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "patternProperties": { "^🐲*$": { "type": "integer" } } }, "tests": [ { "description": "matches empty", "data": { "": 1 }, "valid": true }, { "description": "matches single", "data": { "🐲": 1 }, "valid": true }, { "description": "matches two", "data": { "🐲🐲": 1 }, "valid": true }, { "description": "doesn't match one", "data": { "🐲": "hello" }, "valid": false }, { "description": "doesn't match two", "data": { "🐲🐲": "hello" }, "valid": false } ] } ] refOfUnknownKeyword.json000066400000000000000000000036041477700171100341000ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional[ { "description": "reference of a root arbitrary keyword ", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "unknown-keyword": {"type": "integer"}, "properties": { "bar": {"$ref": "#/unknown-keyword"} } }, "tests": [ { "description": "match", "data": {"bar": 3}, "valid": true }, { "description": "mismatch", "data": {"bar": true}, "valid": false } ] }, { "description": "reference of an arbitrary keyword of a sub-schema", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "foo": {"unknown-keyword": {"type": "integer"}}, "bar": {"$ref": "#/properties/foo/unknown-keyword"} } }, "tests": [ { "description": "match", "data": {"bar": 3}, "valid": true }, { "description": "mismatch", "data": {"bar": true}, "valid": false } ] }, { "description": "reference internals of known non-applicator", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "/base", "examples": [ { "type": "string" } ], "$ref": "#/examples/0" }, "tests": [ { "description": "match", "data": "a string", "valid": true }, { "description": "mismatch", "data": 42, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/pattern.json000066400000000000000000000032751477700171100300250ustar00rootroot00000000000000[ { "description": "pattern validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "pattern": "^a*$" }, "tests": [ { "description": "a matching pattern is valid", "data": "aaa", "valid": true }, { "description": "a non-matching pattern is invalid", "data": "abc", "valid": false }, { "description": "ignores booleans", "data": true, "valid": true }, { "description": "ignores integers", "data": 123, "valid": true }, { "description": "ignores floats", "data": 1.0, "valid": true }, { "description": "ignores objects", "data": {}, "valid": true }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores null", "data": null, "valid": true } ] }, { "description": "pattern is not anchored", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "pattern": "a+" }, "tests": [ { "description": "matches a substring", "data": "xxaayy", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/patternProperties.json000066400000000000000000000126341477700171100321010ustar00rootroot00000000000000[ { "description": "patternProperties validates properties matching a regex", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "patternProperties": { "f.*o": {"type": "integer"} } }, "tests": [ { "description": "a single valid match is valid", "data": {"foo": 1}, "valid": true }, { "description": "multiple valid matches is valid", "data": {"foo": 1, "foooooo" : 2}, "valid": true }, { "description": "a single invalid match is invalid", "data": {"foo": "bar", "fooooo": 2}, "valid": false }, { "description": "multiple invalid matches is invalid", "data": {"foo": "bar", "foooooo" : "baz"}, "valid": false }, { "description": "ignores arrays", "data": ["foo"], "valid": true }, { "description": "ignores strings", "data": "foo", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "multiple simultaneous patternProperties are validated", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "patternProperties": { "a*": {"type": "integer"}, "aaa*": {"maximum": 20} } }, "tests": [ { "description": "a single valid match is valid", "data": {"a": 21}, "valid": true }, { "description": "a simultaneous match is valid", "data": {"aaaa": 18}, "valid": true }, { "description": "multiple matches is valid", "data": {"a": 21, "aaaa": 18}, "valid": true }, { "description": "an invalid due to one is invalid", "data": {"a": "bar"}, "valid": false }, { "description": "an invalid due to the other is invalid", "data": {"aaaa": 31}, "valid": false }, { "description": "an invalid due to both is invalid", "data": {"aaa": "foo", "aaaa": 31}, "valid": false } ] }, { "description": "regexes are not anchored by default and are case sensitive", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "patternProperties": { "[0-9]{2,}": { "type": "boolean" }, "X_": { "type": "string" } } }, "tests": [ { "description": "non recognized members are ignored", "data": { "answer 1": "42" }, "valid": true }, { "description": "recognized members are accounted for", "data": { "a31b": null }, "valid": false }, { "description": "regexes are case sensitive", "data": { "a_x_3": 3 }, "valid": true }, { "description": "regexes are case sensitive, 2", "data": { "a_X_3": 3 }, "valid": false } ] }, { "description": "patternProperties with boolean schemas", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "patternProperties": { "f.*": true, "b.*": false } }, "tests": [ { "description": "object with property matching schema true is valid", "data": {"foo": 1}, "valid": true }, { "description": "object with property matching schema false is invalid", "data": {"bar": 2}, "valid": false }, { "description": "object with both properties is invalid", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "object with a property matching both true and false is invalid", "data": {"foobar":1}, "valid": false }, { "description": "empty object is valid", "data": {}, "valid": true } ] }, { "description": "patternProperties with null valued instance properties", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "patternProperties": { "^.*bar$": {"type": "null"} } }, "tests": [ { "description": "allows null values", "data": {"foobar": null}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/properties.json000066400000000000000000000170631477700171100305440ustar00rootroot00000000000000[ { "description": "object properties validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "foo": {"type": "integer"}, "bar": {"type": "string"} } }, "tests": [ { "description": "both properties present and valid is valid", "data": {"foo": 1, "bar": "baz"}, "valid": true }, { "description": "one property invalid is invalid", "data": {"foo": 1, "bar": {}}, "valid": false }, { "description": "both properties invalid is invalid", "data": {"foo": [], "bar": {}}, "valid": false }, { "description": "doesn't invalidate other properties", "data": {"quux": []}, "valid": true }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "properties, patternProperties, additionalProperties interaction", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "foo": {"type": "array", "maxItems": 3}, "bar": {"type": "array"} }, "patternProperties": {"f.o": {"minItems": 2}}, "additionalProperties": {"type": "integer"} }, "tests": [ { "description": "property validates property", "data": {"foo": [1, 2]}, "valid": true }, { "description": "property invalidates property", "data": {"foo": [1, 2, 3, 4]}, "valid": false }, { "description": "patternProperty invalidates property", "data": {"foo": []}, "valid": false }, { "description": "patternProperty validates nonproperty", "data": {"fxo": [1, 2]}, "valid": true }, { "description": "patternProperty invalidates nonproperty", "data": {"fxo": []}, "valid": false }, { "description": "additionalProperty ignores property", "data": {"bar": []}, "valid": true }, { "description": "additionalProperty validates others", "data": {"quux": 3}, "valid": true }, { "description": "additionalProperty invalidates others", "data": {"quux": "foo"}, "valid": false } ] }, { "description": "properties with boolean schema", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "foo": true, "bar": false } }, "tests": [ { "description": "no property present is valid", "data": {}, "valid": true }, { "description": "only 'true' property present is valid", "data": {"foo": 1}, "valid": true }, { "description": "only 'false' property present is invalid", "data": {"bar": 2}, "valid": false }, { "description": "both properties present is invalid", "data": {"foo": 1, "bar": 2}, "valid": false } ] }, { "description": "properties with escaped characters", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "foo\nbar": {"type": "number"}, "foo\"bar": {"type": "number"}, "foo\\bar": {"type": "number"}, "foo\rbar": {"type": "number"}, "foo\tbar": {"type": "number"}, "foo\fbar": {"type": "number"} } }, "tests": [ { "description": "object with all numbers is valid", "data": { "foo\nbar": 1, "foo\"bar": 1, "foo\\bar": 1, "foo\rbar": 1, "foo\tbar": 1, "foo\fbar": 1 }, "valid": true }, { "description": "object with strings is invalid", "data": { "foo\nbar": "1", "foo\"bar": "1", "foo\\bar": "1", "foo\rbar": "1", "foo\tbar": "1", "foo\fbar": "1" }, "valid": false } ] }, { "description": "properties with null valued instance properties", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "foo": {"type": "null"} } }, "tests": [ { "description": "allows null values", "data": {"foo": null}, "valid": true } ] }, { "description": "properties whose names are Javascript object property names", "comment": "Ensure JS implementations don't universally consider e.g. __proto__ to always be present in an object.", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "__proto__": {"type": "number"}, "toString": { "properties": { "length": { "type": "string" } } }, "constructor": {"type": "number"} } }, "tests": [ { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true }, { "description": "none of the properties mentioned", "data": {}, "valid": true }, { "description": "__proto__ not valid", "data": { "__proto__": "foo" }, "valid": false }, { "description": "toString not valid", "data": { "toString": { "length": 37 } }, "valid": false }, { "description": "constructor not valid", "data": { "constructor": { "length": 37 } }, "valid": false }, { "description": "all present and valid", "data": { "__proto__": 12, "toString": { "length": "foo" }, "constructor": 37 }, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/propertyNames.json000066400000000000000000000063071477700171100312170ustar00rootroot00000000000000[ { "description": "propertyNames validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "propertyNames": {"maxLength": 3} }, "tests": [ { "description": "all property names valid", "data": { "f": {}, "foo": {} }, "valid": true }, { "description": "some property names invalid", "data": { "foo": {}, "foobar": {} }, "valid": false }, { "description": "object without properties is valid", "data": {}, "valid": true }, { "description": "ignores arrays", "data": [1, 2, 3, 4], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "propertyNames validation with pattern", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "propertyNames": { "pattern": "^a+$" } }, "tests": [ { "description": "matching property names valid", "data": { "a": {}, "aa": {}, "aaa": {} }, "valid": true }, { "description": "non-matching property name is invalid", "data": { "aaA": {} }, "valid": false }, { "description": "object without properties is valid", "data": {}, "valid": true } ] }, { "description": "propertyNames with boolean schema true", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "propertyNames": true }, "tests": [ { "description": "object with any properties is valid", "data": {"foo": 1}, "valid": true }, { "description": "empty object is valid", "data": {}, "valid": true } ] }, { "description": "propertyNames with boolean schema false", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "propertyNames": false }, "tests": [ { "description": "object with any properties is invalid", "data": {"foo": 1}, "valid": false }, { "description": "empty object is valid", "data": {}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/recursiveRef.json000066400000000000000000000334341477700171100310140ustar00rootroot00000000000000[ { "description": "$recursiveRef without $recursiveAnchor works like $ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "foo": { "$recursiveRef": "#" } }, "additionalProperties": false }, "tests": [ { "description": "match", "data": {"foo": false}, "valid": true }, { "description": "recursive match", "data": { "foo": { "foo": false } }, "valid": true }, { "description": "mismatch", "data": { "bar": false }, "valid": false }, { "description": "recursive mismatch", "data": { "foo": { "bar": false } }, "valid": false } ] }, { "description": "$recursiveRef without using nesting", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:4242/draft2019-09/recursiveRef2/schema.json", "$defs": { "myobject": { "$id": "myobject.json", "$recursiveAnchor": true, "anyOf": [ { "type": "string" }, { "type": "object", "additionalProperties": { "$recursiveRef": "#" } } ] } }, "anyOf": [ { "type": "integer" }, { "$ref": "#/$defs/myobject" } ] }, "tests": [ { "description": "integer matches at the outer level", "data": 1, "valid": true }, { "description": "single level match", "data": { "foo": "hi" }, "valid": true }, { "description": "integer does not match as a property value", "data": { "foo": 1 }, "valid": false }, { "description": "two levels, properties match with inner definition", "data": { "foo": { "bar": "hi" } }, "valid": true }, { "description": "two levels, no match", "data": { "foo": { "bar": 1 } }, "valid": false } ] }, { "description": "$recursiveRef with nesting", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:4242/draft2019-09/recursiveRef3/schema.json", "$recursiveAnchor": true, "$defs": { "myobject": { "$id": "myobject.json", "$recursiveAnchor": true, "anyOf": [ { "type": "string" }, { "type": "object", "additionalProperties": { "$recursiveRef": "#" } } ] } }, "anyOf": [ { "type": "integer" }, { "$ref": "#/$defs/myobject" } ] }, "tests": [ { "description": "integer matches at the outer level", "data": 1, "valid": true }, { "description": "single level match", "data": { "foo": "hi" }, "valid": true }, { "description": "integer now matches as a property value", "data": { "foo": 1 }, "valid": true }, { "description": "two levels, properties match with inner definition", "data": { "foo": { "bar": "hi" } }, "valid": true }, { "description": "two levels, properties match with $recursiveRef", "data": { "foo": { "bar": 1 } }, "valid": true } ] }, { "description": "$recursiveRef with $recursiveAnchor: false works like $ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:4242/draft2019-09/recursiveRef4/schema.json", "$recursiveAnchor": false, "$defs": { "myobject": { "$id": "myobject.json", "$recursiveAnchor": false, "anyOf": [ { "type": "string" }, { "type": "object", "additionalProperties": { "$recursiveRef": "#" } } ] } }, "anyOf": [ { "type": "integer" }, { "$ref": "#/$defs/myobject" } ] }, "tests": [ { "description": "integer matches at the outer level", "data": 1, "valid": true }, { "description": "single level match", "data": { "foo": "hi" }, "valid": true }, { "description": "integer does not match as a property value", "data": { "foo": 1 }, "valid": false }, { "description": "two levels, properties match with inner definition", "data": { "foo": { "bar": "hi" } }, "valid": true }, { "description": "two levels, integer does not match as a property value", "data": { "foo": { "bar": 1 } }, "valid": false } ] }, { "description": "$recursiveRef with no $recursiveAnchor works like $ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:4242/draft2019-09/recursiveRef5/schema.json", "$defs": { "myobject": { "$id": "myobject.json", "$recursiveAnchor": false, "anyOf": [ { "type": "string" }, { "type": "object", "additionalProperties": { "$recursiveRef": "#" } } ] } }, "anyOf": [ { "type": "integer" }, { "$ref": "#/$defs/myobject" } ] }, "tests": [ { "description": "integer matches at the outer level", "data": 1, "valid": true }, { "description": "single level match", "data": { "foo": "hi" }, "valid": true }, { "description": "integer does not match as a property value", "data": { "foo": 1 }, "valid": false }, { "description": "two levels, properties match with inner definition", "data": { "foo": { "bar": "hi" } }, "valid": true }, { "description": "two levels, integer does not match as a property value", "data": { "foo": { "bar": 1 } }, "valid": false } ] }, { "description": "$recursiveRef with no $recursiveAnchor in the initial target schema resource", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:4242/draft2019-09/recursiveRef6/base.json", "$recursiveAnchor": true, "anyOf": [ { "type": "boolean" }, { "type": "object", "additionalProperties": { "$id": "http://localhost:4242/draft2019-09/recursiveRef6/inner.json", "$comment": "there is no $recursiveAnchor: true here, so we do NOT recurse to the base", "anyOf": [ { "type": "integer" }, { "type": "object", "additionalProperties": { "$recursiveRef": "#" } } ] } } ] }, "tests": [ { "description": "leaf node does not match; no recursion", "data": { "foo": true }, "valid": false }, { "description": "leaf node matches: recursion uses the inner schema", "data": { "foo": { "bar": 1 } }, "valid": true }, { "description": "leaf node does not match: recursion uses the inner schema", "data": { "foo": { "bar": true } }, "valid": false } ] }, { "description": "$recursiveRef with no $recursiveAnchor in the outer schema resource", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:4242/draft2019-09/recursiveRef7/base.json", "anyOf": [ { "type": "boolean" }, { "type": "object", "additionalProperties": { "$id": "http://localhost:4242/draft2019-09/recursiveRef7/inner.json", "$recursiveAnchor": true, "anyOf": [ { "type": "integer" }, { "type": "object", "additionalProperties": { "$recursiveRef": "#" } } ] } } ] }, "tests": [ { "description": "leaf node does not match; no recursion", "data": { "foo": true }, "valid": false }, { "description": "leaf node matches: recursion only uses inner schema", "data": { "foo": { "bar": 1 } }, "valid": true }, { "description": "leaf node does not match: recursion only uses inner schema", "data": { "foo": { "bar": true } }, "valid": false } ] }, { "description": "multiple dynamic paths to the $recursiveRef keyword", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://example.com/recursiveRef8_main.json", "$defs": { "inner": { "$id": "recursiveRef8_inner.json", "$recursiveAnchor": true, "title": "inner", "additionalProperties": { "$recursiveRef": "#" } } }, "if": { "propertyNames": { "pattern": "^[a-m]" } }, "then": { "title": "any type of node", "$id": "recursiveRef8_anyLeafNode.json", "$recursiveAnchor": true, "$ref": "recursiveRef8_inner.json" }, "else": { "title": "integer node", "$id": "recursiveRef8_integerNode.json", "$recursiveAnchor": true, "type": [ "object", "integer" ], "$ref": "recursiveRef8_inner.json" } }, "tests": [ { "description": "recurse to anyLeafNode - floats are allowed", "data": { "alpha": 1.1 }, "valid": true }, { "description": "recurse to integerNode - floats are not allowed", "data": { "november": 1.1 }, "valid": false } ] }, { "description": "dynamic $recursiveRef destination (not predictable at schema compile time)", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://example.com/main.json", "$defs": { "inner": { "$id": "inner.json", "$recursiveAnchor": true, "title": "inner", "additionalProperties": { "$recursiveRef": "#" } } }, "if": { "propertyNames": { "pattern": "^[a-m]" } }, "then": { "title": "any type of node", "$id": "anyLeafNode.json", "$recursiveAnchor": true, "$ref": "main.json#/$defs/inner" }, "else": { "title": "integer node", "$id": "integerNode.json", "$recursiveAnchor": true, "type": [ "object", "integer" ], "$ref": "main.json#/$defs/inner" } }, "tests": [ { "description": "numeric node", "data": { "alpha": 1.1 }, "valid": true }, { "description": "integer node", "data": { "november": 1.1 }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/ref.json000066400000000000000000001003051477700171100271140ustar00rootroot00000000000000[ { "description": "root pointer ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "foo": {"$ref": "#"} }, "additionalProperties": false }, "tests": [ { "description": "match", "data": {"foo": false}, "valid": true }, { "description": "recursive match", "data": {"foo": {"foo": false}}, "valid": true }, { "description": "mismatch", "data": {"bar": false}, "valid": false }, { "description": "recursive mismatch", "data": {"foo": {"bar": false}}, "valid": false } ] }, { "description": "relative pointer ref to object", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "foo": {"type": "integer"}, "bar": {"$ref": "#/properties/foo"} } }, "tests": [ { "description": "match", "data": {"bar": 3}, "valid": true }, { "description": "mismatch", "data": {"bar": true}, "valid": false } ] }, { "description": "relative pointer ref to array", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": [ {"type": "integer"}, {"$ref": "#/items/0"} ] }, "tests": [ { "description": "match array", "data": [1, 2], "valid": true }, { "description": "mismatch array", "data": [1, "foo"], "valid": false } ] }, { "description": "escaped pointer ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$defs": { "tilde~field": {"type": "integer"}, "slash/field": {"type": "integer"}, "percent%field": {"type": "integer"} }, "properties": { "tilde": {"$ref": "#/$defs/tilde~0field"}, "slash": {"$ref": "#/$defs/slash~1field"}, "percent": {"$ref": "#/$defs/percent%25field"} } }, "tests": [ { "description": "slash invalid", "data": {"slash": "aoeu"}, "valid": false }, { "description": "tilde invalid", "data": {"tilde": "aoeu"}, "valid": false }, { "description": "percent invalid", "data": {"percent": "aoeu"}, "valid": false }, { "description": "slash valid", "data": {"slash": 123}, "valid": true }, { "description": "tilde valid", "data": {"tilde": 123}, "valid": true }, { "description": "percent valid", "data": {"percent": 123}, "valid": true } ] }, { "description": "nested refs", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$defs": { "a": {"type": "integer"}, "b": {"$ref": "#/$defs/a"}, "c": {"$ref": "#/$defs/b"} }, "$ref": "#/$defs/c" }, "tests": [ { "description": "nested ref valid", "data": 5, "valid": true }, { "description": "nested ref invalid", "data": "a", "valid": false } ] }, { "description": "ref applies alongside sibling keywords", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$defs": { "reffed": { "type": "array" } }, "properties": { "foo": { "$ref": "#/$defs/reffed", "maxItems": 2 } } }, "tests": [ { "description": "ref valid, maxItems valid", "data": { "foo": [] }, "valid": true }, { "description": "ref valid, maxItems invalid", "data": { "foo": [1, 2, 3] }, "valid": false }, { "description": "ref invalid", "data": { "foo": "string" }, "valid": false } ] }, { "description": "remote ref, containing refs itself", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "https://json-schema.org/draft/2019-09/schema" }, "tests": [ { "description": "remote ref valid", "data": {"minLength": 1}, "valid": true }, { "description": "remote ref invalid", "data": {"minLength": -1}, "valid": false } ] }, { "description": "property named $ref that is not a reference", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "$ref": {"type": "string"} } }, "tests": [ { "description": "property named $ref valid", "data": {"$ref": "a"}, "valid": true }, { "description": "property named $ref invalid", "data": {"$ref": 2}, "valid": false } ] }, { "description": "property named $ref, containing an actual $ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "$ref": {"$ref": "#/$defs/is-string"} }, "$defs": { "is-string": { "type": "string" } } }, "tests": [ { "description": "property named $ref valid", "data": {"$ref": "a"}, "valid": true }, { "description": "property named $ref invalid", "data": {"$ref": 2}, "valid": false } ] }, { "description": "$ref to boolean schema true", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "#/$defs/bool", "$defs": { "bool": true } }, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "$ref to boolean schema false", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "#/$defs/bool", "$defs": { "bool": false } }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "Recursive references between schemas", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:1234/draft2019-09/tree", "description": "tree of nodes", "type": "object", "properties": { "meta": {"type": "string"}, "nodes": { "type": "array", "items": {"$ref": "node"} } }, "required": ["meta", "nodes"], "$defs": { "node": { "$id": "http://localhost:1234/draft2019-09/node", "description": "node", "type": "object", "properties": { "value": {"type": "number"}, "subtree": {"$ref": "tree"} }, "required": ["value"] } } }, "tests": [ { "description": "valid tree", "data": { "meta": "root", "nodes": [ { "value": 1, "subtree": { "meta": "child", "nodes": [ {"value": 1.1}, {"value": 1.2} ] } }, { "value": 2, "subtree": { "meta": "child", "nodes": [ {"value": 2.1}, {"value": 2.2} ] } } ] }, "valid": true }, { "description": "invalid tree", "data": { "meta": "root", "nodes": [ { "value": 1, "subtree": { "meta": "child", "nodes": [ {"value": "string is invalid"}, {"value": 1.2} ] } }, { "value": 2, "subtree": { "meta": "child", "nodes": [ {"value": 2.1}, {"value": 2.2} ] } } ] }, "valid": false } ] }, { "description": "refs with quote", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "foo\"bar": {"$ref": "#/$defs/foo%22bar"} }, "$defs": { "foo\"bar": {"type": "number"} } }, "tests": [ { "description": "object with numbers is valid", "data": { "foo\"bar": 1 }, "valid": true }, { "description": "object with strings is invalid", "data": { "foo\"bar": "1" }, "valid": false } ] }, { "description": "ref creates new scope when adjacent to keywords", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$defs": { "A": { "unevaluatedProperties": false } }, "properties": { "prop1": { "type": "string" } }, "$ref": "#/$defs/A" }, "tests": [ { "description": "referenced subschema doesn't see annotations from properties", "data": { "prop1": "match" }, "valid": false } ] }, { "description": "naive replacement of $ref with its destination is not correct", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$defs": { "a_string": { "type": "string" } }, "enum": [ { "$ref": "#/$defs/a_string" } ] }, "tests": [ { "description": "do not evaluate the $ref inside the enum, matching any string", "data": "this is a string", "valid": false }, { "description": "do not evaluate the $ref inside the enum, definition exact match", "data": { "type": "string" }, "valid": false }, { "description": "match the enum exactly", "data": { "$ref": "#/$defs/a_string" }, "valid": true } ] }, { "description": "refs with relative uris and defs", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://example.com/schema-relative-uri-defs1.json", "properties": { "foo": { "$id": "schema-relative-uri-defs2.json", "$defs": { "inner": { "properties": { "bar": { "type": "string" } } } }, "$ref": "#/$defs/inner" } }, "$ref": "schema-relative-uri-defs2.json" }, "tests": [ { "description": "invalid on inner field", "data": { "foo": { "bar": 1 }, "bar": "a" }, "valid": false }, { "description": "invalid on outer field", "data": { "foo": { "bar": "a" }, "bar": 1 }, "valid": false }, { "description": "valid on both fields", "data": { "foo": { "bar": "a" }, "bar": "a" }, "valid": true } ] }, { "description": "relative refs with absolute uris and defs", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://example.com/schema-refs-absolute-uris-defs1.json", "properties": { "foo": { "$id": "http://example.com/schema-refs-absolute-uris-defs2.json", "$defs": { "inner": { "properties": { "bar": { "type": "string" } } } }, "$ref": "#/$defs/inner" } }, "$ref": "schema-refs-absolute-uris-defs2.json" }, "tests": [ { "description": "invalid on inner field", "data": { "foo": { "bar": 1 }, "bar": "a" }, "valid": false }, { "description": "invalid on outer field", "data": { "foo": { "bar": "a" }, "bar": 1 }, "valid": false }, { "description": "valid on both fields", "data": { "foo": { "bar": "a" }, "bar": "a" }, "valid": true } ] }, { "description": "$id must be resolved against nearest parent, not just immediate parent", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://example.com/a.json", "$defs": { "x": { "$id": "http://example.com/b/c.json", "not": { "$defs": { "y": { "$id": "d.json", "type": "number" } } } } }, "allOf": [ { "$ref": "http://example.com/b/d.json" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] }, { "description": "order of evaluation: $id and $ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$comment": "$id must be evaluated before $ref to get the proper $ref destination", "$id": "https://example.com/draft2019-09/ref-and-id1/base.json", "$ref": "int.json", "$defs": { "bigint": { "$comment": "canonical uri: https://example.com/draft2019-09/ref-and-id1/int.json", "$id": "int.json", "maximum": 10 }, "smallint": { "$comment": "canonical uri: https://example.com/draft2019-09/ref-and-id1-int.json", "$id": "/draft2019-09/ref-and-id1-int.json", "maximum": 2 } } }, "tests": [ { "description": "data is valid against first definition", "data": 5, "valid": true }, { "description": "data is invalid against first definition", "data": 50, "valid": false } ] }, { "description": "order of evaluation: $id and $anchor and $ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$comment": "$id must be evaluated before $ref to get the proper $ref destination", "$id": "https://example.com/draft2019-09/ref-and-id2/base.json", "$ref": "#bigint", "$defs": { "bigint": { "$comment": "canonical uri: https://example.com/draft2019-09/ref-and-id2/base.json#/$defs/bigint; another valid uri for this location: https://example.com/ref-and-id2/base.json#bigint", "$anchor": "bigint", "maximum": 10 }, "smallint": { "$comment": "canonical uri: https://example.com/draft2019-09/ref-and-id2#/$defs/smallint; another valid uri for this location: https://example.com/ref-and-id2/#bigint", "$id": "/draft2019-09/ref-and-id2/", "$anchor": "bigint", "maximum": 2 } } }, "tests": [ { "description": "data is valid against first definition", "data": 5, "valid": true }, { "description": "data is invalid against first definition", "data": 50, "valid": false } ] }, { "description": "simple URN base URI with $ref via the URN", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$comment": "URIs do not have to have HTTP(s) schemes", "$id": "urn:uuid:deadbeef-1234-ffff-ffff-4321feebdaed", "minimum": 30, "properties": { "foo": {"$ref": "urn:uuid:deadbeef-1234-ffff-ffff-4321feebdaed"} } }, "tests": [ { "description": "valid under the URN IDed schema", "data": {"foo": 37}, "valid": true }, { "description": "invalid under the URN IDed schema", "data": {"foo": 12}, "valid": false } ] }, { "description": "simple URN base URI with JSON pointer", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$comment": "URIs do not have to have HTTP(s) schemes", "$id": "urn:uuid:deadbeef-1234-00ff-ff00-4321feebdaed", "properties": { "foo": {"$ref": "#/$defs/bar"} }, "$defs": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with NSS", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$comment": "RFC 8141 §2.2", "$id": "urn:example:1/406/47452/2", "properties": { "foo": {"$ref": "#/$defs/bar"} }, "$defs": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with r-component", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$comment": "RFC 8141 §2.3.1", "$id": "urn:example:foo-bar-baz-qux?+CCResolve:cc=uk", "properties": { "foo": {"$ref": "#/$defs/bar"} }, "$defs": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with q-component", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$comment": "RFC 8141 §2.3.2", "$id": "urn:example:weather?=op=map&lat=39.56&lon=-104.85&datetime=1969-07-21T02:56:15Z", "properties": { "foo": {"$ref": "#/$defs/bar"} }, "$defs": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with f-component", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$comment": "RFC 8141 §2.3.3, but we don't allow fragments", "$ref": "https://json-schema.org/draft/2019-09/schema" }, "tests": [ { "description": "is invalid", "data": {"$id": "urn:example:foo-bar-baz-qux#somepart"}, "valid": false } ] }, { "description": "URN base URI with URN and JSON pointer ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "urn:uuid:deadbeef-1234-0000-0000-4321feebdaed", "properties": { "foo": {"$ref": "urn:uuid:deadbeef-1234-0000-0000-4321feebdaed#/$defs/bar"} }, "$defs": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with URN and anchor ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "urn:uuid:deadbeef-1234-ff00-00ff-4321feebdaed", "properties": { "foo": {"$ref": "urn:uuid:deadbeef-1234-ff00-00ff-4321feebdaed#something"} }, "$defs": { "bar": { "$anchor": "something", "type": "string" } } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN ref with nested pointer ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "urn:uuid:deadbeef-4321-ffff-ffff-1234feebdaed", "$defs": { "foo": { "$id": "urn:uuid:deadbeef-4321-ffff-ffff-1234feebdaed", "$defs": {"bar": {"type": "string"}}, "$ref": "#/$defs/bar" } } }, "tests": [ { "description": "a string is valid", "data": "bar", "valid": true }, { "description": "a non-string is invalid", "data": 12, "valid": false } ] }, { "description": "ref to if", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://example.com/ref/if", "if": { "$id": "http://example.com/ref/if", "type": "integer" } }, "tests": [ { "description": "a non-integer is invalid due to the $ref", "data": "foo", "valid": false }, { "description": "an integer is valid", "data": 12, "valid": true } ] }, { "description": "ref to then", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://example.com/ref/then", "then": { "$id": "http://example.com/ref/then", "type": "integer" } }, "tests": [ { "description": "a non-integer is invalid due to the $ref", "data": "foo", "valid": false }, { "description": "an integer is valid", "data": 12, "valid": true } ] }, { "description": "ref to else", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://example.com/ref/else", "else": { "$id": "http://example.com/ref/else", "type": "integer" } }, "tests": [ { "description": "a non-integer is invalid due to the $ref", "data": "foo", "valid": false }, { "description": "an integer is valid", "data": 12, "valid": true } ] }, { "description": "ref with absolute-path-reference", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://example.com/ref/absref.json", "$defs": { "a": { "$id": "http://example.com/ref/absref/foobar.json", "type": "number" }, "b": { "$id": "http://example.com/absref/foobar.json", "type": "string" } }, "$ref": "/absref/foobar.json" }, "tests": [ { "description": "a string is valid", "data": "foo", "valid": true }, { "description": "an integer is invalid", "data": 12, "valid": false } ] }, { "description": "$id with file URI still resolves pointers - *nix", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "file:///folder/file.json", "$defs": { "foo": { "type": "number" } }, "$ref": "#/$defs/foo" }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] }, { "description": "$id with file URI still resolves pointers - windows", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "file:///c:/folder/file.json", "$defs": { "foo": { "type": "number" } }, "$ref": "#/$defs/foo" }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] }, { "description": "empty tokens in $ref json-pointer", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$defs": { "": { "$defs": { "": { "type": "number" } } } }, "allOf": [ { "$ref": "#/$defs//$defs/" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/refRemote.json000066400000000000000000000240531477700171100302750ustar00rootroot00000000000000[ { "description": "remote ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://localhost:1234/draft2019-09/integer.json" }, "tests": [ { "description": "remote ref valid", "data": 1, "valid": true }, { "description": "remote ref invalid", "data": "a", "valid": false } ] }, { "description": "fragment within remote ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://localhost:1234/draft2019-09/subSchemas.json#/$defs/integer" }, "tests": [ { "description": "remote fragment valid", "data": 1, "valid": true }, { "description": "remote fragment invalid", "data": "a", "valid": false } ] }, { "description": "anchor within remote ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://localhost:1234/draft2019-09/locationIndependentIdentifier.json#foo" }, "tests": [ { "description": "remote anchor valid", "data": 1, "valid": true }, { "description": "remote anchor invalid", "data": "a", "valid": false } ] }, { "description": "ref within remote ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://localhost:1234/draft2019-09/subSchemas.json#/$defs/refToInteger" }, "tests": [ { "description": "ref within ref valid", "data": 1, "valid": true }, { "description": "ref within ref invalid", "data": "a", "valid": false } ] }, { "description": "base URI change", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:1234/draft2019-09/", "items": { "$id": "baseUriChange/", "items": {"$ref": "folderInteger.json"} } }, "tests": [ { "description": "base URI change ref valid", "data": [[1]], "valid": true }, { "description": "base URI change ref invalid", "data": [["a"]], "valid": false } ] }, { "description": "base URI change - change folder", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:1234/draft2019-09/scope_change_defs1.json", "type" : "object", "properties": {"list": {"$ref": "baseUriChangeFolder/"}}, "$defs": { "baz": { "$id": "baseUriChangeFolder/", "type": "array", "items": {"$ref": "folderInteger.json"} } } }, "tests": [ { "description": "number is valid", "data": {"list": [1]}, "valid": true }, { "description": "string is invalid", "data": {"list": ["a"]}, "valid": false } ] }, { "description": "base URI change - change folder in subschema", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:1234/draft2019-09/scope_change_defs2.json", "type" : "object", "properties": {"list": {"$ref": "baseUriChangeFolderInSubschema/#/$defs/bar"}}, "$defs": { "baz": { "$id": "baseUriChangeFolderInSubschema/", "$defs": { "bar": { "type": "array", "items": {"$ref": "folderInteger.json"} } } } } }, "tests": [ { "description": "number is valid", "data": {"list": [1]}, "valid": true }, { "description": "string is invalid", "data": {"list": ["a"]}, "valid": false } ] }, { "description": "root ref in remote ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:1234/draft2019-09/object", "type": "object", "properties": { "name": {"$ref": "name-defs.json#/$defs/orNull"} } }, "tests": [ { "description": "string is valid", "data": { "name": "foo" }, "valid": true }, { "description": "null is valid", "data": { "name": null }, "valid": true }, { "description": "object is invalid", "data": { "name": { "name": null } }, "valid": false } ] }, { "description": "remote ref with ref to defs", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:1234/draft2019-09/schema-remote-ref-ref-defs1.json", "$ref": "ref-and-defs.json" }, "tests": [ { "description": "invalid", "data": { "bar": 1 }, "valid": false }, { "description": "valid", "data": { "bar": "a" }, "valid": true } ] }, { "description": "Location-independent identifier in remote ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://localhost:1234/draft2019-09/locationIndependentIdentifier.json#/$defs/refToInteger" }, "tests": [ { "description": "integer is valid", "data": 1, "valid": true }, { "description": "string is invalid", "data": "foo", "valid": false } ] }, { "description": "retrieved nested refs resolve relative to their URI not $id", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:1234/draft2019-09/some-id", "properties": { "name": {"$ref": "nested/foo-ref-string.json"} } }, "tests": [ { "description": "number is invalid", "data": { "name": {"foo": 1} }, "valid": false }, { "description": "string is valid", "data": { "name": {"foo": "a"} }, "valid": true } ] }, { "description": "remote HTTP ref with different $id", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://localhost:1234/different-id-ref-string.json" }, "tests": [ { "description": "number is invalid", "data": 1, "valid": false }, { "description": "string is valid", "data": "foo", "valid": true } ] }, { "description": "remote HTTP ref with different URN $id", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://localhost:1234/urn-ref-string.json" }, "tests": [ { "description": "number is invalid", "data": 1, "valid": false }, { "description": "string is valid", "data": "foo", "valid": true } ] }, { "description": "remote HTTP ref with nested absolute ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://localhost:1234/nested-absolute-ref-to-string.json" }, "tests": [ { "description": "number is invalid", "data": 1, "valid": false }, { "description": "string is valid", "data": "foo", "valid": true } ] }, { "description": "$ref to $ref finds detached $anchor", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://localhost:1234/draft2019-09/detached-ref.json#/$defs/foo" }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/required.json000066400000000000000000000110231477700171100301560ustar00rootroot00000000000000[ { "description": "required validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "foo": {}, "bar": {} }, "required": ["foo"] }, "tests": [ { "description": "present required property is valid", "data": {"foo": 1}, "valid": true }, { "description": "non-present required property is invalid", "data": {"bar": 1}, "valid": false }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores strings", "data": "", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "required default validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "foo": {} } }, "tests": [ { "description": "not required by default", "data": {}, "valid": true } ] }, { "description": "required with empty array", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "foo": {} }, "required": [] }, "tests": [ { "description": "property not required", "data": {}, "valid": true } ] }, { "description": "required with escaped characters", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "required": [ "foo\nbar", "foo\"bar", "foo\\bar", "foo\rbar", "foo\tbar", "foo\fbar" ] }, "tests": [ { "description": "object with all properties present is valid", "data": { "foo\nbar": 1, "foo\"bar": 1, "foo\\bar": 1, "foo\rbar": 1, "foo\tbar": 1, "foo\fbar": 1 }, "valid": true }, { "description": "object with some properties missing is invalid", "data": { "foo\nbar": "1", "foo\"bar": "1" }, "valid": false } ] }, { "description": "required properties whose names are Javascript object property names", "comment": "Ensure JS implementations don't universally consider e.g. __proto__ to always be present in an object.", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "required": ["__proto__", "toString", "constructor"] }, "tests": [ { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true }, { "description": "none of the properties mentioned", "data": {}, "valid": false }, { "description": "__proto__ present", "data": { "__proto__": "foo" }, "valid": false }, { "description": "toString present", "data": { "toString": { "length": 37 } }, "valid": false }, { "description": "constructor present", "data": { "constructor": { "length": 37 } }, "valid": false }, { "description": "all present", "data": { "__proto__": 12, "toString": { "length": "foo" }, "constructor": 37 }, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/type.json000066400000000000000000000340351477700171100273270ustar00rootroot00000000000000[ { "description": "integer type matches integers", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "integer" }, "tests": [ { "description": "an integer is an integer", "data": 1, "valid": true }, { "description": "a float with zero fractional part is an integer", "data": 1.0, "valid": true }, { "description": "a float is not an integer", "data": 1.1, "valid": false }, { "description": "a string is not an integer", "data": "foo", "valid": false }, { "description": "a string is still not an integer, even if it looks like one", "data": "1", "valid": false }, { "description": "an object is not an integer", "data": {}, "valid": false }, { "description": "an array is not an integer", "data": [], "valid": false }, { "description": "a boolean is not an integer", "data": true, "valid": false }, { "description": "null is not an integer", "data": null, "valid": false } ] }, { "description": "number type matches numbers", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "number" }, "tests": [ { "description": "an integer is a number", "data": 1, "valid": true }, { "description": "a float with zero fractional part is a number (and an integer)", "data": 1.0, "valid": true }, { "description": "a float is a number", "data": 1.1, "valid": true }, { "description": "a string is not a number", "data": "foo", "valid": false }, { "description": "a string is still not a number, even if it looks like one", "data": "1", "valid": false }, { "description": "an object is not a number", "data": {}, "valid": false }, { "description": "an array is not a number", "data": [], "valid": false }, { "description": "a boolean is not a number", "data": true, "valid": false }, { "description": "null is not a number", "data": null, "valid": false } ] }, { "description": "string type matches strings", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "string" }, "tests": [ { "description": "1 is not a string", "data": 1, "valid": false }, { "description": "a float is not a string", "data": 1.1, "valid": false }, { "description": "a string is a string", "data": "foo", "valid": true }, { "description": "a string is still a string, even if it looks like a number", "data": "1", "valid": true }, { "description": "an empty string is still a string", "data": "", "valid": true }, { "description": "an object is not a string", "data": {}, "valid": false }, { "description": "an array is not a string", "data": [], "valid": false }, { "description": "a boolean is not a string", "data": true, "valid": false }, { "description": "null is not a string", "data": null, "valid": false } ] }, { "description": "object type matches objects", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object" }, "tests": [ { "description": "an integer is not an object", "data": 1, "valid": false }, { "description": "a float is not an object", "data": 1.1, "valid": false }, { "description": "a string is not an object", "data": "foo", "valid": false }, { "description": "an object is an object", "data": {}, "valid": true }, { "description": "an array is not an object", "data": [], "valid": false }, { "description": "a boolean is not an object", "data": true, "valid": false }, { "description": "null is not an object", "data": null, "valid": false } ] }, { "description": "array type matches arrays", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "array" }, "tests": [ { "description": "an integer is not an array", "data": 1, "valid": false }, { "description": "a float is not an array", "data": 1.1, "valid": false }, { "description": "a string is not an array", "data": "foo", "valid": false }, { "description": "an object is not an array", "data": {}, "valid": false }, { "description": "an array is an array", "data": [], "valid": true }, { "description": "a boolean is not an array", "data": true, "valid": false }, { "description": "null is not an array", "data": null, "valid": false } ] }, { "description": "boolean type matches booleans", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "boolean" }, "tests": [ { "description": "an integer is not a boolean", "data": 1, "valid": false }, { "description": "zero is not a boolean", "data": 0, "valid": false }, { "description": "a float is not a boolean", "data": 1.1, "valid": false }, { "description": "a string is not a boolean", "data": "foo", "valid": false }, { "description": "an empty string is not a boolean", "data": "", "valid": false }, { "description": "an object is not a boolean", "data": {}, "valid": false }, { "description": "an array is not a boolean", "data": [], "valid": false }, { "description": "true is a boolean", "data": true, "valid": true }, { "description": "false is a boolean", "data": false, "valid": true }, { "description": "null is not a boolean", "data": null, "valid": false } ] }, { "description": "null type matches only the null object", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "null" }, "tests": [ { "description": "an integer is not null", "data": 1, "valid": false }, { "description": "a float is not null", "data": 1.1, "valid": false }, { "description": "zero is not null", "data": 0, "valid": false }, { "description": "a string is not null", "data": "foo", "valid": false }, { "description": "an empty string is not null", "data": "", "valid": false }, { "description": "an object is not null", "data": {}, "valid": false }, { "description": "an array is not null", "data": [], "valid": false }, { "description": "true is not null", "data": true, "valid": false }, { "description": "false is not null", "data": false, "valid": false }, { "description": "null is null", "data": null, "valid": true } ] }, { "description": "multiple types can be specified in an array", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": ["integer", "string"] }, "tests": [ { "description": "an integer is valid", "data": 1, "valid": true }, { "description": "a string is valid", "data": "foo", "valid": true }, { "description": "a float is invalid", "data": 1.1, "valid": false }, { "description": "an object is invalid", "data": {}, "valid": false }, { "description": "an array is invalid", "data": [], "valid": false }, { "description": "a boolean is invalid", "data": true, "valid": false }, { "description": "null is invalid", "data": null, "valid": false } ] }, { "description": "type as array with one item", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": ["string"] }, "tests": [ { "description": "string is valid", "data": "foo", "valid": true }, { "description": "number is invalid", "data": 123, "valid": false } ] }, { "description": "type: array or object", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": ["array", "object"] }, "tests": [ { "description": "array is valid", "data": [1,2,3], "valid": true }, { "description": "object is valid", "data": {"foo": 123}, "valid": true }, { "description": "number is invalid", "data": 123, "valid": false }, { "description": "string is invalid", "data": "foo", "valid": false }, { "description": "null is invalid", "data": null, "valid": false } ] }, { "description": "type: array, object or null", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": ["array", "object", "null"] }, "tests": [ { "description": "array is valid", "data": [1,2,3], "valid": true }, { "description": "object is valid", "data": {"foo": 123}, "valid": true }, { "description": "null is valid", "data": null, "valid": true }, { "description": "number is invalid", "data": 123, "valid": false }, { "description": "string is invalid", "data": "foo", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/unevaluatedItems.json000066400000000000000000000466021477700171100316700ustar00rootroot00000000000000[ { "description": "unevaluatedItems true", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "unevaluatedItems": true }, "tests": [ { "description": "with no unevaluated items", "data": [], "valid": true }, { "description": "with unevaluated items", "data": ["foo"], "valid": true } ] }, { "description": "unevaluatedItems false", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "unevaluatedItems": false }, "tests": [ { "description": "with no unevaluated items", "data": [], "valid": true }, { "description": "with unevaluated items", "data": ["foo"], "valid": false } ] }, { "description": "unevaluatedItems as schema", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "unevaluatedItems": { "type": "string" } }, "tests": [ { "description": "with no unevaluated items", "data": [], "valid": true }, { "description": "with valid unevaluated items", "data": ["foo"], "valid": true }, { "description": "with invalid unevaluated items", "data": [42], "valid": false } ] }, { "description": "unevaluatedItems with uniform items", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": { "type": "string" }, "unevaluatedItems": false }, "tests": [ { "description": "unevaluatedItems doesn't apply", "data": ["foo", "bar"], "valid": true } ] }, { "description": "unevaluatedItems with tuple", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": [ { "type": "string" } ], "unevaluatedItems": false }, "tests": [ { "description": "with no unevaluated items", "data": ["foo"], "valid": true }, { "description": "with unevaluated items", "data": ["foo", "bar"], "valid": false } ] }, { "description": "unevaluatedItems with items and additionalItems", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": [ { "type": "string" } ], "additionalItems": true, "unevaluatedItems": false }, "tests": [ { "description": "unevaluatedItems doesn't apply", "data": ["foo", 42], "valid": true } ] }, { "description": "unevaluatedItems with ignored additionalItems", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "additionalItems": {"type": "number"}, "unevaluatedItems": {"type": "string"} }, "tests": [ { "description": "invalid under unevaluatedItems", "comment": "additionalItems is entirely ignored when items isn't present, so all elements need to be valid against the unevaluatedItems schema", "data": ["foo", 1], "valid": false }, { "description": "all valid under unevaluatedItems", "data": ["foo", "bar", "baz"], "valid": true } ] }, { "description": "unevaluatedItems with ignored applicator additionalItems", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [ { "additionalItems": { "type": "number" } } ], "unevaluatedItems": {"type": "string"} }, "tests": [ { "description": "invalid under unevaluatedItems", "comment": "additionalItems is entirely ignored when items isn't present, so all elements need to be valid against the unevaluatedItems schema", "data": ["foo", 1], "valid": false }, { "description": "all valid under unevaluatedItems", "data": ["foo", "bar", "baz"], "valid": true } ] }, { "description": "unevaluatedItems with nested tuple", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": [ { "type": "string" } ], "allOf": [ { "items": [ true, { "type": "number" } ] } ], "unevaluatedItems": false }, "tests": [ { "description": "with no unevaluated items", "data": ["foo", 42], "valid": true }, { "description": "with unevaluated items", "data": ["foo", 42, true], "valid": false } ] }, { "description": "unevaluatedItems with nested items", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "unevaluatedItems": {"type": "boolean"}, "anyOf": [ { "items": {"type": "string"} }, true ] }, "tests": [ { "description": "with only (valid) additional items", "data": [true, false], "valid": true }, { "description": "with no additional items", "data": ["yes", "no"], "valid": true }, { "description": "with invalid additional item", "data": ["yes", false], "valid": false } ] }, { "description": "unevaluatedItems with nested items and additionalItems", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [ { "items": [ { "type": "string" } ], "additionalItems": true } ], "unevaluatedItems": false }, "tests": [ { "description": "with no additional items", "data": ["foo"], "valid": true }, { "description": "with additional items", "data": ["foo", 42, true], "valid": true } ] }, { "description": "unevaluatedItems with nested unevaluatedItems", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [ { "items": [ { "type": "string" } ] }, { "unevaluatedItems": true } ], "unevaluatedItems": false }, "tests": [ { "description": "with no additional items", "data": ["foo"], "valid": true }, { "description": "with additional items", "data": ["foo", 42, true], "valid": true } ] }, { "description": "unevaluatedItems with anyOf", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": [ { "const": "foo" } ], "anyOf": [ { "items": [ true, { "const": "bar" } ] }, { "items": [ true, true, { "const": "baz" } ] } ], "unevaluatedItems": false }, "tests": [ { "description": "when one schema matches and has no unevaluated items", "data": ["foo", "bar"], "valid": true }, { "description": "when one schema matches and has unevaluated items", "data": ["foo", "bar", 42], "valid": false }, { "description": "when two schemas match and has no unevaluated items", "data": ["foo", "bar", "baz"], "valid": true }, { "description": "when two schemas match and has unevaluated items", "data": ["foo", "bar", "baz", 42], "valid": false } ] }, { "description": "unevaluatedItems with oneOf", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": [ { "const": "foo" } ], "oneOf": [ { "items": [ true, { "const": "bar" } ] }, { "items": [ true, { "const": "baz" } ] } ], "unevaluatedItems": false }, "tests": [ { "description": "with no unevaluated items", "data": ["foo", "bar"], "valid": true }, { "description": "with unevaluated items", "data": ["foo", "bar", 42], "valid": false } ] }, { "description": "unevaluatedItems with not", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": [ { "const": "foo" } ], "not": { "not": { "items": [ true, { "const": "bar" } ] } }, "unevaluatedItems": false }, "tests": [ { "description": "with unevaluated items", "data": ["foo", "bar"], "valid": false } ] }, { "description": "unevaluatedItems with if/then/else", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": [ { "const": "foo" } ], "if": { "items": [ true, { "const": "bar" } ] }, "then": { "items": [ true, true, { "const": "then" } ] }, "else": { "items": [ true, true, true, { "const": "else" } ] }, "unevaluatedItems": false }, "tests": [ { "description": "when if matches and it has no unevaluated items", "data": ["foo", "bar", "then"], "valid": true }, { "description": "when if matches and it has unevaluated items", "data": ["foo", "bar", "then", "else"], "valid": false }, { "description": "when if doesn't match and it has no unevaluated items", "data": ["foo", 42, 42, "else"], "valid": true }, { "description": "when if doesn't match and it has unevaluated items", "data": ["foo", 42, 42, "else", 42], "valid": false } ] }, { "description": "unevaluatedItems with boolean schemas", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [true], "unevaluatedItems": false }, "tests": [ { "description": "with no unevaluated items", "data": [], "valid": true }, { "description": "with unevaluated items", "data": ["foo"], "valid": false } ] }, { "description": "unevaluatedItems with $ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "#/$defs/bar", "items": [ { "type": "string" } ], "unevaluatedItems": false, "$defs": { "bar": { "items": [ true, { "type": "string" } ] } } }, "tests": [ { "description": "with no unevaluated items", "data": ["foo", "bar"], "valid": true }, { "description": "with unevaluated items", "data": ["foo", "bar", "baz"], "valid": false } ] }, { "description": "unevaluatedItems with $recursiveRef", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://example.com/extended-tree", "$recursiveAnchor": true, "$ref": "/tree", "items": [ true, true, { "type": "string" } ], "$defs": { "tree": { "$id": "/tree", "$recursiveAnchor": true, "type": "array", "items": [ { "type": "number" }, { "$comment": "unevaluatedItems comes first so it's more likely to catch bugs with implementations that are sensitive to keyword ordering", "unevaluatedItems": false, "$recursiveRef": "#" } ] } } }, "tests": [ { "description": "with no unevaluated items", "data": [1, [2, [], "b"], "a"], "valid": true }, { "description": "with unevaluated items", "data": [1, [2, [], "b", "too many"], "a"], "valid": false } ] }, { "description": "unevaluatedItems can't see inside cousins", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [ { "items": [ true ] }, { "unevaluatedItems": false } ] }, "tests": [ { "description": "always fails", "data": [ 1 ], "valid": false } ] }, { "description": "item is evaluated in an uncle schema to unevaluatedItems", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "foo": { "items": [ { "type": "string" } ], "unevaluatedItems": false } }, "anyOf": [ { "properties": { "foo": { "items": [ true, { "type": "string" } ] } } } ] }, "tests": [ { "description": "no extra items", "data": { "foo": [ "test" ] }, "valid": true }, { "description": "uncle keyword evaluation is not significant", "data": { "foo": [ "test", "test" ] }, "valid": false } ] }, { "description": "non-array instances are valid", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "unevaluatedItems": false }, "tests": [ { "description": "ignores booleans", "data": true, "valid": true }, { "description": "ignores integers", "data": 123, "valid": true }, { "description": "ignores floats", "data": 1.0, "valid": true }, { "description": "ignores objects", "data": {}, "valid": true }, { "description": "ignores strings", "data": "foo", "valid": true }, { "description": "ignores null", "data": null, "valid": true } ] }, { "description": "unevaluatedItems with null instance elements", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "unevaluatedItems": { "type": "null" } }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] }, { "description": "unevaluatedItems can see annotations from if without then and else", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "if": { "items": [{"const": "a"}] }, "unevaluatedItems": false }, "tests": [ { "description": "valid in case if is evaluated", "data": [ "a" ], "valid": true }, { "description": "invalid in case if is evaluated", "data": [ "b" ], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/unevaluatedProperties.json000066400000000000000000001310671477700171100327430ustar00rootroot00000000000000[ { "description": "unevaluatedProperties true", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "unevaluatedProperties": true }, "tests": [ { "description": "with no unevaluated properties", "data": {}, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo" }, "valid": true } ] }, { "description": "unevaluatedProperties schema", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "unevaluatedProperties": { "type": "string", "minLength": 3 } }, "tests": [ { "description": "with no unevaluated properties", "data": {}, "valid": true }, { "description": "with valid unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with invalid unevaluated properties", "data": { "foo": "fo" }, "valid": false } ] }, { "description": "unevaluatedProperties false", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": {}, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo" }, "valid": false } ] }, { "description": "unevaluatedProperties with adjacent properties", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "unevaluatedProperties with adjacent patternProperties", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "patternProperties": { "^foo": { "type": "string" } }, "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "unevaluatedProperties with adjacent additionalProperties", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "additionalProperties": true, "unevaluatedProperties": false }, "tests": [ { "description": "with no additional properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with additional properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true } ] }, { "description": "unevaluatedProperties with nested properties", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "properties": { "bar": { "type": "string" } } } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no additional properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with additional properties", "data": { "foo": "foo", "bar": "bar", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with nested patternProperties", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "patternProperties": { "^bar": { "type": "string" } } } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no additional properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with additional properties", "data": { "foo": "foo", "bar": "bar", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with nested additionalProperties", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "additionalProperties": true } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no additional properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with additional properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true } ] }, { "description": "unevaluatedProperties with nested unevaluatedProperties", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "unevaluatedProperties": true } ], "unevaluatedProperties": { "type": "string", "maxLength": 2 } }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true } ] }, { "description": "unevaluatedProperties with anyOf", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "anyOf": [ { "properties": { "bar": { "const": "bar" } }, "required": ["bar"] }, { "properties": { "baz": { "const": "baz" } }, "required": ["baz"] }, { "properties": { "quux": { "const": "quux" } }, "required": ["quux"] } ], "unevaluatedProperties": false }, "tests": [ { "description": "when one matches and has no unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "when one matches and has unevaluated properties", "data": { "foo": "foo", "bar": "bar", "baz": "not-baz" }, "valid": false }, { "description": "when two match and has no unevaluated properties", "data": { "foo": "foo", "bar": "bar", "baz": "baz" }, "valid": true }, { "description": "when two match and has unevaluated properties", "data": { "foo": "foo", "bar": "bar", "baz": "baz", "quux": "not-quux" }, "valid": false } ] }, { "description": "unevaluatedProperties with oneOf", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "oneOf": [ { "properties": { "bar": { "const": "bar" } }, "required": ["bar"] }, { "properties": { "baz": { "const": "baz" } }, "required": ["baz"] } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar", "quux": "quux" }, "valid": false } ] }, { "description": "unevaluatedProperties with not", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "not": { "not": { "properties": { "bar": { "const": "bar" } }, "required": ["bar"] } }, "unevaluatedProperties": false }, "tests": [ { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "unevaluatedProperties with if/then/else", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "if": { "properties": { "foo": { "const": "then" } }, "required": ["foo"] }, "then": { "properties": { "bar": { "type": "string" } }, "required": ["bar"] }, "else": { "properties": { "baz": { "type": "string" } }, "required": ["baz"] }, "unevaluatedProperties": false }, "tests": [ { "description": "when if is true and has no unevaluated properties", "data": { "foo": "then", "bar": "bar" }, "valid": true }, { "description": "when if is true and has unevaluated properties", "data": { "foo": "then", "bar": "bar", "baz": "baz" }, "valid": false }, { "description": "when if is false and has no unevaluated properties", "data": { "baz": "baz" }, "valid": true }, { "description": "when if is false and has unevaluated properties", "data": { "foo": "else", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with if/then/else, then not defined", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "if": { "properties": { "foo": { "const": "then" } }, "required": ["foo"] }, "else": { "properties": { "baz": { "type": "string" } }, "required": ["baz"] }, "unevaluatedProperties": false }, "tests": [ { "description": "when if is true and has no unevaluated properties", "data": { "foo": "then", "bar": "bar" }, "valid": false }, { "description": "when if is true and has unevaluated properties", "data": { "foo": "then", "bar": "bar", "baz": "baz" }, "valid": false }, { "description": "when if is false and has no unevaluated properties", "data": { "baz": "baz" }, "valid": true }, { "description": "when if is false and has unevaluated properties", "data": { "foo": "else", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with if/then/else, else not defined", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "if": { "properties": { "foo": { "const": "then" } }, "required": ["foo"] }, "then": { "properties": { "bar": { "type": "string" } }, "required": ["bar"] }, "unevaluatedProperties": false }, "tests": [ { "description": "when if is true and has no unevaluated properties", "data": { "foo": "then", "bar": "bar" }, "valid": true }, { "description": "when if is true and has unevaluated properties", "data": { "foo": "then", "bar": "bar", "baz": "baz" }, "valid": false }, { "description": "when if is false and has no unevaluated properties", "data": { "baz": "baz" }, "valid": false }, { "description": "when if is false and has unevaluated properties", "data": { "foo": "else", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with dependentSchemas", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "dependentSchemas": { "foo": { "properties": { "bar": { "const": "bar" } }, "required": ["bar"] } }, "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with unevaluated properties", "data": { "bar": "bar" }, "valid": false } ] }, { "description": "unevaluatedProperties with boolean schemas", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [true], "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with unevaluated properties", "data": { "bar": "bar" }, "valid": false } ] }, { "description": "unevaluatedProperties with $ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "$ref": "#/$defs/bar", "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": false, "$defs": { "bar": { "properties": { "bar": { "type": "string" } } } } }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with $recursiveRef", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://example.com/extended-tree", "$recursiveAnchor": true, "$ref": "/tree", "properties": { "name": { "type": "string" } }, "$defs": { "tree": { "$id": "/tree", "$recursiveAnchor": true, "type": "object", "properties": { "node": true, "branches": { "$comment": "unevaluatedProperties comes first so it's more likely to bugs errors with implementations that are sensitive to keyword ordering", "unevaluatedProperties": false, "$recursiveRef": "#" } }, "required": ["node"] } } }, "tests": [ { "description": "with no unevaluated properties", "data": { "name": "a", "node": 1, "branches": { "name": "b", "node": 2 } }, "valid": true }, { "description": "with unevaluated properties", "data": { "name": "a", "node": 1, "branches": { "foo": "b", "node": 2 } }, "valid": false } ] }, { "description": "unevaluatedProperties can't see inside cousins", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [ { "properties": { "foo": true } }, { "unevaluatedProperties": false } ] }, "tests": [ { "description": "always fails", "data": { "foo": 1 }, "valid": false } ] }, { "description": "unevaluatedProperties can't see inside cousins (reverse order)", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "allOf": [ { "unevaluatedProperties": false }, { "properties": { "foo": true } } ] }, "tests": [ { "description": "always fails", "data": { "foo": 1 }, "valid": false } ] }, { "description": "nested unevaluatedProperties, outer false, inner true, properties outside", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "unevaluatedProperties": true } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true } ] }, { "description": "nested unevaluatedProperties, outer false, inner true, properties inside", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "allOf": [ { "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": true } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true } ] }, { "description": "nested unevaluatedProperties, outer true, inner false, properties outside", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "unevaluatedProperties": false } ], "unevaluatedProperties": true }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": false }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "nested unevaluatedProperties, outer true, inner false, properties inside", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "allOf": [ { "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": false } ], "unevaluatedProperties": true }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "cousin unevaluatedProperties, true and false, true with properties", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "allOf": [ { "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": true }, { "unevaluatedProperties": false } ] }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": false }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "cousin unevaluatedProperties, true and false, false with properties", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "allOf": [ { "unevaluatedProperties": true }, { "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": false } ] }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "property is evaluated in an uncle schema to unevaluatedProperties", "comment": "see https://stackoverflow.com/questions/66936884/deeply-nested-unevaluatedproperties-and-their-expectations", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "foo": { "type": "object", "properties": { "bar": { "type": "string" } }, "unevaluatedProperties": false } }, "anyOf": [ { "properties": { "foo": { "properties": { "faz": { "type": "string" } } } } } ] }, "tests": [ { "description": "no extra properties", "data": { "foo": { "bar": "test" } }, "valid": true }, { "description": "uncle keyword evaluation is not significant", "data": { "foo": { "bar": "test", "faz": "test" } }, "valid": false } ] }, { "description": "in-place applicator siblings, allOf has unevaluated", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "allOf": [ { "properties": { "foo": true }, "unevaluatedProperties": false } ], "anyOf": [ { "properties": { "bar": true } } ] }, "tests": [ { "description": "base case: both properties present", "data": { "foo": 1, "bar": 1 }, "valid": false }, { "description": "in place applicator siblings, bar is missing", "data": { "foo": 1 }, "valid": true }, { "description": "in place applicator siblings, foo is missing", "data": { "bar": 1 }, "valid": false } ] }, { "description": "in-place applicator siblings, anyOf has unevaluated", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "allOf": [ { "properties": { "foo": true } } ], "anyOf": [ { "properties": { "bar": true }, "unevaluatedProperties": false } ] }, "tests": [ { "description": "base case: both properties present", "data": { "foo": 1, "bar": 1 }, "valid": false }, { "description": "in place applicator siblings, bar is missing", "data": { "foo": 1 }, "valid": false }, { "description": "in place applicator siblings, foo is missing", "data": { "bar": 1 }, "valid": true } ] }, { "description": "unevaluatedProperties + single cyclic ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "x": { "$ref": "#" } }, "unevaluatedProperties": false }, "tests": [ { "description": "Empty is valid", "data": {}, "valid": true }, { "description": "Single is valid", "data": { "x": {} }, "valid": true }, { "description": "Unevaluated on 1st level is invalid", "data": { "x": {}, "y": {} }, "valid": false }, { "description": "Nested is valid", "data": { "x": { "x": {} } }, "valid": true }, { "description": "Unevaluated on 2nd level is invalid", "data": { "x": { "x": {}, "y": {} } }, "valid": false }, { "description": "Deep nested is valid", "data": { "x": { "x": { "x": {} } } }, "valid": true }, { "description": "Unevaluated on 3rd level is invalid", "data": { "x": { "x": { "x": {}, "y": {} } } }, "valid": false } ] }, { "description": "unevaluatedProperties + ref inside allOf / oneOf", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$defs": { "one": { "properties": { "a": true } }, "two": { "required": ["x"], "properties": { "x": true } } }, "allOf": [ { "$ref": "#/$defs/one" }, { "properties": { "b": true } }, { "oneOf": [ { "$ref": "#/$defs/two" }, { "required": ["y"], "properties": { "y": true } } ] } ], "unevaluatedProperties": false }, "tests": [ { "description": "Empty is invalid (no x or y)", "data": {}, "valid": false }, { "description": "a and b are invalid (no x or y)", "data": { "a": 1, "b": 1 }, "valid": false }, { "description": "x and y are invalid", "data": { "x": 1, "y": 1 }, "valid": false }, { "description": "a and x are valid", "data": { "a": 1, "x": 1 }, "valid": true }, { "description": "a and y are valid", "data": { "a": 1, "y": 1 }, "valid": true }, { "description": "a and b and x are valid", "data": { "a": 1, "b": 1, "x": 1 }, "valid": true }, { "description": "a and b and y are valid", "data": { "a": 1, "b": 1, "y": 1 }, "valid": true }, { "description": "a and b and x and y are invalid", "data": { "a": 1, "b": 1, "x": 1, "y": 1 }, "valid": false } ] }, { "description": "dynamic evalation inside nested refs", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$defs": { "one": { "oneOf": [ { "$ref": "#/$defs/two" }, { "required": ["b"], "properties": { "b": true } }, { "required": ["xx"], "patternProperties": { "x": true } }, { "required": ["all"], "unevaluatedProperties": true } ] }, "two": { "oneOf": [ { "required": ["c"], "properties": { "c": true } }, { "required": ["d"], "properties": { "d": true } } ] } }, "oneOf": [ { "$ref": "#/$defs/one" }, { "required": ["a"], "properties": { "a": true } } ], "unevaluatedProperties": false }, "tests": [ { "description": "Empty is invalid", "data": {}, "valid": false }, { "description": "a is valid", "data": { "a": 1 }, "valid": true }, { "description": "b is valid", "data": { "b": 1 }, "valid": true }, { "description": "c is valid", "data": { "c": 1 }, "valid": true }, { "description": "d is valid", "data": { "d": 1 }, "valid": true }, { "description": "a + b is invalid", "data": { "a": 1, "b": 1 }, "valid": false }, { "description": "a + c is invalid", "data": { "a": 1, "c": 1 }, "valid": false }, { "description": "a + d is invalid", "data": { "a": 1, "d": 1 }, "valid": false }, { "description": "b + c is invalid", "data": { "b": 1, "c": 1 }, "valid": false }, { "description": "b + d is invalid", "data": { "b": 1, "d": 1 }, "valid": false }, { "description": "c + d is invalid", "data": { "c": 1, "d": 1 }, "valid": false }, { "description": "xx is valid", "data": { "xx": 1 }, "valid": true }, { "description": "xx + foox is valid", "data": { "xx": 1, "foox": 1 }, "valid": true }, { "description": "xx + foo is invalid", "data": { "xx": 1, "foo": 1 }, "valid": false }, { "description": "xx + a is invalid", "data": { "xx": 1, "a": 1 }, "valid": false }, { "description": "xx + b is invalid", "data": { "xx": 1, "b": 1 }, "valid": false }, { "description": "xx + c is invalid", "data": { "xx": 1, "c": 1 }, "valid": false }, { "description": "xx + d is invalid", "data": { "xx": 1, "d": 1 }, "valid": false }, { "description": "all is valid", "data": { "all": 1 }, "valid": true }, { "description": "all + foo is valid", "data": { "all": 1, "foo": 1 }, "valid": true }, { "description": "all + a is invalid", "data": { "all": 1, "a": 1 }, "valid": false } ] }, { "description": "non-object instances are valid", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "unevaluatedProperties": false }, "tests": [ { "description": "ignores booleans", "data": true, "valid": true }, { "description": "ignores integers", "data": 123, "valid": true }, { "description": "ignores floats", "data": 1.0, "valid": true }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores strings", "data": "foo", "valid": true }, { "description": "ignores null", "data": null, "valid": true } ] }, { "description": "unevaluatedProperties with null valued instance properties", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "unevaluatedProperties": { "type": "null" } }, "tests": [ { "description": "allows null valued properties", "data": {"foo": null}, "valid": true } ] }, { "description": "unevaluatedProperties not affected by propertyNames", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "propertyNames": {"maxLength": 1}, "unevaluatedProperties": { "type": "number" } }, "tests": [ { "description": "allows only number properties", "data": {"a": 1}, "valid": true }, { "description": "string property is invalid", "data": {"a": "b"}, "valid": false } ] }, { "description": "unevaluatedProperties can see annotations from if without then and else", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "if": { "patternProperties": { "foo": { "type": "string" } } }, "unevaluatedProperties": false }, "tests": [ { "description": "valid in case if is evaluated", "data": { "foo": "a" }, "valid": true }, { "description": "invalid in case if is evaluated", "data": { "bar": "a" }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/uniqueItems.json000066400000000000000000000342261477700171100306600ustar00rootroot00000000000000[ { "description": "uniqueItems validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "uniqueItems": true }, "tests": [ { "description": "unique array of integers is valid", "data": [1, 2], "valid": true }, { "description": "non-unique array of integers is invalid", "data": [1, 1], "valid": false }, { "description": "non-unique array of more than two integers is invalid", "data": [1, 2, 1], "valid": false }, { "description": "numbers are unique if mathematically unequal", "data": [1.0, 1.00, 1], "valid": false }, { "description": "false is not equal to zero", "data": [0, false], "valid": true }, { "description": "true is not equal to one", "data": [1, true], "valid": true }, { "description": "unique array of strings is valid", "data": ["foo", "bar", "baz"], "valid": true }, { "description": "non-unique array of strings is invalid", "data": ["foo", "bar", "foo"], "valid": false }, { "description": "unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "baz"}], "valid": true }, { "description": "non-unique array of objects is invalid", "data": [{"foo": "bar"}, {"foo": "bar"}], "valid": false }, { "description": "property order of array of objects is ignored", "data": [{"foo": "bar", "bar": "foo"}, {"bar": "foo", "foo": "bar"}], "valid": false }, { "description": "unique array of nested objects is valid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : false}}} ], "valid": true }, { "description": "non-unique array of nested objects is invalid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : true}}} ], "valid": false }, { "description": "unique array of arrays is valid", "data": [["foo"], ["bar"]], "valid": true }, { "description": "non-unique array of arrays is invalid", "data": [["foo"], ["foo"]], "valid": false }, { "description": "non-unique array of more than two arrays is invalid", "data": [["foo"], ["bar"], ["foo"]], "valid": false }, { "description": "1 and true are unique", "data": [1, true], "valid": true }, { "description": "0 and false are unique", "data": [0, false], "valid": true }, { "description": "[1] and [true] are unique", "data": [[1], [true]], "valid": true }, { "description": "[0] and [false] are unique", "data": [[0], [false]], "valid": true }, { "description": "nested [1] and [true] are unique", "data": [[[1], "foo"], [[true], "foo"]], "valid": true }, { "description": "nested [0] and [false] are unique", "data": [[[0], "foo"], [[false], "foo"]], "valid": true }, { "description": "unique heterogeneous types are valid", "data": [{}, [1], true, null, 1, "{}"], "valid": true }, { "description": "non-unique heterogeneous types are invalid", "data": [{}, [1], true, null, {}, 1], "valid": false }, { "description": "different objects are unique", "data": [{"a": 1, "b": 2}, {"a": 2, "b": 1}], "valid": true }, { "description": "objects are non-unique despite key order", "data": [{"a": 1, "b": 2}, {"b": 2, "a": 1}], "valid": false }, { "description": "{\"a\": false} and {\"a\": 0} are unique", "data": [{"a": false}, {"a": 0}], "valid": true }, { "description": "{\"a\": true} and {\"a\": 1} are unique", "data": [{"a": true}, {"a": 1}], "valid": true } ] }, { "description": "uniqueItems with an array of items", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": true }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is not valid", "data": [false, false], "valid": false }, { "description": "[true, true] from items array is not valid", "data": [true, true], "valid": false }, { "description": "unique array extended from [false, true] is valid", "data": [false, true, "foo", "bar"], "valid": true }, { "description": "unique array extended from [true, false] is valid", "data": [true, false, "foo", "bar"], "valid": true }, { "description": "non-unique array extended from [false, true] is not valid", "data": [false, true, "foo", "foo"], "valid": false }, { "description": "non-unique array extended from [true, false] is not valid", "data": [true, false, "foo", "foo"], "valid": false } ] }, { "description": "uniqueItems with an array of items and additionalItems=false", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": true, "additionalItems": false }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is not valid", "data": [false, false], "valid": false }, { "description": "[true, true] from items array is not valid", "data": [true, true], "valid": false }, { "description": "extra items are invalid even if unique", "data": [false, true, null], "valid": false } ] }, { "description": "uniqueItems=false validation", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "uniqueItems": false }, "tests": [ { "description": "unique array of integers is valid", "data": [1, 2], "valid": true }, { "description": "non-unique array of integers is valid", "data": [1, 1], "valid": true }, { "description": "numbers are unique if mathematically unequal", "data": [1.0, 1.00, 1], "valid": true }, { "description": "false is not equal to zero", "data": [0, false], "valid": true }, { "description": "true is not equal to one", "data": [1, true], "valid": true }, { "description": "unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "baz"}], "valid": true }, { "description": "non-unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "bar"}], "valid": true }, { "description": "unique array of nested objects is valid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : false}}} ], "valid": true }, { "description": "non-unique array of nested objects is valid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : true}}} ], "valid": true }, { "description": "unique array of arrays is valid", "data": [["foo"], ["bar"]], "valid": true }, { "description": "non-unique array of arrays is valid", "data": [["foo"], ["foo"]], "valid": true }, { "description": "1 and true are unique", "data": [1, true], "valid": true }, { "description": "0 and false are unique", "data": [0, false], "valid": true }, { "description": "unique heterogeneous types are valid", "data": [{}, [1], true, null, 1], "valid": true }, { "description": "non-unique heterogeneous types are valid", "data": [{}, [1], true, null, {}, 1], "valid": true } ] }, { "description": "uniqueItems=false with an array of items", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": false }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is valid", "data": [false, false], "valid": true }, { "description": "[true, true] from items array is valid", "data": [true, true], "valid": true }, { "description": "unique array extended from [false, true] is valid", "data": [false, true, "foo", "bar"], "valid": true }, { "description": "unique array extended from [true, false] is valid", "data": [true, false, "foo", "bar"], "valid": true }, { "description": "non-unique array extended from [false, true] is valid", "data": [false, true, "foo", "foo"], "valid": true }, { "description": "non-unique array extended from [true, false] is valid", "data": [true, false, "foo", "foo"], "valid": true } ] }, { "description": "uniqueItems=false with an array of items and additionalItems=false", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": false, "additionalItems": false }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is valid", "data": [false, false], "valid": true }, { "description": "[true, true] from items array is valid", "data": [true, true], "valid": true }, { "description": "extra items are invalid even if unique", "data": [false, true, null], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/unknownKeyword.json000066400000000000000000000041131477700171100314040ustar00rootroot00000000000000[ { "description": "$id inside an unknown keyword is not a real identifier", "comment": "the implementation must not be confused by an $id in locations we do not know how to parse", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$defs": { "id_in_unknown0": { "not": { "array_of_schemas": [ { "$id": "https://localhost:1234/draft2019-09/unknownKeyword/my_identifier.json", "type": "null" } ] } }, "real_id_in_schema": { "$id": "https://localhost:1234/draft2019-09/unknownKeyword/my_identifier.json", "type": "string" }, "id_in_unknown1": { "not": { "object_of_schemas": { "foo": { "$id": "https://localhost:1234/draft2019-09/unknownKeyword/my_identifier.json", "type": "integer" } } } } }, "anyOf": [ { "$ref": "#/$defs/id_in_unknown0" }, { "$ref": "#/$defs/id_in_unknown1" }, { "$ref": "https://localhost:1234/draft2019-09/unknownKeyword/my_identifier.json" } ] }, "tests": [ { "description": "type matches second anyOf, which has a real schema in it", "data": "a string", "valid": true }, { "description": "type matches non-schema in first anyOf", "data": null, "valid": false }, { "description": "type matches non-schema in third anyOf", "data": 1, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/vocabulary.json000066400000000000000000000032741477700171100305160ustar00rootroot00000000000000[ { "description": "schema that uses custom metaschema with with no validation vocabulary", "schema": { "$id": "https://schema/using/no/validation", "$schema": "http://localhost:1234/draft2019-09/metaschema-no-validation.json", "properties": { "badProperty": false, "numberProperty": { "minimum": 10 } } }, "tests": [ { "description": "applicator vocabulary still works", "data": { "badProperty": "this property should not exist" }, "valid": false }, { "description": "no validation: valid number", "data": { "numberProperty": 20 }, "valid": true }, { "description": "no validation: invalid number, but it still validates", "data": { "numberProperty": 1 }, "valid": true } ] }, { "description": "ignore unrecognized optional vocabulary", "schema": { "$schema": "http://localhost:1234/draft2019-09/metaschema-optional-vocabulary.json", "type": "number" }, "tests": [ { "description": "string value", "data": "foobar", "valid": false }, { "description": "number value", "data": 20, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/000077500000000000000000000000001477700171100254305ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/additionalProperties.json000066400000000000000000000115211477700171100325100ustar00rootroot00000000000000[ { "description": "additionalProperties being false does not allow other properties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": {"foo": {}, "bar": {}}, "patternProperties": { "^v": {} }, "additionalProperties": false }, "tests": [ { "description": "no additional properties is valid", "data": {"foo": 1}, "valid": true }, { "description": "an additional property is invalid", "data": {"foo" : 1, "bar" : 2, "quux" : "boom"}, "valid": false }, { "description": "ignores arrays", "data": [1, 2, 3], "valid": true }, { "description": "ignores strings", "data": "foobarbaz", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true }, { "description": "patternProperties are not additional properties", "data": {"foo":1, "vroom": 2}, "valid": true } ] }, { "description": "non-ASCII pattern with additionalProperties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "patternProperties": {"^á": {}}, "additionalProperties": false }, "tests": [ { "description": "matching the pattern is valid", "data": {"ármányos": 2}, "valid": true }, { "description": "not matching the pattern is invalid", "data": {"élmény": 2}, "valid": false } ] }, { "description": "additionalProperties with schema", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": {"foo": {}, "bar": {}}, "additionalProperties": {"type": "boolean"} }, "tests": [ { "description": "no additional properties is valid", "data": {"foo": 1}, "valid": true }, { "description": "an additional valid property is valid", "data": {"foo" : 1, "bar" : 2, "quux" : true}, "valid": true }, { "description": "an additional invalid property is invalid", "data": {"foo" : 1, "bar" : 2, "quux" : 12}, "valid": false } ] }, { "description": "additionalProperties can exist by itself", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": {"type": "boolean"} }, "tests": [ { "description": "an additional valid property is valid", "data": {"foo" : true}, "valid": true }, { "description": "an additional invalid property is invalid", "data": {"foo" : 1}, "valid": false } ] }, { "description": "additionalProperties are allowed by default", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": {"foo": {}, "bar": {}} }, "tests": [ { "description": "additional properties are allowed", "data": {"foo": 1, "bar": 2, "quux": true}, "valid": true } ] }, { "description": "additionalProperties does not look in applicators", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ {"properties": {"foo": {}}} ], "additionalProperties": {"type": "boolean"} }, "tests": [ { "description": "properties defined in allOf are not examined", "data": {"foo": 1, "bar": true}, "valid": false } ] }, { "description": "additionalProperties with null valued instance properties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": { "type": "null" } }, "tests": [ { "description": "allows null values", "data": {"foo": null}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/allOf.json000066400000000000000000000207751477700171100273730ustar00rootroot00000000000000[ { "description": "allOf", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ { "properties": { "bar": {"type": "integer"} }, "required": ["bar"] }, { "properties": { "foo": {"type": "string"} }, "required": ["foo"] } ] }, "tests": [ { "description": "allOf", "data": {"foo": "baz", "bar": 2}, "valid": true }, { "description": "mismatch second", "data": {"foo": "baz"}, "valid": false }, { "description": "mismatch first", "data": {"bar": 2}, "valid": false }, { "description": "wrong type", "data": {"foo": "baz", "bar": "quux"}, "valid": false } ] }, { "description": "allOf with base schema", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": {"bar": {"type": "integer"}}, "required": ["bar"], "allOf" : [ { "properties": { "foo": {"type": "string"} }, "required": ["foo"] }, { "properties": { "baz": {"type": "null"} }, "required": ["baz"] } ] }, "tests": [ { "description": "valid", "data": {"foo": "quux", "bar": 2, "baz": null}, "valid": true }, { "description": "mismatch base schema", "data": {"foo": "quux", "baz": null}, "valid": false }, { "description": "mismatch first allOf", "data": {"bar": 2, "baz": null}, "valid": false }, { "description": "mismatch second allOf", "data": {"foo": "quux", "bar": 2}, "valid": false }, { "description": "mismatch both", "data": {"bar": 2}, "valid": false } ] }, { "description": "allOf simple types", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ {"maximum": 30}, {"minimum": 20} ] }, "tests": [ { "description": "valid", "data": 25, "valid": true }, { "description": "mismatch one", "data": 35, "valid": false } ] }, { "description": "allOf with boolean schemas, all true", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [true, true] }, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "allOf with boolean schemas, some false", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [true, false] }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "allOf with boolean schemas, all false", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [false, false] }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "allOf with one empty schema", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ {} ] }, "tests": [ { "description": "any data is valid", "data": 1, "valid": true } ] }, { "description": "allOf with two empty schemas", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ {}, {} ] }, "tests": [ { "description": "any data is valid", "data": 1, "valid": true } ] }, { "description": "allOf with the first empty schema", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ {}, { "type": "number" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "string is invalid", "data": "foo", "valid": false } ] }, { "description": "allOf with the last empty schema", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ { "type": "number" }, {} ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "string is invalid", "data": "foo", "valid": false } ] }, { "description": "nested allOf, to check validation semantics", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ { "allOf": [ { "type": "null" } ] } ] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "anything non-null is invalid", "data": 123, "valid": false } ] }, { "description": "allOf combined with anyOf, oneOf", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ { "multipleOf": 2 } ], "anyOf": [ { "multipleOf": 3 } ], "oneOf": [ { "multipleOf": 5 } ] }, "tests": [ { "description": "allOf: false, anyOf: false, oneOf: false", "data": 1, "valid": false }, { "description": "allOf: false, anyOf: false, oneOf: true", "data": 5, "valid": false }, { "description": "allOf: false, anyOf: true, oneOf: false", "data": 3, "valid": false }, { "description": "allOf: false, anyOf: true, oneOf: true", "data": 15, "valid": false }, { "description": "allOf: true, anyOf: false, oneOf: false", "data": 2, "valid": false }, { "description": "allOf: true, anyOf: false, oneOf: true", "data": 10, "valid": false }, { "description": "allOf: true, anyOf: true, oneOf: false", "data": 6, "valid": false }, { "description": "allOf: true, anyOf: true, oneOf: true", "data": 30, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/anchor.json000066400000000000000000000160461477700171100276040ustar00rootroot00000000000000[ { "description": "Location-independent identifier", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "#foo", "$defs": { "A": { "$anchor": "foo", "type": "integer" } } }, "tests": [ { "data": 1, "description": "match", "valid": true }, { "data": "a", "description": "mismatch", "valid": false } ] }, { "description": "Location-independent identifier with absolute URI", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "http://localhost:1234/draft2020-12/bar#foo", "$defs": { "A": { "$id": "http://localhost:1234/draft2020-12/bar", "$anchor": "foo", "type": "integer" } } }, "tests": [ { "data": 1, "description": "match", "valid": true }, { "data": "a", "description": "mismatch", "valid": false } ] }, { "description": "Location-independent identifier with base URI change in subschema", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://localhost:1234/draft2020-12/root", "$ref": "http://localhost:1234/draft2020-12/nested.json#foo", "$defs": { "A": { "$id": "nested.json", "$defs": { "B": { "$anchor": "foo", "type": "integer" } } } } }, "tests": [ { "data": 1, "description": "match", "valid": true }, { "data": "a", "description": "mismatch", "valid": false } ] }, { "description": "$anchor inside an enum is not a real identifier", "comment": "the implementation must not be confused by an $anchor buried in the enum", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "anchor_in_enum": { "enum": [ { "$anchor": "my_anchor", "type": "null" } ] }, "real_identifier_in_schema": { "$anchor": "my_anchor", "type": "string" }, "zzz_anchor_in_const": { "const": { "$anchor": "my_anchor", "type": "null" } } }, "anyOf": [ { "$ref": "#/$defs/anchor_in_enum" }, { "$ref": "#my_anchor" } ] }, "tests": [ { "description": "exact match to enum, and type matches", "data": { "$anchor": "my_anchor", "type": "null" }, "valid": true }, { "description": "in implementations that strip $anchor, this may match either $def", "data": { "type": "null" }, "valid": false }, { "description": "match $ref to $anchor", "data": "a string to match #/$defs/anchor_in_enum", "valid": true }, { "description": "no match on enum or $ref to $anchor", "data": 1, "valid": false } ] }, { "description": "same $anchor with different base uri", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://localhost:1234/draft2020-12/foobar", "$defs": { "A": { "$id": "child1", "allOf": [ { "$id": "child2", "$anchor": "my_anchor", "type": "number" }, { "$anchor": "my_anchor", "type": "string" } ] } }, "$ref": "child1#my_anchor" }, "tests": [ { "description": "$ref resolves to /$defs/A/allOf/1", "data": "a", "valid": true }, { "description": "$ref does not resolve to /$defs/A/allOf/0", "data": 1, "valid": false } ] }, { "description": "non-schema object containing an $anchor property", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "const_not_anchor": { "const": { "$anchor": "not_a_real_anchor" } } }, "if": { "const": "skip not_a_real_anchor" }, "then": true, "else" : { "$ref": "#/$defs/const_not_anchor" } }, "tests": [ { "description": "skip traversing definition for a valid result", "data": "skip not_a_real_anchor", "valid": true }, { "description": "const at const_not_anchor does not match", "data": 1, "valid": false } ] }, { "description": "invalid anchors", "comment": "Section 8.2.2", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "https://json-schema.org/draft/2020-12/schema" }, "tests": [ { "description": "MUST start with a letter (and not #)", "data": { "$anchor" : "#foo" }, "valid": false }, { "description": "JSON pointers are not valid", "data": { "$anchor" : "/a/b" }, "valid": false }, { "description": "invalid with valid beginning", "data": { "$anchor" : "foo#something" }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/anyOf.json000066400000000000000000000125251477700171100274040ustar00rootroot00000000000000[ { "description": "anyOf", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "anyOf": [ { "type": "integer" }, { "minimum": 2 } ] }, "tests": [ { "description": "first anyOf valid", "data": 1, "valid": true }, { "description": "second anyOf valid", "data": 2.5, "valid": true }, { "description": "both anyOf valid", "data": 3, "valid": true }, { "description": "neither anyOf valid", "data": 1.5, "valid": false } ] }, { "description": "anyOf with base schema", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "string", "anyOf" : [ { "maxLength": 2 }, { "minLength": 4 } ] }, "tests": [ { "description": "mismatch base schema", "data": 3, "valid": false }, { "description": "one anyOf valid", "data": "foobar", "valid": true }, { "description": "both anyOf invalid", "data": "foo", "valid": false } ] }, { "description": "anyOf with boolean schemas, all true", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "anyOf": [true, true] }, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "anyOf with boolean schemas, some true", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "anyOf": [true, false] }, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "anyOf with boolean schemas, all false", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "anyOf": [false, false] }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "anyOf complex types", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "anyOf": [ { "properties": { "bar": {"type": "integer"} }, "required": ["bar"] }, { "properties": { "foo": {"type": "string"} }, "required": ["foo"] } ] }, "tests": [ { "description": "first anyOf valid (complex)", "data": {"bar": 2}, "valid": true }, { "description": "second anyOf valid (complex)", "data": {"foo": "baz"}, "valid": true }, { "description": "both anyOf valid (complex)", "data": {"foo": "baz", "bar": 2}, "valid": true }, { "description": "neither anyOf valid (complex)", "data": {"foo": 2, "bar": "quux"}, "valid": false } ] }, { "description": "anyOf with one empty schema", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "anyOf": [ { "type": "number" }, {} ] }, "tests": [ { "description": "string is valid", "data": "foo", "valid": true }, { "description": "number is valid", "data": 123, "valid": true } ] }, { "description": "nested anyOf, to check validation semantics", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "anyOf": [ { "anyOf": [ { "type": "null" } ] } ] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "anything non-null is invalid", "data": 123, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/boolean_schema.json000066400000000000000000000054021477700171100312630ustar00rootroot00000000000000[ { "description": "boolean schema 'true'", "schema": true, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "string is valid", "data": "foo", "valid": true }, { "description": "boolean true is valid", "data": true, "valid": true }, { "description": "boolean false is valid", "data": false, "valid": true }, { "description": "null is valid", "data": null, "valid": true }, { "description": "object is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "empty object is valid", "data": {}, "valid": true }, { "description": "array is valid", "data": ["foo"], "valid": true }, { "description": "empty array is valid", "data": [], "valid": true } ] }, { "description": "boolean schema 'false'", "schema": false, "tests": [ { "description": "number is invalid", "data": 1, "valid": false }, { "description": "string is invalid", "data": "foo", "valid": false }, { "description": "boolean true is invalid", "data": true, "valid": false }, { "description": "boolean false is invalid", "data": false, "valid": false }, { "description": "null is invalid", "data": null, "valid": false }, { "description": "object is invalid", "data": {"foo": "bar"}, "valid": false }, { "description": "empty object is invalid", "data": {}, "valid": false }, { "description": "array is invalid", "data": ["foo"], "valid": false }, { "description": "empty array is invalid", "data": [], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/const.json000066400000000000000000000253451477700171100274620ustar00rootroot00000000000000[ { "description": "const validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "const": 2 }, "tests": [ { "description": "same value is valid", "data": 2, "valid": true }, { "description": "another value is invalid", "data": 5, "valid": false }, { "description": "another type is invalid", "data": "a", "valid": false } ] }, { "description": "const with object", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "const": {"foo": "bar", "baz": "bax"} }, "tests": [ { "description": "same object is valid", "data": {"foo": "bar", "baz": "bax"}, "valid": true }, { "description": "same object with different property order is valid", "data": {"baz": "bax", "foo": "bar"}, "valid": true }, { "description": "another object is invalid", "data": {"foo": "bar"}, "valid": false }, { "description": "another type is invalid", "data": [1, 2], "valid": false } ] }, { "description": "const with array", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "const": [{ "foo": "bar" }] }, "tests": [ { "description": "same array is valid", "data": [{"foo": "bar"}], "valid": true }, { "description": "another array item is invalid", "data": [2], "valid": false }, { "description": "array with additional items is invalid", "data": [1, 2, 3], "valid": false } ] }, { "description": "const with null", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "const": null }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "not null is invalid", "data": 0, "valid": false } ] }, { "description": "const with false does not match 0", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "const": false }, "tests": [ { "description": "false is valid", "data": false, "valid": true }, { "description": "integer zero is invalid", "data": 0, "valid": false }, { "description": "float zero is invalid", "data": 0.0, "valid": false } ] }, { "description": "const with true does not match 1", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "const": true }, "tests": [ { "description": "true is valid", "data": true, "valid": true }, { "description": "integer one is invalid", "data": 1, "valid": false }, { "description": "float one is invalid", "data": 1.0, "valid": false } ] }, { "description": "const with [false] does not match [0]", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "const": [false] }, "tests": [ { "description": "[false] is valid", "data": [false], "valid": true }, { "description": "[0] is invalid", "data": [0], "valid": false }, { "description": "[0.0] is invalid", "data": [0.0], "valid": false } ] }, { "description": "const with [true] does not match [1]", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "const": [true] }, "tests": [ { "description": "[true] is valid", "data": [true], "valid": true }, { "description": "[1] is invalid", "data": [1], "valid": false }, { "description": "[1.0] is invalid", "data": [1.0], "valid": false } ] }, { "description": "const with {\"a\": false} does not match {\"a\": 0}", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "const": {"a": false} }, "tests": [ { "description": "{\"a\": false} is valid", "data": {"a": false}, "valid": true }, { "description": "{\"a\": 0} is invalid", "data": {"a": 0}, "valid": false }, { "description": "{\"a\": 0.0} is invalid", "data": {"a": 0.0}, "valid": false } ] }, { "description": "const with {\"a\": true} does not match {\"a\": 1}", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "const": {"a": true} }, "tests": [ { "description": "{\"a\": true} is valid", "data": {"a": true}, "valid": true }, { "description": "{\"a\": 1} is invalid", "data": {"a": 1}, "valid": false }, { "description": "{\"a\": 1.0} is invalid", "data": {"a": 1.0}, "valid": false } ] }, { "description": "const with 0 does not match other zero-like types", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "const": 0 }, "tests": [ { "description": "false is invalid", "data": false, "valid": false }, { "description": "integer zero is valid", "data": 0, "valid": true }, { "description": "float zero is valid", "data": 0.0, "valid": true }, { "description": "empty object is invalid", "data": {}, "valid": false }, { "description": "empty array is invalid", "data": [], "valid": false }, { "description": "empty string is invalid", "data": "", "valid": false } ] }, { "description": "const with 1 does not match true", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "const": 1 }, "tests": [ { "description": "true is invalid", "data": true, "valid": false }, { "description": "integer one is valid", "data": 1, "valid": true }, { "description": "float one is valid", "data": 1.0, "valid": true } ] }, { "description": "const with -2.0 matches integer and float types", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "const": -2.0 }, "tests": [ { "description": "integer -2 is valid", "data": -2, "valid": true }, { "description": "integer 2 is invalid", "data": 2, "valid": false }, { "description": "float -2.0 is valid", "data": -2.0, "valid": true }, { "description": "float 2.0 is invalid", "data": 2.0, "valid": false }, { "description": "float -2.00001 is invalid", "data": -2.00001, "valid": false } ] }, { "description": "float and integers are equal up to 64-bit representation limits", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "const": 9007199254740992 }, "tests": [ { "description": "integer is valid", "data": 9007199254740992, "valid": true }, { "description": "integer minus one is invalid", "data": 9007199254740991, "valid": false }, { "description": "float is valid", "data": 9007199254740992.0, "valid": true }, { "description": "float minus one is invalid", "data": 9007199254740991.0, "valid": false } ] }, { "description": "nul characters in strings", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "const": "hello\u0000there" }, "tests": [ { "description": "match string with nul", "data": "hello\u0000there", "valid": true }, { "description": "do not match string lacking nul", "data": "hellothere", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/contains.json000066400000000000000000000120661477700171100301460ustar00rootroot00000000000000[ { "description": "contains keyword validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "contains": {"minimum": 5} }, "tests": [ { "description": "array with item matching schema (5) is valid", "data": [3, 4, 5], "valid": true }, { "description": "array with item matching schema (6) is valid", "data": [3, 4, 6], "valid": true }, { "description": "array with two items matching schema (5, 6) is valid", "data": [3, 4, 5, 6], "valid": true }, { "description": "array without items matching schema is invalid", "data": [2, 3, 4], "valid": false }, { "description": "empty array is invalid", "data": [], "valid": false }, { "description": "not array is valid", "data": {}, "valid": true } ] }, { "description": "contains keyword with const keyword", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "contains": { "const": 5 } }, "tests": [ { "description": "array with item 5 is valid", "data": [3, 4, 5], "valid": true }, { "description": "array with two items 5 is valid", "data": [3, 4, 5, 5], "valid": true }, { "description": "array without item 5 is invalid", "data": [1, 2, 3, 4], "valid": false } ] }, { "description": "contains keyword with boolean schema true", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "contains": true }, "tests": [ { "description": "any non-empty array is valid", "data": ["foo"], "valid": true }, { "description": "empty array is invalid", "data": [], "valid": false } ] }, { "description": "contains keyword with boolean schema false", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "contains": false }, "tests": [ { "description": "any non-empty array is invalid", "data": ["foo"], "valid": false }, { "description": "empty array is invalid", "data": [], "valid": false }, { "description": "non-arrays are valid", "data": "contains does not apply to strings", "valid": true } ] }, { "description": "items + contains", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "items": { "multipleOf": 2 }, "contains": { "multipleOf": 3 } }, "tests": [ { "description": "matches items, does not match contains", "data": [ 2, 4, 8 ], "valid": false }, { "description": "does not match items, matches contains", "data": [ 3, 6, 9 ], "valid": false }, { "description": "matches both items and contains", "data": [ 6, 12 ], "valid": true }, { "description": "matches neither items nor contains", "data": [ 1, 5 ], "valid": false } ] }, { "description": "contains with false if subschema", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "contains": { "if": false, "else": true } }, "tests": [ { "description": "any non-empty array is valid", "data": ["foo"], "valid": true }, { "description": "empty array is invalid", "data": [], "valid": false } ] }, { "description": "contains with null instance elements", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "contains": { "type": "null" } }, "tests": [ { "description": "allows null items", "data": [ null ], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/content.json000066400000000000000000000104551477700171100300020ustar00rootroot00000000000000[ { "description": "validation of string-encoded content based on media type", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "contentMediaType": "application/json" }, "tests": [ { "description": "a valid JSON document", "data": "{\"foo\": \"bar\"}", "valid": true }, { "description": "an invalid JSON document; validates true", "data": "{:}", "valid": true }, { "description": "ignores non-strings", "data": 100, "valid": true } ] }, { "description": "validation of binary string-encoding", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "contentEncoding": "base64" }, "tests": [ { "description": "a valid base64 string", "data": "eyJmb28iOiAiYmFyIn0K", "valid": true }, { "description": "an invalid base64 string (% is not a valid character); validates true", "data": "eyJmb28iOi%iYmFyIn0K", "valid": true }, { "description": "ignores non-strings", "data": 100, "valid": true } ] }, { "description": "validation of binary-encoded media type documents", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "contentMediaType": "application/json", "contentEncoding": "base64" }, "tests": [ { "description": "a valid base64-encoded JSON document", "data": "eyJmb28iOiAiYmFyIn0K", "valid": true }, { "description": "a validly-encoded invalid JSON document; validates true", "data": "ezp9Cg==", "valid": true }, { "description": "an invalid base64 string that is valid JSON; validates true", "data": "{}", "valid": true }, { "description": "ignores non-strings", "data": 100, "valid": true } ] }, { "description": "validation of binary-encoded media type documents with schema", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "contentMediaType": "application/json", "contentEncoding": "base64", "contentSchema": { "type": "object", "required": ["foo"], "properties": { "foo": { "type": "string" } } } }, "tests": [ { "description": "a valid base64-encoded JSON document", "data": "eyJmb28iOiAiYmFyIn0K", "valid": true }, { "description": "another valid base64-encoded JSON document", "data": "eyJib28iOiAyMCwgImZvbyI6ICJiYXoifQ==", "valid": true }, { "description": "an invalid base64-encoded JSON document; validates true", "data": "eyJib28iOiAyMH0=", "valid": true }, { "description": "an empty object as a base64-encoded JSON document; validates true", "data": "e30=", "valid": true }, { "description": "an empty array as a base64-encoded JSON document", "data": "W10=", "valid": true }, { "description": "a validly-encoded invalid JSON document; validates true", "data": "ezp9Cg==", "valid": true }, { "description": "an invalid base64 string that is valid JSON; validates true", "data": "{}", "valid": true }, { "description": "ignores non-strings", "data": 100, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/default.json000066400000000000000000000046141477700171100277540ustar00rootroot00000000000000[ { "description": "invalid type for default", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "foo": { "type": "integer", "default": [] } } }, "tests": [ { "description": "valid when property is specified", "data": {"foo": 13}, "valid": true }, { "description": "still valid when the invalid default is used", "data": {}, "valid": true } ] }, { "description": "invalid string value for default", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "bar": { "type": "string", "minLength": 4, "default": "bad" } } }, "tests": [ { "description": "valid when property is specified", "data": {"bar": "good"}, "valid": true }, { "description": "still valid when the invalid default is used", "data": {}, "valid": true } ] }, { "description": "the default keyword does not do anything if the property is missing", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "alpha": { "type": "number", "maximum": 3, "default": 5 } } }, "tests": [ { "description": "an explicit property value is checked against maximum (passing)", "data": { "alpha": 1 }, "valid": true }, { "description": "an explicit property value is checked against maximum (failing)", "data": { "alpha": 5 }, "valid": false }, { "description": "missing properties are not filled in with the default", "data": {}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/defs.json000066400000000000000000000011751477700171100272500ustar00rootroot00000000000000[ { "description": "validate definition against metaschema", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "https://json-schema.org/draft/2020-12/schema" }, "tests": [ { "description": "valid definition schema", "data": {"$defs": {"foo": {"type": "integer"}}}, "valid": true }, { "description": "invalid definition schema", "data": {"$defs": {"foo": {"type": 1}}}, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/dependentRequired.json000066400000000000000000000103061477700171100317720ustar00rootroot00000000000000[ { "description": "single dependency", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "dependentRequired": {"bar": ["foo"]} }, "tests": [ { "description": "neither", "data": {}, "valid": true }, { "description": "nondependant", "data": {"foo": 1}, "valid": true }, { "description": "with dependency", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "missing dependency", "data": {"bar": 2}, "valid": false }, { "description": "ignores arrays", "data": ["bar"], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "empty dependents", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "dependentRequired": {"bar": []} }, "tests": [ { "description": "empty object", "data": {}, "valid": true }, { "description": "object with one property", "data": {"bar": 2}, "valid": true }, { "description": "non-object is valid", "data": 1, "valid": true } ] }, { "description": "multiple dependents required", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "dependentRequired": {"quux": ["foo", "bar"]} }, "tests": [ { "description": "neither", "data": {}, "valid": true }, { "description": "nondependants", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "with dependencies", "data": {"foo": 1, "bar": 2, "quux": 3}, "valid": true }, { "description": "missing dependency", "data": {"foo": 1, "quux": 2}, "valid": false }, { "description": "missing other dependency", "data": {"bar": 1, "quux": 2}, "valid": false }, { "description": "missing both dependencies", "data": {"quux": 1}, "valid": false } ] }, { "description": "dependencies with escaped characters", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "dependentRequired": { "foo\nbar": ["foo\rbar"], "foo\"bar": ["foo'bar"] } }, "tests": [ { "description": "CRLF", "data": { "foo\nbar": 1, "foo\rbar": 2 }, "valid": true }, { "description": "quoted quotes", "data": { "foo'bar": 1, "foo\"bar": 2 }, "valid": true }, { "description": "CRLF missing dependent", "data": { "foo\nbar": 1, "foo": 2 }, "valid": false }, { "description": "quoted quotes missing dependent", "data": { "foo\"bar": 2 }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/dependentSchemas.json000066400000000000000000000115551477700171100316040ustar00rootroot00000000000000[ { "description": "single dependency", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "dependentSchemas": { "bar": { "properties": { "foo": {"type": "integer"}, "bar": {"type": "integer"} } } } }, "tests": [ { "description": "valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "no dependency", "data": {"foo": "quux"}, "valid": true }, { "description": "wrong type", "data": {"foo": "quux", "bar": 2}, "valid": false }, { "description": "wrong type other", "data": {"foo": 2, "bar": "quux"}, "valid": false }, { "description": "wrong type both", "data": {"foo": "quux", "bar": "quux"}, "valid": false }, { "description": "ignores arrays", "data": ["bar"], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "boolean subschemas", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "dependentSchemas": { "foo": true, "bar": false } }, "tests": [ { "description": "object with property having schema true is valid", "data": {"foo": 1}, "valid": true }, { "description": "object with property having schema false is invalid", "data": {"bar": 2}, "valid": false }, { "description": "object with both properties is invalid", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "empty object is valid", "data": {}, "valid": true } ] }, { "description": "dependencies with escaped characters", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "dependentSchemas": { "foo\tbar": {"minProperties": 4}, "foo'bar": {"required": ["foo\"bar"]} } }, "tests": [ { "description": "quoted tab", "data": { "foo\tbar": 1, "a": 2, "b": 3, "c": 4 }, "valid": true }, { "description": "quoted quote", "data": { "foo'bar": {"foo\"bar": 1} }, "valid": false }, { "description": "quoted tab invalid under dependent schema", "data": { "foo\tbar": 1, "a": 2 }, "valid": false }, { "description": "quoted quote invalid under dependent schema", "data": {"foo'bar": 1}, "valid": false } ] }, { "description": "dependent subschema incompatible with root", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "foo": {} }, "dependentSchemas": { "foo": { "properties": { "bar": {} }, "additionalProperties": false } } }, "tests": [ { "description": "matches root", "data": {"foo": 1}, "valid": false }, { "description": "matches dependency", "data": {"bar": 1}, "valid": true }, { "description": "matches both", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "no dependency", "data": {"baz": 1}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/dynamicRef.json000066400000000000000000000602721477700171100304130ustar00rootroot00000000000000[ { "description": "A $dynamicRef to a $dynamicAnchor in the same schema resource behaves like a normal $ref to an $anchor", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://test.json-schema.org/dynamicRef-dynamicAnchor-same-schema/root", "type": "array", "items": { "$dynamicRef": "#items" }, "$defs": { "foo": { "$dynamicAnchor": "items", "type": "string" } } }, "tests": [ { "description": "An array of strings is valid", "data": ["foo", "bar"], "valid": true }, { "description": "An array containing non-strings is invalid", "data": ["foo", 42], "valid": false } ] }, { "description": "A $dynamicRef to an $anchor in the same schema resource behaves like a normal $ref to an $anchor", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://test.json-schema.org/dynamicRef-anchor-same-schema/root", "type": "array", "items": { "$dynamicRef": "#items" }, "$defs": { "foo": { "$anchor": "items", "type": "string" } } }, "tests": [ { "description": "An array of strings is valid", "data": ["foo", "bar"], "valid": true }, { "description": "An array containing non-strings is invalid", "data": ["foo", 42], "valid": false } ] }, { "description": "A $ref to a $dynamicAnchor in the same schema resource behaves like a normal $ref to an $anchor", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://test.json-schema.org/ref-dynamicAnchor-same-schema/root", "type": "array", "items": { "$ref": "#items" }, "$defs": { "foo": { "$dynamicAnchor": "items", "type": "string" } } }, "tests": [ { "description": "An array of strings is valid", "data": ["foo", "bar"], "valid": true }, { "description": "An array containing non-strings is invalid", "data": ["foo", 42], "valid": false } ] }, { "description": "A $dynamicRef resolves to the first $dynamicAnchor still in scope that is encountered when the schema is evaluated", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://test.json-schema.org/typical-dynamic-resolution/root", "$ref": "list", "$defs": { "foo": { "$dynamicAnchor": "items", "type": "string" }, "list": { "$id": "list", "type": "array", "items": { "$dynamicRef": "#items" }, "$defs": { "items": { "$comment": "This is only needed to satisfy the bookending requirement", "$dynamicAnchor": "items" } } } } }, "tests": [ { "description": "An array of strings is valid", "data": ["foo", "bar"], "valid": true }, { "description": "An array containing non-strings is invalid", "data": ["foo", 42], "valid": false } ] }, { "description": "A $dynamicRef without anchor in fragment behaves identical to $ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://test.json-schema.org/dynamicRef-without-anchor/root", "$ref": "list", "$defs": { "foo": { "$dynamicAnchor": "items", "type": "string" }, "list": { "$id": "list", "type": "array", "items": { "$dynamicRef": "#/$defs/items" }, "$defs": { "items": { "$comment": "This is only needed to satisfy the bookending requirement", "$dynamicAnchor": "items", "type": "number" } } } } }, "tests": [ { "description": "An array of strings is invalid", "data": ["foo", "bar"], "valid": false }, { "description": "An array of numbers is valid", "data": [24, 42], "valid": true } ] }, { "description": "A $dynamicRef with intermediate scopes that don't include a matching $dynamicAnchor does not affect dynamic scope resolution", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://test.json-schema.org/dynamic-resolution-with-intermediate-scopes/root", "$ref": "intermediate-scope", "$defs": { "foo": { "$dynamicAnchor": "items", "type": "string" }, "intermediate-scope": { "$id": "intermediate-scope", "$ref": "list" }, "list": { "$id": "list", "type": "array", "items": { "$dynamicRef": "#items" }, "$defs": { "items": { "$comment": "This is only needed to satisfy the bookending requirement", "$dynamicAnchor": "items" } } } } }, "tests": [ { "description": "An array of strings is valid", "data": ["foo", "bar"], "valid": true }, { "description": "An array containing non-strings is invalid", "data": ["foo", 42], "valid": false } ] }, { "description": "An $anchor with the same name as a $dynamicAnchor is not used for dynamic scope resolution", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://test.json-schema.org/dynamic-resolution-ignores-anchors/root", "$ref": "list", "$defs": { "foo": { "$anchor": "items", "type": "string" }, "list": { "$id": "list", "type": "array", "items": { "$dynamicRef": "#items" }, "$defs": { "items": { "$comment": "This is only needed to satisfy the bookending requirement", "$dynamicAnchor": "items" } } } } }, "tests": [ { "description": "Any array is valid", "data": ["foo", 42], "valid": true } ] }, { "description": "A $dynamicRef without a matching $dynamicAnchor in the same schema resource behaves like a normal $ref to $anchor", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://test.json-schema.org/dynamic-resolution-without-bookend/root", "$ref": "list", "$defs": { "foo": { "$dynamicAnchor": "items", "type": "string" }, "list": { "$id": "list", "type": "array", "items": { "$dynamicRef": "#items" }, "$defs": { "items": { "$comment": "This is only needed to give the reference somewhere to resolve to when it behaves like $ref", "$anchor": "items" } } } } }, "tests": [ { "description": "Any array is valid", "data": ["foo", 42], "valid": true } ] }, { "description": "A $dynamicRef with a non-matching $dynamicAnchor in the same schema resource behaves like a normal $ref to $anchor", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://test.json-schema.org/unmatched-dynamic-anchor/root", "$ref": "list", "$defs": { "foo": { "$dynamicAnchor": "items", "type": "string" }, "list": { "$id": "list", "type": "array", "items": { "$dynamicRef": "#items" }, "$defs": { "items": { "$comment": "This is only needed to give the reference somewhere to resolve to when it behaves like $ref", "$anchor": "items", "$dynamicAnchor": "foo" } } } } }, "tests": [ { "description": "Any array is valid", "data": ["foo", 42], "valid": true } ] }, { "description": "A $dynamicRef that initially resolves to a schema with a matching $dynamicAnchor resolves to the first $dynamicAnchor in the dynamic scope", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://test.json-schema.org/relative-dynamic-reference/root", "$dynamicAnchor": "meta", "type": "object", "properties": { "foo": { "const": "pass" } }, "$ref": "extended", "$defs": { "extended": { "$id": "extended", "$dynamicAnchor": "meta", "type": "object", "properties": { "bar": { "$ref": "bar" } } }, "bar": { "$id": "bar", "type": "object", "properties": { "baz": { "$dynamicRef": "extended#meta" } } } } }, "tests": [ { "description": "The recursive part is valid against the root", "data": { "foo": "pass", "bar": { "baz": { "foo": "pass" } } }, "valid": true }, { "description": "The recursive part is not valid against the root", "data": { "foo": "pass", "bar": { "baz": { "foo": "fail" } } }, "valid": false } ] }, { "description": "A $dynamicRef that initially resolves to a schema without a matching $dynamicAnchor behaves like a normal $ref to $anchor", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://test.json-schema.org/relative-dynamic-reference-without-bookend/root", "$dynamicAnchor": "meta", "type": "object", "properties": { "foo": { "const": "pass" } }, "$ref": "extended", "$defs": { "extended": { "$id": "extended", "$anchor": "meta", "type": "object", "properties": { "bar": { "$ref": "bar" } } }, "bar": { "$id": "bar", "type": "object", "properties": { "baz": { "$dynamicRef": "extended#meta" } } } } }, "tests": [ { "description": "The recursive part doesn't need to validate against the root", "data": { "foo": "pass", "bar": { "baz": { "foo": "fail" } } }, "valid": true } ] }, { "description": "multiple dynamic paths to the $dynamicRef keyword", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://test.json-schema.org/dynamic-ref-with-multiple-paths/main", "if": { "properties": { "kindOfList": { "const": "numbers" } }, "required": ["kindOfList"] }, "then": { "$ref": "numberList" }, "else": { "$ref": "stringList" }, "$defs": { "genericList": { "$id": "genericList", "properties": { "list": { "items": { "$dynamicRef": "#itemType" } } }, "$defs": { "defaultItemType": { "$comment": "Only needed to satisfy bookending requirement", "$dynamicAnchor": "itemType" } } }, "numberList": { "$id": "numberList", "$defs": { "itemType": { "$dynamicAnchor": "itemType", "type": "number" } }, "$ref": "genericList" }, "stringList": { "$id": "stringList", "$defs": { "itemType": { "$dynamicAnchor": "itemType", "type": "string" } }, "$ref": "genericList" } } }, "tests": [ { "description": "number list with number values", "data": { "kindOfList": "numbers", "list": [1.1] }, "valid": true }, { "description": "number list with string values", "data": { "kindOfList": "numbers", "list": ["foo"] }, "valid": false }, { "description": "string list with number values", "data": { "kindOfList": "strings", "list": [1.1] }, "valid": false }, { "description": "string list with string values", "data": { "kindOfList": "strings", "list": ["foo"] }, "valid": true } ] }, { "description": "after leaving a dynamic scope, it is not used by a $dynamicRef", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://test.json-schema.org/dynamic-ref-leaving-dynamic-scope/main", "if": { "$id": "first_scope", "$defs": { "thingy": { "$comment": "this is first_scope#thingy", "$dynamicAnchor": "thingy", "type": "number" } } }, "then": { "$id": "second_scope", "$ref": "start", "$defs": { "thingy": { "$comment": "this is second_scope#thingy, the final destination of the $dynamicRef", "$dynamicAnchor": "thingy", "type": "null" } } }, "$defs": { "start": { "$comment": "this is the landing spot from $ref", "$id": "start", "$dynamicRef": "inner_scope#thingy" }, "thingy": { "$comment": "this is the first stop for the $dynamicRef", "$id": "inner_scope", "$dynamicAnchor": "thingy", "type": "string" } } }, "tests": [ { "description": "string matches /$defs/thingy, but the $dynamicRef does not stop here", "data": "a string", "valid": false }, { "description": "first_scope is not in dynamic scope for the $dynamicRef", "data": 42, "valid": false }, { "description": "/then/$defs/thingy is the final stop for the $dynamicRef", "data": null, "valid": true } ] }, { "description": "strict-tree schema, guards against misspelled properties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://localhost:1234/draft2020-12/strict-tree.json", "$dynamicAnchor": "node", "$ref": "tree.json", "unevaluatedProperties": false }, "tests": [ { "description": "instance with misspelled field", "data": { "children": [{ "daat": 1 }] }, "valid": false }, { "description": "instance with correct field", "data": { "children": [{ "data": 1 }] }, "valid": true } ] }, { "description": "tests for implementation dynamic anchor and reference link", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://localhost:1234/draft2020-12/strict-extendible.json", "$ref": "extendible-dynamic-ref.json", "$defs": { "elements": { "$dynamicAnchor": "elements", "properties": { "a": true }, "required": ["a"], "additionalProperties": false } } }, "tests": [ { "description": "incorrect parent schema", "data": { "a": true }, "valid": false }, { "description": "incorrect extended schema", "data": { "elements": [ { "b": 1 } ] }, "valid": false }, { "description": "correct extended schema", "data": { "elements": [ { "a": 1 } ] }, "valid": true } ] }, { "description": "$ref and $dynamicAnchor are independent of order - $defs first", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://localhost:1234/draft2020-12/strict-extendible-allof-defs-first.json", "allOf": [ { "$ref": "extendible-dynamic-ref.json" }, { "$defs": { "elements": { "$dynamicAnchor": "elements", "properties": { "a": true }, "required": ["a"], "additionalProperties": false } } } ] }, "tests": [ { "description": "incorrect parent schema", "data": { "a": true }, "valid": false }, { "description": "incorrect extended schema", "data": { "elements": [ { "b": 1 } ] }, "valid": false }, { "description": "correct extended schema", "data": { "elements": [ { "a": 1 } ] }, "valid": true } ] }, { "description": "$ref and $dynamicAnchor are independent of order - $ref first", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://localhost:1234/draft2020-12/strict-extendible-allof-ref-first.json", "allOf": [ { "$defs": { "elements": { "$dynamicAnchor": "elements", "properties": { "a": true }, "required": ["a"], "additionalProperties": false } } }, { "$ref": "extendible-dynamic-ref.json" } ] }, "tests": [ { "description": "incorrect parent schema", "data": { "a": true }, "valid": false }, { "description": "incorrect extended schema", "data": { "elements": [ { "b": 1 } ] }, "valid": false }, { "description": "correct extended schema", "data": { "elements": [ { "a": 1 } ] }, "valid": true } ] }, { "description": "$ref to $dynamicRef finds detached $dynamicAnchor", "schema": { "$ref": "http://localhost:1234/draft2020-12/detached-dynamicref.json#/$defs/foo" }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/enum.json000066400000000000000000000164251477700171100272770ustar00rootroot00000000000000[ { "description": "simple enum validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "enum": [1, 2, 3] }, "tests": [ { "description": "one of the enum is valid", "data": 1, "valid": true }, { "description": "something else is invalid", "data": 4, "valid": false } ] }, { "description": "heterogeneous enum validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "enum": [6, "foo", [], true, {"foo": 12}] }, "tests": [ { "description": "one of the enum is valid", "data": [], "valid": true }, { "description": "something else is invalid", "data": null, "valid": false }, { "description": "objects are deep compared", "data": {"foo": false}, "valid": false }, { "description": "valid object matches", "data": {"foo": 12}, "valid": true }, { "description": "extra properties in object is invalid", "data": {"foo": 12, "boo": 42}, "valid": false } ] }, { "description": "heterogeneous enum-with-null validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "enum": [6, null] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "number is valid", "data": 6, "valid": true }, { "description": "something else is invalid", "data": "test", "valid": false } ] }, { "description": "enums in properties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type":"object", "properties": { "foo": {"enum":["foo"]}, "bar": {"enum":["bar"]} }, "required": ["bar"] }, "tests": [ { "description": "both properties are valid", "data": {"foo":"foo", "bar":"bar"}, "valid": true }, { "description": "wrong foo value", "data": {"foo":"foot", "bar":"bar"}, "valid": false }, { "description": "wrong bar value", "data": {"foo":"foo", "bar":"bart"}, "valid": false }, { "description": "missing optional property is valid", "data": {"bar":"bar"}, "valid": true }, { "description": "missing required property is invalid", "data": {"foo":"foo"}, "valid": false }, { "description": "missing all properties is invalid", "data": {}, "valid": false } ] }, { "description": "enum with escaped characters", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "enum": ["foo\nbar", "foo\rbar"] }, "tests": [ { "description": "member 1 is valid", "data": "foo\nbar", "valid": true }, { "description": "member 2 is valid", "data": "foo\rbar", "valid": true }, { "description": "another string is invalid", "data": "abc", "valid": false } ] }, { "description": "enum with false does not match 0", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "enum": [false] }, "tests": [ { "description": "false is valid", "data": false, "valid": true }, { "description": "integer zero is invalid", "data": 0, "valid": false }, { "description": "float zero is invalid", "data": 0.0, "valid": false } ] }, { "description": "enum with true does not match 1", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "enum": [true] }, "tests": [ { "description": "true is valid", "data": true, "valid": true }, { "description": "integer one is invalid", "data": 1, "valid": false }, { "description": "float one is invalid", "data": 1.0, "valid": false } ] }, { "description": "enum with 0 does not match false", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "enum": [0] }, "tests": [ { "description": "false is invalid", "data": false, "valid": false }, { "description": "integer zero is valid", "data": 0, "valid": true }, { "description": "float zero is valid", "data": 0.0, "valid": true } ] }, { "description": "enum with 1 does not match true", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "enum": [1] }, "tests": [ { "description": "true is invalid", "data": true, "valid": false }, { "description": "integer one is valid", "data": 1, "valid": true }, { "description": "float one is valid", "data": 1.0, "valid": true } ] }, { "description": "nul characters in strings", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "enum": [ "hello\u0000there" ] }, "tests": [ { "description": "match string with nul", "data": "hello\u0000there", "valid": true }, { "description": "do not match string lacking nul", "data": "hellothere", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/exclusiveMaximum.json000066400000000000000000000015161477700171100316730ustar00rootroot00000000000000[ { "description": "exclusiveMaximum validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "exclusiveMaximum": 3.0 }, "tests": [ { "description": "below the exclusiveMaximum is valid", "data": 2.2, "valid": true }, { "description": "boundary point is invalid", "data": 3.0, "valid": false }, { "description": "above the exclusiveMaximum is invalid", "data": 3.5, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/exclusiveMinimum.json000066400000000000000000000015161477700171100316710ustar00rootroot00000000000000[ { "description": "exclusiveMinimum validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "exclusiveMinimum": 1.1 }, "tests": [ { "description": "above the exclusiveMinimum is valid", "data": 1.2, "valid": true }, { "description": "boundary point is invalid", "data": 1.1, "valid": false }, { "description": "below the exclusiveMinimum is invalid", "data": 0.6, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/format.json000066400000000000000000000620541477700171100276220ustar00rootroot00000000000000[ { "description": "email format", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "email" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid email string is only an annotation by default", "data": "2962", "valid": true } ] }, { "description": "idn-email format", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "idn-email" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid idn-email string is only an annotation by default", "data": "2962", "valid": true } ] }, { "description": "regex format", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "regex" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid regex string is only an annotation by default", "data": "^(abc]", "valid": true } ] }, { "description": "ipv4 format", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "ipv4" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid ipv4 string is only an annotation by default", "data": "127.0.0.0.1", "valid": true } ] }, { "description": "ipv6 format", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "ipv6" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid ipv6 string is only an annotation by default", "data": "12345::", "valid": true } ] }, { "description": "idn-hostname format", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "idn-hostname" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid idn-hostname string is only an annotation by default", "data": "〮실례.테스트", "valid": true } ] }, { "description": "hostname format", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "hostname" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid hostname string is only an annotation by default", "data": "-a-host-name-that-starts-with--", "valid": true } ] }, { "description": "date format", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "date" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid date string is only an annotation by default", "data": "06/19/1963", "valid": true } ] }, { "description": "date-time format", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "date-time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid date-time string is only an annotation by default", "data": "1990-02-31T15:59:60.123-08:00", "valid": true } ] }, { "description": "time format", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid time string is only an annotation by default", "data": "08:30:06 PST", "valid": true } ] }, { "description": "json-pointer format", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "json-pointer" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid json-pointer string is only an annotation by default", "data": "/foo/bar~", "valid": true } ] }, { "description": "relative-json-pointer format", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "relative-json-pointer" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid relative-json-pointer string is only an annotation by default", "data": "/foo/bar", "valid": true } ] }, { "description": "iri format", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "iri" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid iri string is only an annotation by default", "data": "http://2001:0db8:85a3:0000:0000:8a2e:0370:7334", "valid": true } ] }, { "description": "iri-reference format", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "iri-reference" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid iri-reference string is only an annotation by default", "data": "\\\\WINDOWS\\filëßåré", "valid": true } ] }, { "description": "uri format", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "uri" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid uri string is only an annotation by default", "data": "//foo.bar/?baz=qux#quux", "valid": true } ] }, { "description": "uri-reference format", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "uri-reference" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid uri-reference string is only an annotation by default", "data": "\\\\WINDOWS\\fileshare", "valid": true } ] }, { "description": "uri-template format", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "uri-template" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid uri-template string is only an annotation by default", "data": "http://example.com/dictionary/{term:1}/{term", "valid": true } ] }, { "description": "uuid format", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "uuid" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid uuid string is only an annotation by default", "data": "2eb8aa08-aa98-11ea-b4aa-73b441d1638", "valid": true } ] }, { "description": "duration format", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "duration" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "invalid duration string is only an annotation by default", "data": "PT1D", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/id.json000066400000000000000000000240661477700171100267270ustar00rootroot00000000000000[ { "description": "Invalid use of fragments in location-independent $id", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "https://json-schema.org/draft/2020-12/schema" }, "tests": [ { "description": "Identifier name", "data": { "$ref": "#foo", "$defs": { "A": { "$id": "#foo", "type": "integer" } } }, "valid": false }, { "description": "Identifier name and no ref", "data": { "$defs": { "A": { "$id": "#foo" } } }, "valid": false }, { "description": "Identifier path", "data": { "$ref": "#/a/b", "$defs": { "A": { "$id": "#/a/b", "type": "integer" } } }, "valid": false }, { "description": "Identifier name with absolute URI", "data": { "$ref": "http://localhost:1234/draft2020-12/bar#foo", "$defs": { "A": { "$id": "http://localhost:1234/draft2020-12/bar#foo", "type": "integer" } } }, "valid": false }, { "description": "Identifier path with absolute URI", "data": { "$ref": "http://localhost:1234/draft2020-12/bar#/a/b", "$defs": { "A": { "$id": "http://localhost:1234/draft2020-12/bar#/a/b", "type": "integer" } } }, "valid": false }, { "description": "Identifier name with base URI change in subschema", "data": { "$id": "http://localhost:1234/draft2020-12/root", "$ref": "http://localhost:1234/draft2020-12/nested.json#foo", "$defs": { "A": { "$id": "nested.json", "$defs": { "B": { "$id": "#foo", "type": "integer" } } } } }, "valid": false }, { "description": "Identifier path with base URI change in subschema", "data": { "$id": "http://localhost:1234/draft2020-12/root", "$ref": "http://localhost:1234/draft2020-12/nested.json#/a/b", "$defs": { "A": { "$id": "nested.json", "$defs": { "B": { "$id": "#/a/b", "type": "integer" } } } } }, "valid": false } ] }, { "description": "Valid use of empty fragments in location-independent $id", "comment": "These are allowed but discouraged", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "https://json-schema.org/draft/2020-12/schema" }, "tests": [ { "description": "Identifier name with absolute URI", "data": { "$ref": "http://localhost:1234/draft2020-12/bar", "$defs": { "A": { "$id": "http://localhost:1234/draft2020-12/bar#", "type": "integer" } } }, "valid": true }, { "description": "Identifier name with base URI change in subschema", "data": { "$id": "http://localhost:1234/draft2020-12/root", "$ref": "http://localhost:1234/draft2020-12/nested.json#/$defs/B", "$defs": { "A": { "$id": "nested.json", "$defs": { "B": { "$id": "#", "type": "integer" } } } } }, "valid": true } ] }, { "description": "Unnormalized $ids are allowed but discouraged", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "https://json-schema.org/draft/2020-12/schema" }, "tests": [ { "description": "Unnormalized identifier", "data": { "$ref": "http://localhost:1234/draft2020-12/foo/baz", "$defs": { "A": { "$id": "http://localhost:1234/draft2020-12/foo/bar/../baz", "type": "integer" } } }, "valid": true }, { "description": "Unnormalized identifier and no ref", "data": { "$defs": { "A": { "$id": "http://localhost:1234/draft2020-12/foo/bar/../baz", "type": "integer" } } }, "valid": true }, { "description": "Unnormalized identifier with empty fragment", "data": { "$ref": "http://localhost:1234/draft2020-12/foo/baz", "$defs": { "A": { "$id": "http://localhost:1234/draft2020-12/foo/bar/../baz#", "type": "integer" } } }, "valid": true }, { "description": "Unnormalized identifier with empty fragment and no ref", "data": { "$defs": { "A": { "$id": "http://localhost:1234/draft2020-12/foo/bar/../baz#", "type": "integer" } } }, "valid": true } ] }, { "description": "$id inside an enum is not a real identifier", "comment": "the implementation must not be confused by an $id buried in the enum", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "id_in_enum": { "enum": [ { "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", "type": "null" } ] }, "real_id_in_schema": { "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", "type": "string" }, "zzz_id_in_const": { "const": { "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", "type": "null" } } }, "anyOf": [ { "$ref": "#/$defs/id_in_enum" }, { "$ref": "https://localhost:1234/draft2020-12/id/my_identifier.json" } ] }, "tests": [ { "description": "exact match to enum, and type matches", "data": { "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", "type": "null" }, "valid": true }, { "description": "match $ref to $id", "data": "a string to match #/$defs/id_in_enum", "valid": true }, { "description": "no match on enum or $ref to $id", "data": 1, "valid": false } ] }, { "description": "non-schema object containing an $id property", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "const_not_id": { "const": { "$id": "not_a_real_id" } } }, "if": { "const": "skip not_a_real_id" }, "then": true, "else" : { "$ref": "#/$defs/const_not_id" } }, "tests": [ { "description": "skip traversing definition for a valid result", "data": "skip not_a_real_id", "valid": true }, { "description": "const at const_not_id does not match", "data": 1, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/if-then-else.json000066400000000000000000000166301477700171100306110ustar00rootroot00000000000000[ { "description": "ignore if without then or else", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "if": { "const": 0 } }, "tests": [ { "description": "valid when valid against lone if", "data": 0, "valid": true }, { "description": "valid when invalid against lone if", "data": "hello", "valid": true } ] }, { "description": "ignore then without if", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "then": { "const": 0 } }, "tests": [ { "description": "valid when valid against lone then", "data": 0, "valid": true }, { "description": "valid when invalid against lone then", "data": "hello", "valid": true } ] }, { "description": "ignore else without if", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "else": { "const": 0 } }, "tests": [ { "description": "valid when valid against lone else", "data": 0, "valid": true }, { "description": "valid when invalid against lone else", "data": "hello", "valid": true } ] }, { "description": "if and then without else", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "if": { "exclusiveMaximum": 0 }, "then": { "minimum": -10 } }, "tests": [ { "description": "valid through then", "data": -1, "valid": true }, { "description": "invalid through then", "data": -100, "valid": false }, { "description": "valid when if test fails", "data": 3, "valid": true } ] }, { "description": "if and else without then", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "if": { "exclusiveMaximum": 0 }, "else": { "multipleOf": 2 } }, "tests": [ { "description": "valid when if test passes", "data": -1, "valid": true }, { "description": "valid through else", "data": 4, "valid": true }, { "description": "invalid through else", "data": 3, "valid": false } ] }, { "description": "validate against correct branch, then vs else", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "if": { "exclusiveMaximum": 0 }, "then": { "minimum": -10 }, "else": { "multipleOf": 2 } }, "tests": [ { "description": "valid through then", "data": -1, "valid": true }, { "description": "invalid through then", "data": -100, "valid": false }, { "description": "valid through else", "data": 4, "valid": true }, { "description": "invalid through else", "data": 3, "valid": false } ] }, { "description": "non-interference across combined schemas", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ { "if": { "exclusiveMaximum": 0 } }, { "then": { "minimum": -10 } }, { "else": { "multipleOf": 2 } } ] }, "tests": [ { "description": "valid, but would have been invalid through then", "data": -100, "valid": true }, { "description": "valid, but would have been invalid through else", "data": 3, "valid": true } ] }, { "description": "if with boolean schema true", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "if": true, "then": { "const": "then" }, "else": { "const": "else" } }, "tests": [ { "description": "boolean schema true in if always chooses the then path (valid)", "data": "then", "valid": true }, { "description": "boolean schema true in if always chooses the then path (invalid)", "data": "else", "valid": false } ] }, { "description": "if with boolean schema false", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "if": false, "then": { "const": "then" }, "else": { "const": "else" } }, "tests": [ { "description": "boolean schema false in if always chooses the else path (invalid)", "data": "then", "valid": false }, { "description": "boolean schema false in if always chooses the else path (valid)", "data": "else", "valid": true } ] }, { "description": "if appears at the end when serialized (keyword processing sequence)", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "then": { "const": "yes" }, "else": { "const": "other" }, "if": { "maxLength": 4 } }, "tests": [ { "description": "yes redirects to then and passes", "data": "yes", "valid": true }, { "description": "other redirects to else and passes", "data": "other", "valid": true }, { "description": "no redirects to then and fails", "data": "no", "valid": false }, { "description": "invalid redirects to else and fails", "data": "invalid", "valid": false } ] } ] infinite-loop-detection.json000066400000000000000000000020331477700171100327720ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12[ { "description": "evaluating the same schema location against the same data location twice is not a sign of an infinite loop", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "int": { "type": "integer" } }, "allOf": [ { "properties": { "foo": { "$ref": "#/$defs/int" } } }, { "additionalProperties": { "$ref": "#/$defs/int" } } ] }, "tests": [ { "description": "passing case", "data": { "foo": 1 }, "valid": true }, { "description": "failing case", "data": { "foo": "a string" }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/items.json000066400000000000000000000217711477700171100274540ustar00rootroot00000000000000[ { "description": "a schema given for items", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "items": {"type": "integer"} }, "tests": [ { "description": "valid items", "data": [ 1, 2, 3 ], "valid": true }, { "description": "wrong type of items", "data": [1, "x"], "valid": false }, { "description": "ignores non-arrays", "data": {"foo" : "bar"}, "valid": true }, { "description": "JavaScript pseudo-array is valid", "data": { "0": "invalid", "length": 1 }, "valid": true } ] }, { "description": "items with boolean schema (true)", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "items": true }, "tests": [ { "description": "any array is valid", "data": [ 1, "foo", true ], "valid": true }, { "description": "empty array is valid", "data": [], "valid": true } ] }, { "description": "items with boolean schema (false)", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "items": false }, "tests": [ { "description": "any non-empty array is invalid", "data": [ 1, "foo", true ], "valid": false }, { "description": "empty array is valid", "data": [], "valid": true } ] }, { "description": "items and subitems", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "item": { "type": "array", "items": false, "prefixItems": [ { "$ref": "#/$defs/sub-item" }, { "$ref": "#/$defs/sub-item" } ] }, "sub-item": { "type": "object", "required": ["foo"] } }, "type": "array", "items": false, "prefixItems": [ { "$ref": "#/$defs/item" }, { "$ref": "#/$defs/item" }, { "$ref": "#/$defs/item" } ] }, "tests": [ { "description": "valid items", "data": [ [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": true }, { "description": "too many items", "data": [ [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "too many sub-items", "data": [ [ {"foo": null}, {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "wrong item", "data": [ {"foo": null}, [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "wrong sub-item", "data": [ [ {}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "fewer items is valid", "data": [ [ {"foo": null} ], [ {"foo": null} ] ], "valid": true } ] }, { "description": "nested items", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "array", "items": { "type": "array", "items": { "type": "array", "items": { "type": "array", "items": { "type": "number" } } } } }, "tests": [ { "description": "valid nested array", "data": [[[[1]], [[2],[3]]], [[[4], [5], [6]]]], "valid": true }, { "description": "nested array with invalid type", "data": [[[["1"]], [[2],[3]]], [[[4], [5], [6]]]], "valid": false }, { "description": "not deep enough", "data": [[[1], [2],[3]], [[4], [5], [6]]], "valid": false } ] }, { "description": "prefixItems with no additional items allowed", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [{}, {}, {}], "items": false }, "tests": [ { "description": "empty array", "data": [ ], "valid": true }, { "description": "fewer number of items present (1)", "data": [ 1 ], "valid": true }, { "description": "fewer number of items present (2)", "data": [ 1, 2 ], "valid": true }, { "description": "equal number of items present", "data": [ 1, 2, 3 ], "valid": true }, { "description": "additional items are not permitted", "data": [ 1, 2, 3, 4 ], "valid": false } ] }, { "description": "items does not look in applicators, valid case", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ { "prefixItems": [ { "minimum": 3 } ] } ], "items": { "minimum": 5 } }, "tests": [ { "description": "prefixItems in allOf does not constrain items, invalid case", "data": [ 3, 5 ], "valid": false }, { "description": "prefixItems in allOf does not constrain items, valid case", "data": [ 5, 5 ], "valid": true } ] }, { "description": "prefixItems validation adjusts the starting index for items", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [ { "type": "string" } ], "items": { "type": "integer" } }, "tests": [ { "description": "valid items", "data": [ "x", 2, 3 ], "valid": true }, { "description": "wrong type of second item", "data": [ "x", "y" ], "valid": false } ] }, { "description": "items with heterogeneous array", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [{}], "items": false }, "tests": [ { "description": "heterogeneous invalid instance", "data": [ "foo", "bar", 37 ], "valid": false }, { "description": "valid instance", "data": [ null ], "valid": true } ] }, { "description": "items with null instance elements", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "items": { "type": "null" } }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/maxContains.json000066400000000000000000000057461477700171100306230ustar00rootroot00000000000000[ { "description": "maxContains without contains is ignored", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "maxContains": 1 }, "tests": [ { "description": "one item valid against lone maxContains", "data": [ 1 ], "valid": true }, { "description": "two items still valid against lone maxContains", "data": [ 1, 2 ], "valid": true } ] }, { "description": "maxContains with contains", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "contains": {"const": 1}, "maxContains": 1 }, "tests": [ { "description": "empty data", "data": [ ], "valid": false }, { "description": "all elements match, valid maxContains", "data": [ 1 ], "valid": true }, { "description": "all elements match, invalid maxContains", "data": [ 1, 1 ], "valid": false }, { "description": "some elements match, valid maxContains", "data": [ 1, 2 ], "valid": true }, { "description": "some elements match, invalid maxContains", "data": [ 1, 2, 1 ], "valid": false } ] }, { "description": "maxContains with contains, value with a decimal", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "contains": {"const": 1}, "maxContains": 1.0 }, "tests": [ { "description": "one element matches, valid maxContains", "data": [ 1 ], "valid": true }, { "description": "too many elements match, invalid maxContains", "data": [ 1, 1 ], "valid": false } ] }, { "description": "minContains < maxContains", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "contains": {"const": 1}, "minContains": 1, "maxContains": 3 }, "tests": [ { "description": "actual < minContains < maxContains", "data": [ ], "valid": false }, { "description": "minContains < actual < maxContains", "data": [ 1, 1 ], "valid": true }, { "description": "minContains < maxContains < actual", "data": [ 1, 1, 1, 1 ], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/maxItems.json000066400000000000000000000024471477700171100301210ustar00rootroot00000000000000[ { "description": "maxItems validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "maxItems": 2 }, "tests": [ { "description": "shorter is valid", "data": [1], "valid": true }, { "description": "exact length is valid", "data": [1, 2], "valid": true }, { "description": "too long is invalid", "data": [1, 2, 3], "valid": false }, { "description": "ignores non-arrays", "data": "foobar", "valid": true } ] }, { "description": "maxItems validation with a decimal", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "maxItems": 2.0 }, "tests": [ { "description": "shorter is valid", "data": [1], "valid": true }, { "description": "too long is invalid", "data": [1, 2, 3], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/maxLength.json000066400000000000000000000027431477700171100302600ustar00rootroot00000000000000[ { "description": "maxLength validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "maxLength": 2 }, "tests": [ { "description": "shorter is valid", "data": "f", "valid": true }, { "description": "exact length is valid", "data": "fo", "valid": true }, { "description": "too long is invalid", "data": "foo", "valid": false }, { "description": "ignores non-strings", "data": 100, "valid": true }, { "description": "two supplementary Unicode code points is long enough", "data": "\uD83D\uDCA9\uD83D\uDCA9", "valid": true } ] }, { "description": "maxLength validation with a decimal", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "maxLength": 2.0 }, "tests": [ { "description": "shorter is valid", "data": "f", "valid": true }, { "description": "too long is invalid", "data": "foo", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/maxProperties.json000066400000000000000000000043001477700171100311620ustar00rootroot00000000000000[ { "description": "maxProperties validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "maxProperties": 2 }, "tests": [ { "description": "shorter is valid", "data": {"foo": 1}, "valid": true }, { "description": "exact length is valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "too long is invalid", "data": {"foo": 1, "bar": 2, "baz": 3}, "valid": false }, { "description": "ignores arrays", "data": [1, 2, 3], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "maxProperties validation with a decimal", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "maxProperties": 2.0 }, "tests": [ { "description": "shorter is valid", "data": {"foo": 1}, "valid": true }, { "description": "too long is invalid", "data": {"foo": 1, "bar": 2, "baz": 3}, "valid": false } ] }, { "description": "maxProperties = 0 means the object is empty", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "maxProperties": 0 }, "tests": [ { "description": "no properties is valid", "data": {}, "valid": true }, { "description": "one property is invalid", "data": { "foo": 1 }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/maximum.json000066400000000000000000000031761477700171100300070ustar00rootroot00000000000000[ { "description": "maximum validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "maximum": 3.0 }, "tests": [ { "description": "below the maximum is valid", "data": 2.6, "valid": true }, { "description": "boundary point is valid", "data": 3.0, "valid": true }, { "description": "above the maximum is invalid", "data": 3.5, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] }, { "description": "maximum validation with unsigned integer", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "maximum": 300 }, "tests": [ { "description": "below the maximum is invalid", "data": 299.97, "valid": true }, { "description": "boundary point integer is valid", "data": 300, "valid": true }, { "description": "boundary point float is valid", "data": 300.00, "valid": true }, { "description": "above the maximum is invalid", "data": 300.5, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/minContains.json000066400000000000000000000147141477700171100306140ustar00rootroot00000000000000[ { "description": "minContains without contains is ignored", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "minContains": 1 }, "tests": [ { "description": "one item valid against lone minContains", "data": [ 1 ], "valid": true }, { "description": "zero items still valid against lone minContains", "data": [], "valid": true } ] }, { "description": "minContains=1 with contains", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "contains": {"const": 1}, "minContains": 1 }, "tests": [ { "description": "empty data", "data": [ ], "valid": false }, { "description": "no elements match", "data": [ 2 ], "valid": false }, { "description": "single element matches, valid minContains", "data": [ 1 ], "valid": true }, { "description": "some elements match, valid minContains", "data": [ 1, 2 ], "valid": true }, { "description": "all elements match, valid minContains", "data": [ 1, 1 ], "valid": true } ] }, { "description": "minContains=2 with contains", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "contains": {"const": 1}, "minContains": 2 }, "tests": [ { "description": "empty data", "data": [ ], "valid": false }, { "description": "all elements match, invalid minContains", "data": [ 1 ], "valid": false }, { "description": "some elements match, invalid minContains", "data": [ 1, 2 ], "valid": false }, { "description": "all elements match, valid minContains (exactly as needed)", "data": [ 1, 1 ], "valid": true }, { "description": "all elements match, valid minContains (more than needed)", "data": [ 1, 1, 1 ], "valid": true }, { "description": "some elements match, valid minContains", "data": [ 1, 2, 1 ], "valid": true } ] }, { "description": "minContains=2 with contains with a decimal value", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "contains": {"const": 1}, "minContains": 2.0 }, "tests": [ { "description": "one element matches, invalid minContains", "data": [ 1 ], "valid": false }, { "description": "both elements match, valid minContains", "data": [ 1, 1 ], "valid": true } ] }, { "description": "maxContains = minContains", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "contains": {"const": 1}, "maxContains": 2, "minContains": 2 }, "tests": [ { "description": "empty data", "data": [ ], "valid": false }, { "description": "all elements match, invalid minContains", "data": [ 1 ], "valid": false }, { "description": "all elements match, invalid maxContains", "data": [ 1, 1, 1 ], "valid": false }, { "description": "all elements match, valid maxContains and minContains", "data": [ 1, 1 ], "valid": true } ] }, { "description": "maxContains < minContains", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "contains": {"const": 1}, "maxContains": 1, "minContains": 3 }, "tests": [ { "description": "empty data", "data": [ ], "valid": false }, { "description": "invalid minContains", "data": [ 1 ], "valid": false }, { "description": "invalid maxContains", "data": [ 1, 1, 1 ], "valid": false }, { "description": "invalid maxContains and minContains", "data": [ 1, 1 ], "valid": false } ] }, { "description": "minContains = 0", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "contains": {"const": 1}, "minContains": 0 }, "tests": [ { "description": "empty data", "data": [ ], "valid": true }, { "description": "minContains = 0 makes contains always pass", "data": [ 2 ], "valid": true } ] }, { "description": "minContains = 0 with maxContains", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "contains": {"const": 1}, "minContains": 0, "maxContains": 1 }, "tests": [ { "description": "empty data", "data": [ ], "valid": true }, { "description": "not more than maxContains", "data": [ 1 ], "valid": true }, { "description": "too many", "data": [ 1, 1 ], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/minItems.json000066400000000000000000000024261477700171100301140ustar00rootroot00000000000000[ { "description": "minItems validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "minItems": 1 }, "tests": [ { "description": "longer is valid", "data": [1, 2], "valid": true }, { "description": "exact length is valid", "data": [1], "valid": true }, { "description": "too short is invalid", "data": [], "valid": false }, { "description": "ignores non-arrays", "data": "", "valid": true } ] }, { "description": "minItems validation with a decimal", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "minItems": 1.0 }, "tests": [ { "description": "longer is valid", "data": [1, 2], "valid": true }, { "description": "too short is invalid", "data": [], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/minLength.json000066400000000000000000000027311477700171100302530ustar00rootroot00000000000000[ { "description": "minLength validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "minLength": 2 }, "tests": [ { "description": "longer is valid", "data": "foo", "valid": true }, { "description": "exact length is valid", "data": "fo", "valid": true }, { "description": "too short is invalid", "data": "f", "valid": false }, { "description": "ignores non-strings", "data": 1, "valid": true }, { "description": "one supplementary Unicode code point is not long enough", "data": "\uD83D\uDCA9", "valid": false } ] }, { "description": "minLength validation with a decimal", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "minLength": 2.0 }, "tests": [ { "description": "longer is valid", "data": "foo", "valid": true }, { "description": "too short is invalid", "data": "f", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/minProperties.json000066400000000000000000000031451477700171100311660ustar00rootroot00000000000000[ { "description": "minProperties validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "minProperties": 1 }, "tests": [ { "description": "longer is valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "exact length is valid", "data": {"foo": 1}, "valid": true }, { "description": "too short is invalid", "data": {}, "valid": false }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores strings", "data": "", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "minProperties validation with a decimal", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "minProperties": 1.0 }, "tests": [ { "description": "longer is valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "too short is invalid", "data": {}, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/minimum.json000066400000000000000000000041041477700171100277750ustar00rootroot00000000000000[ { "description": "minimum validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "minimum": 1.1 }, "tests": [ { "description": "above the minimum is valid", "data": 2.6, "valid": true }, { "description": "boundary point is valid", "data": 1.1, "valid": true }, { "description": "below the minimum is invalid", "data": 0.6, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] }, { "description": "minimum validation with signed integer", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "minimum": -2 }, "tests": [ { "description": "negative above the minimum is valid", "data": -1, "valid": true }, { "description": "positive above the minimum is valid", "data": 0, "valid": true }, { "description": "boundary point is valid", "data": -2, "valid": true }, { "description": "boundary point with float is valid", "data": -2.0, "valid": true }, { "description": "float below the minimum is invalid", "data": -2.0001, "valid": false }, { "description": "int below the minimum is invalid", "data": -3, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/multipleOf.json000066400000000000000000000051451477700171100304500ustar00rootroot00000000000000[ { "description": "by int", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "multipleOf": 2 }, "tests": [ { "description": "int by int", "data": 10, "valid": true }, { "description": "int by int fail", "data": 7, "valid": false }, { "description": "ignores non-numbers", "data": "foo", "valid": true } ] }, { "description": "by number", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "multipleOf": 1.5 }, "tests": [ { "description": "zero is multiple of anything", "data": 0, "valid": true }, { "description": "4.5 is multiple of 1.5", "data": 4.5, "valid": true }, { "description": "35 is not multiple of 1.5", "data": 35, "valid": false } ] }, { "description": "by small number", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "multipleOf": 0.0001 }, "tests": [ { "description": "0.0075 is multiple of 0.0001", "data": 0.0075, "valid": true }, { "description": "0.00751 is not multiple of 0.0001", "data": 0.00751, "valid": false } ] }, { "description": "float division = inf", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "integer", "multipleOf": 0.123456789 }, "tests": [ { "description": "always invalid, but naive implementations may raise an overflow error", "data": 1e308, "valid": false } ] }, { "description": "small multiple of large integer", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "integer", "multipleOf": 1e-8 }, "tests": [ { "description": "any integer is a multiple of 1e-8", "data": 12391239123, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/not.json000066400000000000000000000101501477700171100271200ustar00rootroot00000000000000[ { "description": "not", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "not": {"type": "integer"} }, "tests": [ { "description": "allowed", "data": "foo", "valid": true }, { "description": "disallowed", "data": 1, "valid": false } ] }, { "description": "not multiple types", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "not": {"type": ["integer", "boolean"]} }, "tests": [ { "description": "valid", "data": "foo", "valid": true }, { "description": "mismatch", "data": 1, "valid": false }, { "description": "other mismatch", "data": true, "valid": false } ] }, { "description": "not more complex schema", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "not": { "type": "object", "properties": { "foo": { "type": "string" } } } }, "tests": [ { "description": "match", "data": 1, "valid": true }, { "description": "other match", "data": {"foo": 1}, "valid": true }, { "description": "mismatch", "data": {"foo": "bar"}, "valid": false } ] }, { "description": "forbidden property", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "foo": { "not": {} } } }, "tests": [ { "description": "property present", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "property absent", "data": {"bar": 1, "baz": 2}, "valid": true } ] }, { "description": "not with boolean schema true", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "not": true }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "not with boolean schema false", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "not": false }, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "collect annotations inside a 'not', even if collection is disabled", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "not": { "$comment": "this subschema must still produce annotations internally, even though the 'not' will ultimately discard them", "anyOf": [ true, { "properties": { "foo": true } } ], "unevaluatedProperties": false } }, "tests": [ { "description": "unevaluated property", "data": { "bar": 1 }, "valid": true }, { "description": "annotations are still collected inside a 'not'", "data": { "foo": 1 }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/oneOf.json000066400000000000000000000176701477700171100274040ustar00rootroot00000000000000[ { "description": "oneOf", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "oneOf": [ { "type": "integer" }, { "minimum": 2 } ] }, "tests": [ { "description": "first oneOf valid", "data": 1, "valid": true }, { "description": "second oneOf valid", "data": 2.5, "valid": true }, { "description": "both oneOf valid", "data": 3, "valid": false }, { "description": "neither oneOf valid", "data": 1.5, "valid": false } ] }, { "description": "oneOf with base schema", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "string", "oneOf" : [ { "minLength": 2 }, { "maxLength": 4 } ] }, "tests": [ { "description": "mismatch base schema", "data": 3, "valid": false }, { "description": "one oneOf valid", "data": "foobar", "valid": true }, { "description": "both oneOf valid", "data": "foo", "valid": false } ] }, { "description": "oneOf with boolean schemas, all true", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "oneOf": [true, true, true] }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "oneOf with boolean schemas, one true", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "oneOf": [true, false, false] }, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "oneOf with boolean schemas, more than one true", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "oneOf": [true, true, false] }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "oneOf with boolean schemas, all false", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "oneOf": [false, false, false] }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "oneOf complex types", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "oneOf": [ { "properties": { "bar": {"type": "integer"} }, "required": ["bar"] }, { "properties": { "foo": {"type": "string"} }, "required": ["foo"] } ] }, "tests": [ { "description": "first oneOf valid (complex)", "data": {"bar": 2}, "valid": true }, { "description": "second oneOf valid (complex)", "data": {"foo": "baz"}, "valid": true }, { "description": "both oneOf valid (complex)", "data": {"foo": "baz", "bar": 2}, "valid": false }, { "description": "neither oneOf valid (complex)", "data": {"foo": 2, "bar": "quux"}, "valid": false } ] }, { "description": "oneOf with empty schema", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "oneOf": [ { "type": "number" }, {} ] }, "tests": [ { "description": "one valid - valid", "data": "foo", "valid": true }, { "description": "both valid - invalid", "data": 123, "valid": false } ] }, { "description": "oneOf with required", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "oneOf": [ { "required": ["foo", "bar"] }, { "required": ["foo", "baz"] } ] }, "tests": [ { "description": "both invalid - invalid", "data": {"bar": 2}, "valid": false }, { "description": "first valid - valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "second valid - valid", "data": {"foo": 1, "baz": 3}, "valid": true }, { "description": "both valid - invalid", "data": {"foo": 1, "bar": 2, "baz" : 3}, "valid": false } ] }, { "description": "oneOf with missing optional property", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "oneOf": [ { "properties": { "bar": true, "baz": true }, "required": ["bar"] }, { "properties": { "foo": true }, "required": ["foo"] } ] }, "tests": [ { "description": "first oneOf valid", "data": {"bar": 8}, "valid": true }, { "description": "second oneOf valid", "data": {"foo": "foo"}, "valid": true }, { "description": "both oneOf valid", "data": {"foo": "foo", "bar": 8}, "valid": false }, { "description": "neither oneOf valid", "data": {"baz": "quux"}, "valid": false } ] }, { "description": "nested oneOf, to check validation semantics", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "oneOf": [ { "oneOf": [ { "type": "null" } ] } ] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "anything non-null is invalid", "data": 123, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/000077500000000000000000000000001477700171100272555ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/bignum.json000066400000000000000000000065261477700171100314420ustar00rootroot00000000000000[ { "description": "integer", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "integer" }, "tests": [ { "description": "a bignum is an integer", "data": 12345678910111213141516171819202122232425262728293031, "valid": true }, { "description": "a negative bignum is an integer", "data": -12345678910111213141516171819202122232425262728293031, "valid": true } ] }, { "description": "number", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "number" }, "tests": [ { "description": "a bignum is a number", "data": 98249283749234923498293171823948729348710298301928331, "valid": true }, { "description": "a negative bignum is a number", "data": -98249283749234923498293171823948729348710298301928331, "valid": true } ] }, { "description": "string", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "string" }, "tests": [ { "description": "a bignum is not a string", "data": 98249283749234923498293171823948729348710298301928331, "valid": false } ] }, { "description": "maximum integer comparison", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "maximum": 18446744073709551615 }, "tests": [ { "description": "comparison works for high numbers", "data": 18446744073709551600, "valid": true } ] }, { "description": "float comparison with high precision", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "exclusiveMaximum": 972783798187987123879878123.18878137 }, "tests": [ { "description": "comparison works for high numbers", "data": 972783798187987123879878123.188781371, "valid": false } ] }, { "description": "minimum integer comparison", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "minimum": -18446744073709551615 }, "tests": [ { "description": "comparison works for very negative numbers", "data": -18446744073709551600, "valid": true } ] }, { "description": "float comparison with high precision on negative numbers", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "exclusiveMinimum": -972783798187987123879878123.18878137 }, "tests": [ { "description": "comparison works for very negative numbers", "data": -972783798187987123879878123.188781371, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/cross-draft.json000066400000000000000000000011541477700171100324000ustar00rootroot00000000000000[ { "description": "refs to historic drafts are processed as historic drafts", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "array", "$ref": "http://localhost:1234/draft2019-09/ignore-prefixItems.json" }, "tests": [ { "description": "first item not a string is valid", "comment": "if the implementation is not processing the $ref as a 2019-09 schema, this test will fail", "data": [1, 2, 3], "valid": true } ] } ] dependencies-compatibility.json000066400000000000000000000177201477700171100353750ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional[ { "description": "single dependency", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "dependencies": {"bar": ["foo"]} }, "tests": [ { "description": "neither", "data": {}, "valid": true }, { "description": "nondependant", "data": {"foo": 1}, "valid": true }, { "description": "with dependency", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "missing dependency", "data": {"bar": 2}, "valid": false }, { "description": "ignores arrays", "data": ["bar"], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "empty dependents", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "dependencies": {"bar": []} }, "tests": [ { "description": "empty object", "data": {}, "valid": true }, { "description": "object with one property", "data": {"bar": 2}, "valid": true }, { "description": "non-object is valid", "data": 1, "valid": true } ] }, { "description": "multiple dependents required", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "dependencies": {"quux": ["foo", "bar"]} }, "tests": [ { "description": "neither", "data": {}, "valid": true }, { "description": "nondependants", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "with dependencies", "data": {"foo": 1, "bar": 2, "quux": 3}, "valid": true }, { "description": "missing dependency", "data": {"foo": 1, "quux": 2}, "valid": false }, { "description": "missing other dependency", "data": {"bar": 1, "quux": 2}, "valid": false }, { "description": "missing both dependencies", "data": {"quux": 1}, "valid": false } ] }, { "description": "dependencies with escaped characters", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "dependencies": { "foo\nbar": ["foo\rbar"], "foo\"bar": ["foo'bar"] } }, "tests": [ { "description": "CRLF", "data": { "foo\nbar": 1, "foo\rbar": 2 }, "valid": true }, { "description": "quoted quotes", "data": { "foo'bar": 1, "foo\"bar": 2 }, "valid": true }, { "description": "CRLF missing dependent", "data": { "foo\nbar": 1, "foo": 2 }, "valid": false }, { "description": "quoted quotes missing dependent", "data": { "foo\"bar": 2 }, "valid": false } ] }, { "description": "single schema dependency", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "dependencies": { "bar": { "properties": { "foo": {"type": "integer"}, "bar": {"type": "integer"} } } } }, "tests": [ { "description": "valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "no dependency", "data": {"foo": "quux"}, "valid": true }, { "description": "wrong type", "data": {"foo": "quux", "bar": 2}, "valid": false }, { "description": "wrong type other", "data": {"foo": 2, "bar": "quux"}, "valid": false }, { "description": "wrong type both", "data": {"foo": "quux", "bar": "quux"}, "valid": false }, { "description": "ignores arrays", "data": ["bar"], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "boolean subschemas", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "dependencies": { "foo": true, "bar": false } }, "tests": [ { "description": "object with property having schema true is valid", "data": {"foo": 1}, "valid": true }, { "description": "object with property having schema false is invalid", "data": {"bar": 2}, "valid": false }, { "description": "object with both properties is invalid", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "empty object is valid", "data": {}, "valid": true } ] }, { "description": "schema dependencies with escaped characters", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "dependencies": { "foo\tbar": {"minProperties": 4}, "foo'bar": {"required": ["foo\"bar"]} } }, "tests": [ { "description": "quoted tab", "data": { "foo\tbar": 1, "a": 2, "b": 3, "c": 4 }, "valid": true }, { "description": "quoted quote", "data": { "foo'bar": {"foo\"bar": 1} }, "valid": false }, { "description": "quoted tab invalid under dependent schema", "data": { "foo\tbar": 1, "a": 2 }, "valid": false }, { "description": "quoted quote invalid under dependent schema", "data": {"foo'bar": 1}, "valid": false } ] } ] ecmascript-regex.json000066400000000000000000000477461477700171100333550ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional[ { "description": "ECMA 262 regex $ does not match trailing newline", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "string", "pattern": "^abc$" }, "tests": [ { "description": "matches in Python, but not in ECMA 262", "data": "abc\\n", "valid": false }, { "description": "matches", "data": "abc", "valid": true } ] }, { "description": "ECMA 262 regex converts \\t to horizontal tab", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "string", "pattern": "^\\t$" }, "tests": [ { "description": "does not match", "data": "\\t", "valid": false }, { "description": "matches", "data": "\u0009", "valid": true } ] }, { "description": "ECMA 262 regex escapes control codes with \\c and upper letter", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "string", "pattern": "^\\cC$" }, "tests": [ { "description": "does not match", "data": "\\cC", "valid": false }, { "description": "matches", "data": "\u0003", "valid": true } ] }, { "description": "ECMA 262 regex escapes control codes with \\c and lower letter", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "string", "pattern": "^\\cc$" }, "tests": [ { "description": "does not match", "data": "\\cc", "valid": false }, { "description": "matches", "data": "\u0003", "valid": true } ] }, { "description": "ECMA 262 \\d matches ascii digits only", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "string", "pattern": "^\\d$" }, "tests": [ { "description": "ASCII zero matches", "data": "0", "valid": true }, { "description": "NKO DIGIT ZERO does not match (unlike e.g. Python)", "data": "߀", "valid": false }, { "description": "NKO DIGIT ZERO (as \\u escape) does not match", "data": "\u07c0", "valid": false } ] }, { "description": "ECMA 262 \\D matches everything but ascii digits", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "string", "pattern": "^\\D$" }, "tests": [ { "description": "ASCII zero does not match", "data": "0", "valid": false }, { "description": "NKO DIGIT ZERO matches (unlike e.g. Python)", "data": "߀", "valid": true }, { "description": "NKO DIGIT ZERO (as \\u escape) matches", "data": "\u07c0", "valid": true } ] }, { "description": "ECMA 262 \\w matches ascii letters only", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "string", "pattern": "^\\w$" }, "tests": [ { "description": "ASCII 'a' matches", "data": "a", "valid": true }, { "description": "latin-1 e-acute does not match (unlike e.g. Python)", "data": "é", "valid": false } ] }, { "description": "ECMA 262 \\W matches everything but ascii letters", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "string", "pattern": "^\\W$" }, "tests": [ { "description": "ASCII 'a' does not match", "data": "a", "valid": false }, { "description": "latin-1 e-acute matches (unlike e.g. Python)", "data": "é", "valid": true } ] }, { "description": "ECMA 262 \\s matches whitespace", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "string", "pattern": "^\\s$" }, "tests": [ { "description": "ASCII space matches", "data": " ", "valid": true }, { "description": "Character tabulation matches", "data": "\t", "valid": true }, { "description": "Line tabulation matches", "data": "\u000b", "valid": true }, { "description": "Form feed matches", "data": "\u000c", "valid": true }, { "description": "latin-1 non-breaking-space matches", "data": "\u00a0", "valid": true }, { "description": "zero-width whitespace matches", "data": "\ufeff", "valid": true }, { "description": "line feed matches (line terminator)", "data": "\u000a", "valid": true }, { "description": "paragraph separator matches (line terminator)", "data": "\u2029", "valid": true }, { "description": "EM SPACE matches (Space_Separator)", "data": "\u2003", "valid": true }, { "description": "Non-whitespace control does not match", "data": "\u0001", "valid": false }, { "description": "Non-whitespace does not match", "data": "\u2013", "valid": false } ] }, { "description": "ECMA 262 \\S matches everything but whitespace", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "string", "pattern": "^\\S$" }, "tests": [ { "description": "ASCII space does not match", "data": " ", "valid": false }, { "description": "Character tabulation does not match", "data": "\t", "valid": false }, { "description": "Line tabulation does not match", "data": "\u000b", "valid": false }, { "description": "Form feed does not match", "data": "\u000c", "valid": false }, { "description": "latin-1 non-breaking-space does not match", "data": "\u00a0", "valid": false }, { "description": "zero-width whitespace does not match", "data": "\ufeff", "valid": false }, { "description": "line feed does not match (line terminator)", "data": "\u000a", "valid": false }, { "description": "paragraph separator does not match (line terminator)", "data": "\u2029", "valid": false }, { "description": "EM SPACE does not match (Space_Separator)", "data": "\u2003", "valid": false }, { "description": "Non-whitespace control matches", "data": "\u0001", "valid": true }, { "description": "Non-whitespace matches", "data": "\u2013", "valid": true } ] }, { "description": "patterns always use unicode semantics with pattern", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "pattern": "\\p{Letter}cole" }, "tests": [ { "description": "ascii character in json string", "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", "valid": true }, { "description": "literal unicode character in json string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": true }, { "description": "unicode character in hex format in string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": true }, { "description": "unicode matching is case-sensitive", "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", "valid": false } ] }, { "description": "\\w in patterns matches [A-Za-z0-9_], not unicode letters", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "pattern": "\\wcole" }, "tests": [ { "description": "ascii character in json string", "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", "valid": true }, { "description": "literal unicode character in json string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "unicode character in hex format in string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "unicode matching is case-sensitive", "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", "valid": false } ] }, { "description": "pattern with ASCII ranges", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "pattern": "[a-z]cole" }, "tests": [ { "description": "literal unicode character in json string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "unicode character in hex format in string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "ascii characters match", "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", "valid": true } ] }, { "description": "\\d in pattern matches [0-9], not unicode digits", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "pattern": "^\\d+$" }, "tests": [ { "description": "ascii digits", "data": "42", "valid": true }, { "description": "ascii non-digits", "data": "-%#", "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": "৪২", "valid": false } ] }, { "description": "\\a is not an ECMA 262 control escape", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "https://json-schema.org/draft/2020-12/schema" }, "tests": [ { "description": "when used as a pattern", "data": { "pattern": "\\a" }, "valid": false } ] }, { "description": "pattern with non-ASCII digits", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "pattern": "^\\p{digit}+$" }, "tests": [ { "description": "ascii digits", "data": "42", "valid": true }, { "description": "ascii non-digits", "data": "-%#", "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": "৪২", "valid": true } ] }, { "description": "patterns always use unicode semantics with patternProperties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "patternProperties": { "\\p{Letter}cole": true }, "additionalProperties": false }, "tests": [ { "description": "ascii character in json string", "data": { "l'ecole": "pas de vraie vie" }, "valid": true }, { "description": "literal unicode character in json string", "data": { "l'école": "pas de vraie vie" }, "valid": true }, { "description": "unicode character in hex format in string", "data": { "l'\u00e9cole": "pas de vraie vie" }, "valid": true }, { "description": "unicode matching is case-sensitive", "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, "valid": false } ] }, { "description": "\\w in patternProperties matches [A-Za-z0-9_], not unicode letters", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "patternProperties": { "\\wcole": true }, "additionalProperties": false }, "tests": [ { "description": "ascii character in json string", "data": { "l'ecole": "pas de vraie vie" }, "valid": true }, { "description": "literal unicode character in json string", "data": { "l'école": "pas de vraie vie" }, "valid": false }, { "description": "unicode character in hex format in string", "data": { "l'\u00e9cole": "pas de vraie vie" }, "valid": false }, { "description": "unicode matching is case-sensitive", "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, "valid": false } ] }, { "description": "patternProperties with ASCII ranges", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "patternProperties": { "[a-z]cole": true }, "additionalProperties": false }, "tests": [ { "description": "literal unicode character in json string", "data": { "l'école": "pas de vraie vie" }, "valid": false }, { "description": "unicode character in hex format in string", "data": { "l'\u00e9cole": "pas de vraie vie" }, "valid": false }, { "description": "ascii characters match", "data": { "l'ecole": "pas de vraie vie" }, "valid": true } ] }, { "description": "\\d in patternProperties matches [0-9], not unicode digits", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "patternProperties": { "^\\d+$": true }, "additionalProperties": false }, "tests": [ { "description": "ascii digits", "data": { "42": "life, the universe, and everything" }, "valid": true }, { "description": "ascii non-digits", "data": { "-%#": "spending the year dead for tax reasons" }, "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": { "৪২": "khajit has wares if you have coin" }, "valid": false } ] }, { "description": "patternProperties with non-ASCII digits", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "patternProperties": { "^\\p{digit}+$": true }, "additionalProperties": false }, "tests": [ { "description": "ascii digits", "data": { "42": "life, the universe, and everything" }, "valid": true }, { "description": "ascii non-digits", "data": { "-%#": "spending the year dead for tax reasons" }, "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": { "৪২": "khajit has wares if you have coin" }, "valid": true } ] } ] float-overflow.json000066400000000000000000000007221477700171100330400ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional[ { "description": "all integers are multiples of 0.5, if overflow is handled", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "integer", "multipleOf": 0.5 }, "tests": [ { "description": "valid if optional overflow handling is implemented", "data": 1e308, "valid": true } ] } ] format-assertion.json000066400000000000000000000025341477700171100333720ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional[ { "description": "schema that uses custom metaschema with format-assertion: false", "schema": { "$id": "https://schema/using/format-assertion/false", "$schema": "http://localhost:1234/draft2020-12/format-assertion-false.json", "format": "ipv4" }, "tests": [ { "description": "format-assertion: false: valid string", "data": "127.0.0.1", "valid": true }, { "description": "format-assertion: false: invalid string", "data": "not-an-ipv4", "valid": false } ] }, { "description": "schema that uses custom metaschema with format-assertion: true", "schema": { "$id": "https://schema/using/format-assertion/true", "$schema": "http://localhost:1234/draft2020-12/format-assertion-true.json", "format": "ipv4" }, "tests": [ { "description": "format-assertion: true: valid string", "data": "127.0.0.1", "valid": true }, { "description": "format-assertion: true: invalid string", "data": "not-an-ipv4", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/000077500000000000000000000000001477700171100305455ustar00rootroot00000000000000date-time.json000066400000000000000000000112131477700171100332300ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format[ { "description": "validation of date-time strings", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "date-time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid date-time string", "data": "1963-06-19T08:30:06.283185Z", "valid": true }, { "description": "a valid date-time string without second fraction", "data": "1963-06-19T08:30:06Z", "valid": true }, { "description": "a valid date-time string with plus offset", "data": "1937-01-01T12:00:27.87+00:20", "valid": true }, { "description": "a valid date-time string with minus offset", "data": "1990-12-31T15:59:50.123-08:00", "valid": true }, { "description": "a valid date-time with a leap second, UTC", "data": "1998-12-31T23:59:60Z", "valid": true }, { "description": "a valid date-time with a leap second, with minus offset", "data": "1998-12-31T15:59:60.123-08:00", "valid": true }, { "description": "an invalid date-time past leap second, UTC", "data": "1998-12-31T23:59:61Z", "valid": false }, { "description": "an invalid date-time with leap second on a wrong minute, UTC", "data": "1998-12-31T23:58:60Z", "valid": false }, { "description": "an invalid date-time with leap second on a wrong hour, UTC", "data": "1998-12-31T22:59:60Z", "valid": false }, { "description": "an invalid day in date-time string", "data": "1990-02-31T15:59:59.123-08:00", "valid": false }, { "description": "an invalid offset in date-time string", "data": "1990-12-31T15:59:59-24:00", "valid": false }, { "description": "an invalid closing Z after time-zone offset", "data": "1963-06-19T08:30:06.28123+01:00Z", "valid": false }, { "description": "an invalid date-time string", "data": "06/19/1963 08:30:06 PST", "valid": false }, { "description": "case-insensitive T and Z", "data": "1963-06-19t08:30:06.283185z", "valid": true }, { "description": "only RFC3339 not all of ISO 8601 are valid", "data": "2013-350T01:01:01", "valid": false }, { "description": "invalid non-padded month dates", "data": "1963-6-19T08:30:06.283185Z", "valid": false }, { "description": "invalid non-padded day dates", "data": "1963-06-1T08:30:06.283185Z", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4) in date portion", "data": "1963-06-1৪T00:00:00Z", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4) in time portion", "data": "1963-06-11T0৪:00:00Z", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/date.json000066400000000000000000000202051477700171100323540ustar00rootroot00000000000000[ { "description": "validation of date strings", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "date" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid date string", "data": "1963-06-19", "valid": true }, { "description": "a valid date string with 31 days in January", "data": "2020-01-31", "valid": true }, { "description": "a invalid date string with 32 days in January", "data": "2020-01-32", "valid": false }, { "description": "a valid date string with 28 days in February (normal)", "data": "2021-02-28", "valid": true }, { "description": "a invalid date string with 29 days in February (normal)", "data": "2021-02-29", "valid": false }, { "description": "a valid date string with 29 days in February (leap)", "data": "2020-02-29", "valid": true }, { "description": "a invalid date string with 30 days in February (leap)", "data": "2020-02-30", "valid": false }, { "description": "a valid date string with 31 days in March", "data": "2020-03-31", "valid": true }, { "description": "a invalid date string with 32 days in March", "data": "2020-03-32", "valid": false }, { "description": "a valid date string with 30 days in April", "data": "2020-04-30", "valid": true }, { "description": "a invalid date string with 31 days in April", "data": "2020-04-31", "valid": false }, { "description": "a valid date string with 31 days in May", "data": "2020-05-31", "valid": true }, { "description": "a invalid date string with 32 days in May", "data": "2020-05-32", "valid": false }, { "description": "a valid date string with 30 days in June", "data": "2020-06-30", "valid": true }, { "description": "a invalid date string with 31 days in June", "data": "2020-06-31", "valid": false }, { "description": "a valid date string with 31 days in July", "data": "2020-07-31", "valid": true }, { "description": "a invalid date string with 32 days in July", "data": "2020-07-32", "valid": false }, { "description": "a valid date string with 31 days in August", "data": "2020-08-31", "valid": true }, { "description": "a invalid date string with 32 days in August", "data": "2020-08-32", "valid": false }, { "description": "a valid date string with 30 days in September", "data": "2020-09-30", "valid": true }, { "description": "a invalid date string with 31 days in September", "data": "2020-09-31", "valid": false }, { "description": "a valid date string with 31 days in October", "data": "2020-10-31", "valid": true }, { "description": "a invalid date string with 32 days in October", "data": "2020-10-32", "valid": false }, { "description": "a valid date string with 30 days in November", "data": "2020-11-30", "valid": true }, { "description": "a invalid date string with 31 days in November", "data": "2020-11-31", "valid": false }, { "description": "a valid date string with 31 days in December", "data": "2020-12-31", "valid": true }, { "description": "a invalid date string with 32 days in December", "data": "2020-12-32", "valid": false }, { "description": "a invalid date string with invalid month", "data": "2020-13-01", "valid": false }, { "description": "an invalid date string", "data": "06/19/1963", "valid": false }, { "description": "only RFC3339 not all of ISO 8601 are valid", "data": "2013-350", "valid": false }, { "description": "non-padded month dates are not valid", "data": "1998-1-20", "valid": false }, { "description": "non-padded day dates are not valid", "data": "1998-01-1", "valid": false }, { "description": "invalid month", "data": "1998-13-01", "valid": false }, { "description": "invalid month-day combination", "data": "1998-04-31", "valid": false }, { "description": "2021 is not a leap year", "data": "2021-02-29", "valid": false }, { "description": "2020 is a leap year", "data": "2020-02-29", "valid": true }, { "description": "invalid non-ASCII '৪' (a Bengali 4)", "data": "1963-06-1৪", "valid": false }, { "description": "ISO8601 / non-RFC3339: YYYYMMDD without dashes (2023-03-28)", "data": "20230328", "valid": false }, { "description": "ISO8601 / non-RFC3339: week number implicit day of week (2023-01-02)", "data": "2023-W01", "valid": false }, { "description": "ISO8601 / non-RFC3339: week number with day of week (2023-03-28)", "data": "2023-W13-2", "valid": false }, { "description": "ISO8601 / non-RFC3339: week number rollover to next year (2023-01-01)", "data": "2022W527", "valid": false } ] } ] duration.json000066400000000000000000000077201477700171100332140ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format[ { "description": "validation of duration strings", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "duration" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid duration string", "data": "P4DT12H30M5S", "valid": true }, { "description": "an invalid duration string", "data": "PT1D", "valid": false }, { "description": "no elements present", "data": "P", "valid": false }, { "description": "no time elements present", "data": "P1YT", "valid": false }, { "description": "no date or time elements present", "data": "PT", "valid": false }, { "description": "elements out of order", "data": "P2D1Y", "valid": false }, { "description": "missing time separator", "data": "P1D2H", "valid": false }, { "description": "time element in the date position", "data": "P2S", "valid": false }, { "description": "four years duration", "data": "P4Y", "valid": true }, { "description": "zero time, in seconds", "data": "PT0S", "valid": true }, { "description": "zero time, in days", "data": "P0D", "valid": true }, { "description": "one month duration", "data": "P1M", "valid": true }, { "description": "one minute duration", "data": "PT1M", "valid": true }, { "description": "one and a half days, in hours", "data": "PT36H", "valid": true }, { "description": "one and a half days, in days and hours", "data": "P1DT12H", "valid": true }, { "description": "two weeks", "data": "P2W", "valid": true }, { "description": "weeks cannot be combined with other units", "data": "P1Y2W", "valid": false }, { "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "P২Y", "valid": false }, { "description": "element without unit", "data": "P1", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/email.json000066400000000000000000000077301477700171100325360ustar00rootroot00000000000000[ { "description": "validation of e-mail addresses", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "email" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid e-mail address", "data": "joe.bloggs@example.com", "valid": true }, { "description": "an invalid e-mail address", "data": "2962", "valid": false }, { "description": "tilde in local part is valid", "data": "te~st@example.com", "valid": true }, { "description": "tilde before local part is valid", "data": "~test@example.com", "valid": true }, { "description": "tilde after local part is valid", "data": "test~@example.com", "valid": true }, { "description": "a quoted string with a space in the local part is valid", "data": "\"joe bloggs\"@example.com", "valid": true }, { "description": "a quoted string with a double dot in the local part is valid", "data": "\"joe..bloggs\"@example.com", "valid": true }, { "description": "a quoted string with a @ in the local part is valid", "data": "\"joe@bloggs\"@example.com", "valid": true }, { "description": "an IPv4-address-literal after the @ is valid", "data": "joe.bloggs@[127.0.0.1]", "valid": true }, { "description": "an IPv6-address-literal after the @ is valid", "data": "joe.bloggs@[IPv6:::1]", "valid": true }, { "description": "dot before local part is not valid", "data": ".test@example.com", "valid": false }, { "description": "dot after local part is not valid", "data": "test.@example.com", "valid": false }, { "description": "two separated dots inside local part are valid", "data": "te.s.t@example.com", "valid": true }, { "description": "two subsequent dots inside local part are not valid", "data": "te..st@example.com", "valid": false }, { "description": "an invalid domain", "data": "joe.bloggs@invalid=domain.com", "valid": false }/*, { "description": "an invalid IPv4-address-literal", "data": "joe.bloggs@[127.0.0.300]", "valid": false }*/ ] } ] hostname.json000066400000000000000000000077611477700171100332120ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format[ { "description": "validation of host names", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "hostname" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid host name", "data": "www.example.com", "valid": true }, { "description": "a valid punycoded IDN hostname", "data": "xn--4gbwdl.xn--wgbh1c", "valid": true }, { "description": "a host name starting with an illegal character", "data": "-a-host-name-that-starts-with--", "valid": false }, { "description": "a host name containing illegal characters", "data": "not_a_valid_host_name", "valid": false }, { "description": "a host name with a component too long", "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", "valid": false }, { "description": "starts with hyphen", "data": "-hostname", "valid": false }, { "description": "ends with hyphen", "data": "hostname-", "valid": false }, { "description": "starts with underscore", "data": "_hostname", "valid": false }, { "description": "ends with underscore", "data": "hostname_", "valid": false }, { "description": "contains underscore", "data": "host_name", "valid": false }, { "description": "maximum label length", "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.com", "valid": true }, { "description": "exceeds maximum label length", "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl.com", "valid": false }, { "description": "single label", "data": "hostname", "valid": true }, { "description": "single label with hyphen", "data": "host-name", "valid": true }, { "description": "single label with digits", "data": "h0stn4me", "valid": true }, { "description": "single label starting with digit", "data": "1host", "valid": true }, { "description": "single label ending with digit", "data": "hostnam3", "valid": true } ] } ] idn-email.json000066400000000000000000000035071477700171100332250ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format[ { "description": "validation of an internationalized e-mail addresses", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "idn-email" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid idn e-mail (example@example.test in Hangul)", "data": "실례@실례.테스트", "valid": true }, { "description": "an invalid idn e-mail address", "data": "2962", "valid": false }, { "description": "a valid e-mail address", "data": "joe.bloggs@example.com", "valid": true }, { "description": "an invalid e-mail address", "data": "2962", "valid": false } ] } ] idn-hostname.json000066400000000000000000000363761477700171100337660ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format[ { "description": "validation of internationalized host names", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "idn-hostname" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid host name (example.test in Hangul)", "data": "실례.테스트", "valid": true }, { "description": "illegal first char U+302E Hangul single dot tone mark", "data": "〮실례.테스트", "valid": false }, { "description": "contains illegal char U+302E Hangul single dot tone mark", "data": "실〮례.테스트", "valid": false }, { "description": "a host name with a component too long", "data": "실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실례례테스트례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례테스트례례실례.테스트", "valid": false }, { "description": "invalid label, correct Punycode", "comment": "https://tools.ietf.org/html/rfc5890#section-2.3.2.1 https://tools.ietf.org/html/rfc5891#section-4.4 https://tools.ietf.org/html/rfc3492#section-7.1", "data": "-> $1.00 <--", "valid": false }, { "description": "valid Chinese Punycode", "comment": "https://tools.ietf.org/html/rfc5890#section-2.3.2.1 https://tools.ietf.org/html/rfc5891#section-4.4", "data": "xn--ihqwcrb4cv8a8dqg056pqjye", "valid": true }, { "description": "invalid Punycode", "comment": "https://tools.ietf.org/html/rfc5891#section-4.4 https://tools.ietf.org/html/rfc5890#section-2.3.2.1", "data": "xn--X", "valid": false }, { "description": "U-label contains \"--\" in the 3rd and 4th position", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1 https://tools.ietf.org/html/rfc5890#section-2.3.2.1", "data": "XN--aa---o47jg78q", "valid": false }, { "description": "U-label starts with a dash", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", "data": "-hello", "valid": false }, { "description": "U-label ends with a dash", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", "data": "hello-", "valid": false }, { "description": "U-label starts and ends with a dash", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", "data": "-hello-", "valid": false }, { "description": "Begins with a Spacing Combining Mark", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", "data": "\u0903hello", "valid": false }, { "description": "Begins with a Nonspacing Mark", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", "data": "\u0300hello", "valid": false }, { "description": "Begins with an Enclosing Mark", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", "data": "\u0488hello", "valid": false }, { "description": "Exceptions that are PVALID, left-to-right chars", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", "data": "\u00df\u03c2\u0f0b\u3007", "valid": true }, { "description": "Exceptions that are PVALID, right-to-left chars", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", "data": "\u06fd\u06fe", "valid": true }, { "description": "Exceptions that are DISALLOWED, right-to-left chars", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", "data": "\u0640\u07fa", "valid": false }, { "description": "Exceptions that are DISALLOWED, left-to-right chars", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6 Note: The two combining marks (U+302E and U+302F) are in the middle and not at the start", "data": "\u3031\u3032\u3033\u3034\u3035\u302e\u302f\u303b", "valid": false }, { "description": "MIDDLE DOT with no preceding 'l'", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", "data": "a\u00b7l", "valid": false }, { "description": "MIDDLE DOT with nothing preceding", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", "data": "\u00b7l", "valid": false }, { "description": "MIDDLE DOT with no following 'l'", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", "data": "l\u00b7a", "valid": false }, { "description": "MIDDLE DOT with nothing following", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", "data": "l\u00b7", "valid": false }, { "description": "MIDDLE DOT with surrounding 'l's", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", "data": "l\u00b7l", "valid": true }, { "description": "Greek KERAIA not followed by Greek", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", "data": "\u03b1\u0375S", "valid": false }, { "description": "Greek KERAIA not followed by anything", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", "data": "\u03b1\u0375", "valid": false }, { "description": "Greek KERAIA followed by Greek", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", "data": "\u03b1\u0375\u03b2", "valid": true }, { "description": "Hebrew GERESH not preceded by Hebrew", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", "data": "A\u05f3\u05d1", "valid": false }, { "description": "Hebrew GERESH not preceded by anything", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", "data": "\u05f3\u05d1", "valid": false }, { "description": "Hebrew GERESH preceded by Hebrew", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", "data": "\u05d0\u05f3\u05d1", "valid": true }, { "description": "Hebrew GERSHAYIM not preceded by Hebrew", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", "data": "A\u05f4\u05d1", "valid": false }, { "description": "Hebrew GERSHAYIM not preceded by anything", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", "data": "\u05f4\u05d1", "valid": false }, { "description": "Hebrew GERSHAYIM preceded by Hebrew", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", "data": "\u05d0\u05f4\u05d1", "valid": true }, { "description": "KATAKANA MIDDLE DOT with no Hiragana, Katakana, or Han", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", "data": "def\u30fbabc", "valid": false }, { "description": "KATAKANA MIDDLE DOT with no other characters", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", "data": "\u30fb", "valid": false }, { "description": "KATAKANA MIDDLE DOT with Hiragana", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", "data": "\u30fb\u3041", "valid": true }, { "description": "KATAKANA MIDDLE DOT with Katakana", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", "data": "\u30fb\u30a1", "valid": true }, { "description": "KATAKANA MIDDLE DOT with Han", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", "data": "\u30fb\u4e08", "valid": true }, { "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", "data": "\u0660\u06f0", "valid": false }, { "description": "Arabic-Indic digits not mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", "data": "\u0628\u0660\u0628", "valid": true }, { "description": "Extended Arabic-Indic digits not mixed with Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.9", "data": "\u06f00", "valid": true }, { "description": "ZERO WIDTH JOINER not preceded by Virama", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", "data": "\u0915\u200d\u0937", "valid": false }, { "description": "ZERO WIDTH JOINER not preceded by anything", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", "data": "\u200d\u0937", "valid": false }, { "description": "ZERO WIDTH JOINER preceded by Virama", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", "data": "\u0915\u094d\u200d\u0937", "valid": true }, { "description": "ZERO WIDTH NON-JOINER preceded by Virama", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1", "data": "\u0915\u094d\u200c\u0937", "valid": true }, { "description": "ZERO WIDTH NON-JOINER not preceded by Virama but matches regexp", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1 https://www.w3.org/TR/alreq/#h_disjoining_enforcement", "data": "\u0628\u064a\u200c\u0628\u064a", "valid": true }, { "description": "single label", "data": "hostname", "valid": true }, { "description": "single label with hyphen", "data": "host-name", "valid": true }, { "description": "single label with digits", "data": "h0stn4me", "valid": true }, { "description": "single label starting with digit", "data": "1host", "valid": true }, { "description": "single label ending with digit", "data": "hostnam3", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/ipv4.json000066400000000000000000000060151477700171100323240ustar00rootroot00000000000000[ { "description": "validation of IP addresses", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "ipv4" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid IP address", "data": "192.168.0.1", "valid": true }, { "description": "an IP address with too many components", "data": "127.0.0.0.1", "valid": false }, { "description": "an IP address with out-of-range values", "data": "256.256.256.256", "valid": false }, { "description": "an IP address without 4 components", "data": "127.0", "valid": false }, { "description": "an IP address as an integer", "data": "0x7f000001", "valid": false }, { "description": "an IP address as an integer (decimal)", "data": "2130706433", "valid": false }, { "description": "invalid leading zeroes, as they are treated as octals", "comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/", "data": "087.10.0.1", "valid": false }, { "description": "value without leading zero is valid", "data": "87.10.0.1", "valid": true }, { "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২7.0.0.1", "valid": false }, { "description": "netmask is not a part of ipv4 address", "data": "192.168.1.0/24", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/ipv6.json000066400000000000000000000155721477700171100323360ustar00rootroot00000000000000[ { "description": "validation of IPv6 addresses", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "ipv6" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid IPv6 address", "data": "::1", "valid": true }, { "description": "an IPv6 address with out-of-range values", "data": "12345::", "valid": false }, { "description": "trailing 4 hex symbols is valid", "data": "::abef", "valid": true }, { "description": "trailing 5 hex symbols is invalid", "data": "::abcef", "valid": false }, { "description": "an IPv6 address with too many components", "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", "valid": false }, { "description": "an IPv6 address containing illegal characters", "data": "::laptop", "valid": false }, { "description": "no digits is valid", "data": "::", "valid": true }, { "description": "leading colons is valid", "data": "::42:ff:1", "valid": true }, { "description": "trailing colons is valid", "data": "d6::", "valid": true }, { "description": "missing leading octet is invalid", "data": ":2:3:4:5:6:7:8", "valid": false }, { "description": "missing trailing octet is invalid", "data": "1:2:3:4:5:6:7:", "valid": false }, { "description": "missing leading octet with omitted octets later", "data": ":2:3:4::8", "valid": false }, { "description": "single set of double colons in the middle is valid", "data": "1:d6::42", "valid": true }, { "description": "two sets of double colons is invalid", "data": "1::d6::42", "valid": false }, { "description": "mixed format with the ipv4 section as decimal octets", "data": "1::d6:192.168.0.1", "valid": true }, { "description": "mixed format with double colons between the sections", "data": "1:2::192.168.0.1", "valid": true }, { "description": "mixed format with ipv4 section with octet out of range", "data": "1::2:192.168.256.1", "valid": false }, { "description": "mixed format with ipv4 section with a hex octet", "data": "1::2:192.168.ff.1", "valid": false }, { "description": "mixed format with leading double colons (ipv4-mapped ipv6 address)", "data": "::ffff:192.168.0.1", "valid": true }, { "description": "triple colons is invalid", "data": "1:2:3:4:5:::8", "valid": false }, { "description": "8 octets", "data": "1:2:3:4:5:6:7:8", "valid": true }, { "description": "insufficient octets without double colons", "data": "1:2:3:4:5:6:7", "valid": false }, { "description": "no colons is invalid", "data": "1", "valid": false }, { "description": "ipv4 is not ipv6", "data": "127.0.0.1", "valid": false }, { "description": "ipv4 segment must have 4 octets", "data": "1:2:3:4:1.2.3", "valid": false }, { "description": "leading whitespace is invalid", "data": " ::1", "valid": false }, { "description": "trailing whitespace is invalid", "data": "::1 ", "valid": false }, { "description": "netmask is not a part of ipv6 address", "data": "fe80::/64", "valid": false }, { "description": "zone id is not a part of ipv6 address", "data": "fe80::a%eth1", "valid": false }, { "description": "a long valid ipv6", "data": "1000:1000:1000:1000:1000:1000:255.255.255.255", "valid": true }, { "description": "a long invalid ipv6, below length limit, first", "data": "100:100:100:100:100:100:255.255.255.255.255", "valid": false }, { "description": "a long invalid ipv6, below length limit, second", "data": "100:100:100:100:100:100:100:255.255.255.255", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4)", "data": "1:2:3:4:5:6:7:৪", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4) in the IPv4 portion", "data": "1:2::192.16৪.0.1", "valid": false } ] } ] iri-reference.json000066400000000000000000000044451477700171100341070ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format[ { "description": "validation of IRI References", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "iri-reference" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid IRI", "data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx", "valid": true }, { "description": "a valid protocol-relative IRI Reference", "data": "//ƒøø.ßår/?∂éœ=πîx#πîüx", "valid": true }, { "description": "a valid relative IRI Reference", "data": "/âππ", "valid": true }, { "description": "an invalid IRI Reference", "data": "\\\\WINDOWS\\filëßåré", "valid": false }, { "description": "a valid IRI Reference", "data": "âππ", "valid": true }, { "description": "a valid IRI fragment", "data": "#ƒrägmênt", "valid": true }, { "description": "an invalid IRI fragment", "data": "#ƒräg\\mênt", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/iri.json000066400000000000000000000054571477700171100322360ustar00rootroot00000000000000[ { "description": "validation of IRIs", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "iri" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid IRI with anchor tag", "data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx", "valid": true }, { "description": "a valid IRI with anchor tag and parentheses", "data": "http://ƒøø.com/blah_(wîkïpédiå)_blah#ßité-1", "valid": true }, { "description": "a valid IRI with URL-encoded stuff", "data": "http://ƒøø.ßår/?q=Test%20URL-encoded%20stuff", "valid": true }, { "description": "a valid IRI with many special characters", "data": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", "valid": true }, { "description": "a valid IRI based on IPv6", "data": "http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]", "valid": true }, { "description": "an invalid IRI based on IPv6", "data": "http://2001:0db8:85a3:0000:0000:8a2e:0370:7334", "valid": false }, { "description": "an invalid relative IRI Reference", "data": "/abc", "valid": false }, { "description": "an invalid IRI", "data": "\\\\WINDOWS\\filëßåré", "valid": false }, { "description": "an invalid IRI though valid IRI reference", "data": "âππ", "valid": false } ] } ] json-pointer.json000066400000000000000000000152161477700171100340150ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format[ { "description": "validation of JSON-pointers (JSON String Representation)", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "json-pointer" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid JSON-pointer", "data": "/foo/bar~0/baz~1/%a", "valid": true }, { "description": "not a valid JSON-pointer (~ not escaped)", "data": "/foo/bar~", "valid": false }, { "description": "valid JSON-pointer with empty segment", "data": "/foo//bar", "valid": true }, { "description": "valid JSON-pointer with the last empty segment", "data": "/foo/bar/", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #1", "data": "", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #2", "data": "/foo", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #3", "data": "/foo/0", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #4", "data": "/", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #5", "data": "/a~1b", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #6", "data": "/c%d", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #7", "data": "/e^f", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #8", "data": "/g|h", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #9", "data": "/i\\j", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #10", "data": "/k\"l", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #11", "data": "/ ", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #12", "data": "/m~0n", "valid": true }, { "description": "valid JSON-pointer used adding to the last array position", "data": "/foo/-", "valid": true }, { "description": "valid JSON-pointer (- used as object member name)", "data": "/foo/-/bar", "valid": true }, { "description": "valid JSON-pointer (multiple escaped characters)", "data": "/~1~0~0~1~1", "valid": true }, { "description": "valid JSON-pointer (escaped with fraction part) #1", "data": "/~1.1", "valid": true }, { "description": "valid JSON-pointer (escaped with fraction part) #2", "data": "/~0.1", "valid": true }, { "description": "not a valid JSON-pointer (URI Fragment Identifier) #1", "data": "#", "valid": false }, { "description": "not a valid JSON-pointer (URI Fragment Identifier) #2", "data": "#/", "valid": false }, { "description": "not a valid JSON-pointer (URI Fragment Identifier) #3", "data": "#a", "valid": false }, { "description": "not a valid JSON-pointer (some escaped, but not all) #1", "data": "/~0~", "valid": false }, { "description": "not a valid JSON-pointer (some escaped, but not all) #2", "data": "/~0/~", "valid": false }, { "description": "not a valid JSON-pointer (wrong escape character) #1", "data": "/~2", "valid": false }, { "description": "not a valid JSON-pointer (wrong escape character) #2", "data": "/~-1", "valid": false }, { "description": "not a valid JSON-pointer (multiple characters not escaped)", "data": "/~~", "valid": false }, { "description": "not a valid JSON-pointer (isn't empty nor starts with /) #1", "data": "a", "valid": false }, { "description": "not a valid JSON-pointer (isn't empty nor starts with /) #2", "data": "0", "valid": false }, { "description": "not a valid JSON-pointer (isn't empty nor starts with /) #3", "data": "a/a", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/regex.json000066400000000000000000000027511477700171100325570ustar00rootroot00000000000000[ { "description": "validation of regular expressions", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "regex" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid regular expression", "data": "([abc])+\\s+$", "valid": true }, { "description": "a regular expression with unclosed parens is invalid", "data": "^(abc]", "valid": false } ] } ] relative-json-pointer.json000066400000000000000000000060761477700171100356320ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format[ { "description": "validation of Relative JSON Pointers (RJP)", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "relative-json-pointer" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid upwards RJP", "data": "1", "valid": true }, { "description": "a valid downwards RJP", "data": "0/foo/bar", "valid": true }, { "description": "a valid up and then down RJP, with array index", "data": "2/0/baz/1/zip", "valid": true }, { "description": "a valid RJP taking the member or index name", "data": "0#", "valid": true }, { "description": "an invalid RJP that is a valid JSON Pointer", "data": "/foo/bar", "valid": false }, { "description": "negative prefix", "data": "-1/foo/bar", "valid": false }, { "description": "explicit positive prefix", "data": "+1/foo/bar", "valid": false }, { "description": "## is not a valid json-pointer", "data": "0##", "valid": false }, { "description": "zero cannot be followed by other digits, plus json-pointer", "data": "01/a", "valid": false }, { "description": "zero cannot be followed by other digits, plus octothorpe", "data": "01#", "valid": false }, { "description": "empty string", "data": "", "valid": false }, { "description": "multi-digit integer prefix", "data": "120/foo/bar", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/time.json000066400000000000000000000176401477700171100324060ustar00rootroot00000000000000[ { "description": "validation of time strings", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid time string", "data": "08:30:06Z", "valid": true }, { "description": "invalid time string with extra leading zeros", "data": "008:030:006Z", "valid": false }, { "description": "invalid time string with no leading zero for single digit", "data": "8:3:6Z", "valid": false }, { "description": "hour, minute, second must be two digits", "data": "8:0030:6Z", "valid": false }, { "description": "a valid time string with leap second, Zulu", "data": "23:59:60Z", "valid": true }, { "description": "invalid leap second, Zulu (wrong hour)", "data": "22:59:60Z", "valid": false }, { "description": "invalid leap second, Zulu (wrong minute)", "data": "23:58:60Z", "valid": false }, { "description": "valid leap second, zero time-offset", "data": "23:59:60+00:00", "valid": true }, { "description": "invalid leap second, zero time-offset (wrong hour)", "data": "22:59:60+00:00", "valid": false }, { "description": "invalid leap second, zero time-offset (wrong minute)", "data": "23:58:60+00:00", "valid": false }, { "description": "valid leap second, positive time-offset", "data": "01:29:60+01:30", "valid": true }, { "description": "valid leap second, large positive time-offset", "data": "23:29:60+23:30", "valid": true }, { "description": "invalid leap second, positive time-offset (wrong hour)", "data": "23:59:60+01:00", "valid": false }, { "description": "invalid leap second, positive time-offset (wrong minute)", "data": "23:59:60+00:30", "valid": false }, { "description": "valid leap second, negative time-offset", "data": "15:59:60-08:00", "valid": true }, { "description": "valid leap second, large negative time-offset", "data": "00:29:60-23:30", "valid": true }, { "description": "invalid leap second, negative time-offset (wrong hour)", "data": "23:59:60-01:00", "valid": false }, { "description": "invalid leap second, negative time-offset (wrong minute)", "data": "23:59:60-00:30", "valid": false }, { "description": "a valid time string with second fraction", "data": "23:20:50.52Z", "valid": true }, { "description": "a valid time string with precise second fraction", "data": "08:30:06.283185Z", "valid": true }, { "description": "a valid time string with plus offset", "data": "08:30:06+00:20", "valid": true }, { "description": "a valid time string with minus offset", "data": "08:30:06-08:00", "valid": true }, { "description": "hour, minute in time-offset must be two digits", "data": "08:30:06-8:000", "valid": false }, { "description": "a valid time string with case-insensitive Z", "data": "08:30:06z", "valid": true }, { "description": "an invalid time string with invalid hour", "data": "24:00:00Z", "valid": false }, { "description": "an invalid time string with invalid minute", "data": "00:60:00Z", "valid": false }, { "description": "an invalid time string with invalid second", "data": "00:00:61Z", "valid": false }, { "description": "an invalid time string with invalid leap second (wrong hour)", "data": "22:59:60Z", "valid": false }, { "description": "an invalid time string with invalid leap second (wrong minute)", "data": "23:58:60Z", "valid": false }, { "description": "an invalid time string with invalid time numoffset hour", "data": "01:02:03+24:00", "valid": false }, { "description": "an invalid time string with invalid time numoffset minute", "data": "01:02:03+00:60", "valid": false }, { "description": "an invalid time string with invalid time with both Z and numoffset", "data": "01:02:03Z+00:30", "valid": false }, { "description": "an invalid offset indicator", "data": "08:30:06 PST", "valid": false }, { "description": "only RFC3339 not all of ISO 8601 are valid", "data": "01:01:01,1111", "valid": false }, { "description": "no time offset", "data": "12:00:00", "valid": false }, { "description": "no time offset with second fraction", "data": "12:00:00.52", "valid": false }, { "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২:00:00Z", "valid": false }, { "description": "offset not starting with plus or minus", "data": "08:30:06#00:20", "valid": false }, { "description": "contains letters", "data": "ab:cd:ef", "valid": false } ] } ] unknown.json000066400000000000000000000024161477700171100330630ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format[ { "description": "unknown format", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "unknown" }, "tests": [ { "description": "unknown formats ignore integers", "data": 12, "valid": true }, { "description": "unknown formats ignore floats", "data": 13.7, "valid": true }, { "description": "unknown formats ignore objects", "data": {}, "valid": true }, { "description": "unknown formats ignore arrays", "data": [], "valid": true }, { "description": "unknown formats ignore booleans", "data": false, "valid": true }, { "description": "unknown formats ignore nulls", "data": null, "valid": true }, { "description": "unknown formats ignore strings", "data": "string", "valid": true } ] } ] uri-reference.json000066400000000000000000000043721477700171100341220ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format[ { "description": "validation of URI References", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "uri-reference" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid URI", "data": "http://foo.bar/?baz=qux#quux", "valid": true }, { "description": "a valid protocol-relative URI Reference", "data": "//foo.bar/?baz=qux#quux", "valid": true }, { "description": "a valid relative URI Reference", "data": "/abc", "valid": true }, { "description": "an invalid URI Reference", "data": "\\\\WINDOWS\\fileshare", "valid": false }, { "description": "a valid URI Reference", "data": "abc", "valid": true }, { "description": "a valid URI fragment", "data": "#fragment", "valid": true }, { "description": "an invalid URI fragment", "data": "#frag\\ment", "valid": false } ] } ] uri-template.json000066400000000000000000000035641477700171100340010ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format[ { "description": "format: uri-template", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "uri-template" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid uri-template", "data": "http://example.com/dictionary/{term:1}/{term}", "valid": true }, { "description": "an invalid uri-template", "data": "http://example.com/dictionary/{term:1}/{term", "valid": false }, { "description": "a valid uri-template without variables", "data": "http://example.com/dictionary", "valid": true }, { "description": "a valid relative uri-template", "data": "dictionary/{term:1}/{term}", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/uri.json000066400000000000000000000111671477700171100322450ustar00rootroot00000000000000[ { "description": "validation of URIs", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "uri" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid URL with anchor tag", "data": "http://foo.bar/?baz=qux#quux", "valid": true }, { "description": "a valid URL with anchor tag and parentheses", "data": "http://foo.com/blah_(wikipedia)_blah#cite-1", "valid": true }, { "description": "a valid URL with URL-encoded stuff", "data": "http://foo.bar/?q=Test%20URL-encoded%20stuff", "valid": true }, { "description": "a valid puny-coded URL ", "data": "http://xn--nw2a.xn--j6w193g/", "valid": true }, { "description": "a valid URL with many special characters", "data": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", "valid": true }, { "description": "a valid URL based on IPv4", "data": "http://223.255.255.254", "valid": true }, { "description": "a valid URL with ftp scheme", "data": "ftp://ftp.is.co.za/rfc/rfc1808.txt", "valid": true }, { "description": "a valid URL for a simple text file", "data": "http://www.ietf.org/rfc/rfc2396.txt", "valid": true }, { "description": "a valid URL ", "data": "ldap://[2001:db8::7]/c=GB?objectClass?one", "valid": true }, { "description": "a valid mailto URI", "data": "mailto:John.Doe@example.com", "valid": true }, { "description": "a valid newsgroup URI", "data": "news:comp.infosystems.www.servers.unix", "valid": true }, { "description": "a valid tel URI", "data": "tel:+1-816-555-1212", "valid": true }, { "description": "a valid URN", "data": "urn:oasis:names:specification:docbook:dtd:xml:4.1.2", "valid": true }, { "description": "an invalid protocol-relative URI Reference", "data": "//foo.bar/?baz=qux#quux", "valid": false }, { "description": "an invalid relative URI Reference", "data": "/abc", "valid": false }, { "description": "an invalid URI", "data": "\\\\WINDOWS\\fileshare", "valid": false }, { "description": "an invalid URI though valid URI reference", "data": "abc", "valid": false }, { "description": "an invalid URI with spaces", "data": "http:// shouldfail.com", "valid": false }, { "description": "an invalid URI with spaces and missing scheme", "data": ":// should fail", "valid": false }, { "description": "an invalid URI with comma in scheme", "data": "bar,baz:foo", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/uuid.json000066400000000000000000000072571477700171100324210ustar00rootroot00000000000000[ { "description": "uuid format", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "uuid" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "all upper-case", "data": "2EB8AA08-AA98-11EA-B4AA-73B441D16380", "valid": true }, { "description": "all lower-case", "data": "2eb8aa08-aa98-11ea-b4aa-73b441d16380", "valid": true }, { "description": "mixed case", "data": "2eb8aa08-AA98-11ea-B4Aa-73B441D16380", "valid": true }, { "description": "all zeroes is valid", "data": "00000000-0000-0000-0000-000000000000", "valid": true }, { "description": "wrong length", "data": "2eb8aa08-aa98-11ea-b4aa-73b441d1638", "valid": false }, { "description": "missing section", "data": "2eb8aa08-aa98-11ea-73b441d16380", "valid": false }, { "description": "bad characters (not hex)", "data": "2eb8aa08-aa98-11ea-b4ga-73b441d16380", "valid": false }, { "description": "no dashes", "data": "2eb8aa08aa9811eab4aa73b441d16380", "valid": false }, { "description": "too few dashes", "data": "2eb8aa08aa98-11ea-b4aa73b441d16380", "valid": false }, { "description": "too many dashes", "data": "2eb8-aa08-aa98-11ea-b4aa73b44-1d16380", "valid": false }, { "description": "dashes in the wrong spot", "data": "2eb8aa08aa9811eab4aa73b441d16380----", "valid": false }, { "description": "valid version 4", "data": "98d80576-482e-427f-8434-7f86890ab222", "valid": true }, { "description": "valid version 5", "data": "99c17cbb-656f-564a-940f-1a4568f03487", "valid": true }, { "description": "hypothetical version 6", "data": "99c17cbb-656f-664a-940f-1a4568f03487", "valid": true }, { "description": "hypothetical version 15", "data": "99c17cbb-656f-f64a-940f-1a4568f03487", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/no-schema.json000066400000000000000000000012361477700171100320240ustar00rootroot00000000000000[ { "description": "validation without $schema", "comment": "minLength is the same across all drafts", "schema": { "minLength": 2 }, "tests": [ { "description": "a 3-character string is valid", "data": "foo", "valid": true }, { "description": "a 1-character string is not valid", "data": "a", "valid": false }, { "description": "a non-string is valid", "data": 5, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/non-bmp-regex.json000066400000000000000000000050001477700171100326210ustar00rootroot00000000000000[ { "description": "Proper UTF-16 surrogate pair handling: pattern", "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "pattern": "^🐲*$" }, "tests": [ { "description": "matches empty", "data": "", "valid": true }, { "description": "matches single", "data": "🐲", "valid": true }, { "description": "matches two", "data": "🐲🐲", "valid": true }, { "description": "doesn't match one", "data": "🐉", "valid": false }, { "description": "doesn't match two", "data": "🐉🐉", "valid": false }, { "description": "doesn't match one ASCII", "data": "D", "valid": false }, { "description": "doesn't match two ASCII", "data": "DD", "valid": false } ] }, { "description": "Proper UTF-16 surrogate pair handling: patternProperties", "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "patternProperties": { "^🐲*$": { "type": "integer" } } }, "tests": [ { "description": "matches empty", "data": { "": 1 }, "valid": true }, { "description": "matches single", "data": { "🐲": 1 }, "valid": true }, { "description": "matches two", "data": { "🐲🐲": 1 }, "valid": true }, { "description": "doesn't match one", "data": { "🐲": "hello" }, "valid": false }, { "description": "doesn't match two", "data": { "🐲🐲": "hello" }, "valid": false } ] } ] refOfUnknownKeyword.json000066400000000000000000000036041477700171100340620ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional[ { "description": "reference of a root arbitrary keyword ", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "unknown-keyword": {"type": "integer"}, "properties": { "bar": {"$ref": "#/unknown-keyword"} } }, "tests": [ { "description": "match", "data": {"bar": 3}, "valid": true }, { "description": "mismatch", "data": {"bar": true}, "valid": false } ] }, { "description": "reference of an arbitrary keyword of a sub-schema", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "foo": {"unknown-keyword": {"type": "integer"}}, "bar": {"$ref": "#/properties/foo/unknown-keyword"} } }, "tests": [ { "description": "match", "data": {"bar": 3}, "valid": true }, { "description": "mismatch", "data": {"bar": true}, "valid": false } ] }, { "description": "reference internals of known non-applicator", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "/base", "examples": [ { "type": "string" } ], "$ref": "#/examples/0" }, "tests": [ { "description": "match", "data": "a string", "valid": true }, { "description": "mismatch", "data": 42, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/pattern.json000066400000000000000000000032751477700171100300070ustar00rootroot00000000000000[ { "description": "pattern validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "pattern": "^a*$" }, "tests": [ { "description": "a matching pattern is valid", "data": "aaa", "valid": true }, { "description": "a non-matching pattern is invalid", "data": "abc", "valid": false }, { "description": "ignores booleans", "data": true, "valid": true }, { "description": "ignores integers", "data": 123, "valid": true }, { "description": "ignores floats", "data": 1.0, "valid": true }, { "description": "ignores objects", "data": {}, "valid": true }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores null", "data": null, "valid": true } ] }, { "description": "pattern is not anchored", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "pattern": "a+" }, "tests": [ { "description": "matches a substring", "data": "xxaayy", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/patternProperties.json000066400000000000000000000126341477700171100320630ustar00rootroot00000000000000[ { "description": "patternProperties validates properties matching a regex", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "patternProperties": { "f.*o": {"type": "integer"} } }, "tests": [ { "description": "a single valid match is valid", "data": {"foo": 1}, "valid": true }, { "description": "multiple valid matches is valid", "data": {"foo": 1, "foooooo" : 2}, "valid": true }, { "description": "a single invalid match is invalid", "data": {"foo": "bar", "fooooo": 2}, "valid": false }, { "description": "multiple invalid matches is invalid", "data": {"foo": "bar", "foooooo" : "baz"}, "valid": false }, { "description": "ignores arrays", "data": ["foo"], "valid": true }, { "description": "ignores strings", "data": "foo", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "multiple simultaneous patternProperties are validated", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "patternProperties": { "a*": {"type": "integer"}, "aaa*": {"maximum": 20} } }, "tests": [ { "description": "a single valid match is valid", "data": {"a": 21}, "valid": true }, { "description": "a simultaneous match is valid", "data": {"aaaa": 18}, "valid": true }, { "description": "multiple matches is valid", "data": {"a": 21, "aaaa": 18}, "valid": true }, { "description": "an invalid due to one is invalid", "data": {"a": "bar"}, "valid": false }, { "description": "an invalid due to the other is invalid", "data": {"aaaa": 31}, "valid": false }, { "description": "an invalid due to both is invalid", "data": {"aaa": "foo", "aaaa": 31}, "valid": false } ] }, { "description": "regexes are not anchored by default and are case sensitive", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "patternProperties": { "[0-9]{2,}": { "type": "boolean" }, "X_": { "type": "string" } } }, "tests": [ { "description": "non recognized members are ignored", "data": { "answer 1": "42" }, "valid": true }, { "description": "recognized members are accounted for", "data": { "a31b": null }, "valid": false }, { "description": "regexes are case sensitive", "data": { "a_x_3": 3 }, "valid": true }, { "description": "regexes are case sensitive, 2", "data": { "a_X_3": 3 }, "valid": false } ] }, { "description": "patternProperties with boolean schemas", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "patternProperties": { "f.*": true, "b.*": false } }, "tests": [ { "description": "object with property matching schema true is valid", "data": {"foo": 1}, "valid": true }, { "description": "object with property matching schema false is invalid", "data": {"bar": 2}, "valid": false }, { "description": "object with both properties is invalid", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "object with a property matching both true and false is invalid", "data": {"foobar":1}, "valid": false }, { "description": "empty object is valid", "data": {}, "valid": true } ] }, { "description": "patternProperties with null valued instance properties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "patternProperties": { "^.*bar$": {"type": "null"} } }, "tests": [ { "description": "allows null values", "data": {"foobar": null}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/prefixItems.json000066400000000000000000000055611477700171100306310ustar00rootroot00000000000000[ { "description": "a schema given for prefixItems", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [ {"type": "integer"}, {"type": "string"} ] }, "tests": [ { "description": "correct types", "data": [ 1, "foo" ], "valid": true }, { "description": "wrong types", "data": [ "foo", 1 ], "valid": false }, { "description": "incomplete array of items", "data": [ 1 ], "valid": true }, { "description": "array with additional items", "data": [ 1, "foo", true ], "valid": true }, { "description": "empty array", "data": [ ], "valid": true }, { "description": "JavaScript pseudo-array is valid", "data": { "0": "invalid", "1": "valid", "length": 2 }, "valid": true } ] }, { "description": "prefixItems with boolean schemas", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [true, false] }, "tests": [ { "description": "array with one item is valid", "data": [ 1 ], "valid": true }, { "description": "array with two items is invalid", "data": [ 1, "foo" ], "valid": false }, { "description": "empty array is valid", "data": [], "valid": true } ] }, { "description": "additional items are allowed by default", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [{"type": "integer"}] }, "tests": [ { "description": "only the first item is validated", "data": [1, "foo", false], "valid": true } ] }, { "description": "prefixItems with null instance elements", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [ { "type": "null" } ] }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/properties.json000066400000000000000000000170631477700171100305260ustar00rootroot00000000000000[ { "description": "object properties validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "foo": {"type": "integer"}, "bar": {"type": "string"} } }, "tests": [ { "description": "both properties present and valid is valid", "data": {"foo": 1, "bar": "baz"}, "valid": true }, { "description": "one property invalid is invalid", "data": {"foo": 1, "bar": {}}, "valid": false }, { "description": "both properties invalid is invalid", "data": {"foo": [], "bar": {}}, "valid": false }, { "description": "doesn't invalidate other properties", "data": {"quux": []}, "valid": true }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "properties, patternProperties, additionalProperties interaction", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "foo": {"type": "array", "maxItems": 3}, "bar": {"type": "array"} }, "patternProperties": {"f.o": {"minItems": 2}}, "additionalProperties": {"type": "integer"} }, "tests": [ { "description": "property validates property", "data": {"foo": [1, 2]}, "valid": true }, { "description": "property invalidates property", "data": {"foo": [1, 2, 3, 4]}, "valid": false }, { "description": "patternProperty invalidates property", "data": {"foo": []}, "valid": false }, { "description": "patternProperty validates nonproperty", "data": {"fxo": [1, 2]}, "valid": true }, { "description": "patternProperty invalidates nonproperty", "data": {"fxo": []}, "valid": false }, { "description": "additionalProperty ignores property", "data": {"bar": []}, "valid": true }, { "description": "additionalProperty validates others", "data": {"quux": 3}, "valid": true }, { "description": "additionalProperty invalidates others", "data": {"quux": "foo"}, "valid": false } ] }, { "description": "properties with boolean schema", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "foo": true, "bar": false } }, "tests": [ { "description": "no property present is valid", "data": {}, "valid": true }, { "description": "only 'true' property present is valid", "data": {"foo": 1}, "valid": true }, { "description": "only 'false' property present is invalid", "data": {"bar": 2}, "valid": false }, { "description": "both properties present is invalid", "data": {"foo": 1, "bar": 2}, "valid": false } ] }, { "description": "properties with escaped characters", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "foo\nbar": {"type": "number"}, "foo\"bar": {"type": "number"}, "foo\\bar": {"type": "number"}, "foo\rbar": {"type": "number"}, "foo\tbar": {"type": "number"}, "foo\fbar": {"type": "number"} } }, "tests": [ { "description": "object with all numbers is valid", "data": { "foo\nbar": 1, "foo\"bar": 1, "foo\\bar": 1, "foo\rbar": 1, "foo\tbar": 1, "foo\fbar": 1 }, "valid": true }, { "description": "object with strings is invalid", "data": { "foo\nbar": "1", "foo\"bar": "1", "foo\\bar": "1", "foo\rbar": "1", "foo\tbar": "1", "foo\fbar": "1" }, "valid": false } ] }, { "description": "properties with null valued instance properties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "foo": {"type": "null"} } }, "tests": [ { "description": "allows null values", "data": {"foo": null}, "valid": true } ] }, { "description": "properties whose names are Javascript object property names", "comment": "Ensure JS implementations don't universally consider e.g. __proto__ to always be present in an object.", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "__proto__": {"type": "number"}, "toString": { "properties": { "length": { "type": "string" } } }, "constructor": {"type": "number"} } }, "tests": [ { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true }, { "description": "none of the properties mentioned", "data": {}, "valid": true }, { "description": "__proto__ not valid", "data": { "__proto__": "foo" }, "valid": false }, { "description": "toString not valid", "data": { "toString": { "length": 37 } }, "valid": false }, { "description": "constructor not valid", "data": { "constructor": { "length": 37 } }, "valid": false }, { "description": "all present and valid", "data": { "__proto__": 12, "toString": { "length": "foo" }, "constructor": 37 }, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/propertyNames.json000066400000000000000000000045311477700171100311760ustar00rootroot00000000000000[ { "description": "propertyNames validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "propertyNames": {"maxLength": 3} }, "tests": [ { "description": "all property names valid", "data": { "f": {}, "foo": {} }, "valid": true }, { "description": "some property names invalid", "data": { "foo": {}, "foobar": {} }, "valid": false }, { "description": "object without properties is valid", "data": {}, "valid": true }, { "description": "ignores arrays", "data": [1, 2, 3, 4], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "propertyNames with boolean schema true", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "propertyNames": true }, "tests": [ { "description": "object with any properties is valid", "data": {"foo": 1}, "valid": true }, { "description": "empty object is valid", "data": {}, "valid": true } ] }, { "description": "propertyNames with boolean schema false", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "propertyNames": false }, "tests": [ { "description": "object with any properties is invalid", "data": {"foo": 1}, "valid": false }, { "description": "empty object is valid", "data": {}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/ref.json000066400000000000000000001000411477700171100270730ustar00rootroot00000000000000[ { "description": "root pointer ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "foo": {"$ref": "#"} }, "additionalProperties": false }, "tests": [ { "description": "match", "data": {"foo": false}, "valid": true }, { "description": "recursive match", "data": {"foo": {"foo": false}}, "valid": true }, { "description": "mismatch", "data": {"bar": false}, "valid": false }, { "description": "recursive mismatch", "data": {"foo": {"bar": false}}, "valid": false } ] }, { "description": "relative pointer ref to object", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "foo": {"type": "integer"}, "bar": {"$ref": "#/properties/foo"} } }, "tests": [ { "description": "match", "data": {"bar": 3}, "valid": true }, { "description": "mismatch", "data": {"bar": true}, "valid": false } ] }, { "description": "relative pointer ref to array", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [ {"type": "integer"}, {"$ref": "#/prefixItems/0"} ] }, "tests": [ { "description": "match array", "data": [1, 2], "valid": true }, { "description": "mismatch array", "data": [1, "foo"], "valid": false } ] }, { "description": "escaped pointer ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "tilde~field": {"type": "integer"}, "slash/field": {"type": "integer"}, "percent%field": {"type": "integer"} }, "properties": { "tilde": {"$ref": "#/$defs/tilde~0field"}, "slash": {"$ref": "#/$defs/slash~1field"}, "percent": {"$ref": "#/$defs/percent%25field"} } }, "tests": [ { "description": "slash invalid", "data": {"slash": "aoeu"}, "valid": false }, { "description": "tilde invalid", "data": {"tilde": "aoeu"}, "valid": false }, { "description": "percent invalid", "data": {"percent": "aoeu"}, "valid": false }, { "description": "slash valid", "data": {"slash": 123}, "valid": true }, { "description": "tilde valid", "data": {"tilde": 123}, "valid": true }, { "description": "percent valid", "data": {"percent": 123}, "valid": true } ] }, { "description": "nested refs", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "a": {"type": "integer"}, "b": {"$ref": "#/$defs/a"}, "c": {"$ref": "#/$defs/b"} }, "$ref": "#/$defs/c" }, "tests": [ { "description": "nested ref valid", "data": 5, "valid": true }, { "description": "nested ref invalid", "data": "a", "valid": false } ] }, { "description": "ref applies alongside sibling keywords", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "reffed": { "type": "array" } }, "properties": { "foo": { "$ref": "#/$defs/reffed", "maxItems": 2 } } }, "tests": [ { "description": "ref valid, maxItems valid", "data": { "foo": [] }, "valid": true }, { "description": "ref valid, maxItems invalid", "data": { "foo": [1, 2, 3] }, "valid": false }, { "description": "ref invalid", "data": { "foo": "string" }, "valid": false } ] }, { "description": "remote ref, containing refs itself", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "https://json-schema.org/draft/2020-12/schema" }, "tests": [ { "description": "remote ref valid", "data": {"minLength": 1}, "valid": true }, { "description": "remote ref invalid", "data": {"minLength": -1}, "valid": false } ] }, { "description": "property named $ref that is not a reference", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "$ref": {"type": "string"} } }, "tests": [ { "description": "property named $ref valid", "data": {"$ref": "a"}, "valid": true }, { "description": "property named $ref invalid", "data": {"$ref": 2}, "valid": false } ] }, { "description": "property named $ref, containing an actual $ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "$ref": {"$ref": "#/$defs/is-string"} }, "$defs": { "is-string": { "type": "string" } } }, "tests": [ { "description": "property named $ref valid", "data": {"$ref": "a"}, "valid": true }, { "description": "property named $ref invalid", "data": {"$ref": 2}, "valid": false } ] }, { "description": "$ref to boolean schema true", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "#/$defs/bool", "$defs": { "bool": true } }, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "$ref to boolean schema false", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "#/$defs/bool", "$defs": { "bool": false } }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "Recursive references between schemas", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://localhost:1234/draft2020-12/tree", "description": "tree of nodes", "type": "object", "properties": { "meta": {"type": "string"}, "nodes": { "type": "array", "items": {"$ref": "node"} } }, "required": ["meta", "nodes"], "$defs": { "node": { "$id": "http://localhost:1234/draft2020-12/node", "description": "node", "type": "object", "properties": { "value": {"type": "number"}, "subtree": {"$ref": "tree"} }, "required": ["value"] } } }, "tests": [ { "description": "valid tree", "data": { "meta": "root", "nodes": [ { "value": 1, "subtree": { "meta": "child", "nodes": [ {"value": 1.1}, {"value": 1.2} ] } }, { "value": 2, "subtree": { "meta": "child", "nodes": [ {"value": 2.1}, {"value": 2.2} ] } } ] }, "valid": true }, { "description": "invalid tree", "data": { "meta": "root", "nodes": [ { "value": 1, "subtree": { "meta": "child", "nodes": [ {"value": "string is invalid"}, {"value": 1.2} ] } }, { "value": 2, "subtree": { "meta": "child", "nodes": [ {"value": 2.1}, {"value": 2.2} ] } } ] }, "valid": false } ] }, { "description": "refs with quote", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "foo\"bar": {"$ref": "#/$defs/foo%22bar"} }, "$defs": { "foo\"bar": {"type": "number"} } }, "tests": [ { "description": "object with numbers is valid", "data": { "foo\"bar": 1 }, "valid": true }, { "description": "object with strings is invalid", "data": { "foo\"bar": "1" }, "valid": false } ] }, { "description": "ref creates new scope when adjacent to keywords", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "A": { "unevaluatedProperties": false } }, "properties": { "prop1": { "type": "string" } }, "$ref": "#/$defs/A" }, "tests": [ { "description": "referenced subschema doesn't see annotations from properties", "data": { "prop1": "match" }, "valid": false } ] }, { "description": "naive replacement of $ref with its destination is not correct", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "a_string": { "type": "string" } }, "enum": [ { "$ref": "#/$defs/a_string" } ] }, "tests": [ { "description": "do not evaluate the $ref inside the enum, matching any string", "data": "this is a string", "valid": false }, { "description": "do not evaluate the $ref inside the enum, definition exact match", "data": { "type": "string" }, "valid": false }, { "description": "match the enum exactly", "data": { "$ref": "#/$defs/a_string" }, "valid": true } ] }, { "description": "refs with relative uris and defs", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://example.com/schema-relative-uri-defs1.json", "properties": { "foo": { "$id": "schema-relative-uri-defs2.json", "$defs": { "inner": { "properties": { "bar": { "type": "string" } } } }, "$ref": "#/$defs/inner" } }, "$ref": "schema-relative-uri-defs2.json" }, "tests": [ { "description": "invalid on inner field", "data": { "foo": { "bar": 1 }, "bar": "a" }, "valid": false }, { "description": "invalid on outer field", "data": { "foo": { "bar": "a" }, "bar": 1 }, "valid": false }, { "description": "valid on both fields", "data": { "foo": { "bar": "a" }, "bar": "a" }, "valid": true } ] }, { "description": "relative refs with absolute uris and defs", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://example.com/schema-refs-absolute-uris-defs1.json", "properties": { "foo": { "$id": "http://example.com/schema-refs-absolute-uris-defs2.json", "$defs": { "inner": { "properties": { "bar": { "type": "string" } } } }, "$ref": "#/$defs/inner" } }, "$ref": "schema-refs-absolute-uris-defs2.json" }, "tests": [ { "description": "invalid on inner field", "data": { "foo": { "bar": 1 }, "bar": "a" }, "valid": false }, { "description": "invalid on outer field", "data": { "foo": { "bar": "a" }, "bar": 1 }, "valid": false }, { "description": "valid on both fields", "data": { "foo": { "bar": "a" }, "bar": "a" }, "valid": true } ] }, { "description": "$id must be resolved against nearest parent, not just immediate parent", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://example.com/a.json", "$defs": { "x": { "$id": "http://example.com/b/c.json", "not": { "$defs": { "y": { "$id": "d.json", "type": "number" } } } } }, "allOf": [ { "$ref": "http://example.com/b/d.json" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] }, { "description": "order of evaluation: $id and $ref", "schema": { "$comment": "$id must be evaluated before $ref to get the proper $ref destination", "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://example.com/draft2020-12/ref-and-id1/base.json", "$ref": "int.json", "$defs": { "bigint": { "$comment": "canonical uri: https://example.com/ref-and-id1/int.json", "$id": "int.json", "maximum": 10 }, "smallint": { "$comment": "canonical uri: https://example.com/ref-and-id1-int.json", "$id": "/draft2020-12/ref-and-id1-int.json", "maximum": 2 } } }, "tests": [ { "description": "data is valid against first definition", "data": 5, "valid": true }, { "description": "data is invalid against first definition", "data": 50, "valid": false } ] }, { "description": "order of evaluation: $id and $anchor and $ref", "schema": { "$comment": "$id must be evaluated before $ref to get the proper $ref destination", "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://example.com/draft2020-12/ref-and-id2/base.json", "$ref": "#bigint", "$defs": { "bigint": { "$comment": "canonical uri: /ref-and-id2/base.json#/$defs/bigint; another valid uri for this location: /ref-and-id2/base.json#bigint", "$anchor": "bigint", "maximum": 10 }, "smallint": { "$comment": "canonical uri: https://example.com/ref-and-id2#/$defs/smallint; another valid uri for this location: https://example.com/ref-and-id2/#bigint", "$id": "https://example.com/draft2020-12/ref-and-id2/", "$anchor": "bigint", "maximum": 2 } } }, "tests": [ { "description": "data is valid against first definition", "data": 5, "valid": true }, { "description": "data is invalid against first definition", "data": 50, "valid": false } ] }, { "description": "simple URN base URI with $ref via the URN", "schema": { "$comment": "URIs do not have to have HTTP(s) schemes", "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "urn:uuid:deadbeef-1234-ffff-ffff-4321feebdaed", "minimum": 30, "properties": { "foo": {"$ref": "urn:uuid:deadbeef-1234-ffff-ffff-4321feebdaed"} } }, "tests": [ { "description": "valid under the URN IDed schema", "data": {"foo": 37}, "valid": true }, { "description": "invalid under the URN IDed schema", "data": {"foo": 12}, "valid": false } ] }, { "description": "simple URN base URI with JSON pointer", "schema": { "$comment": "URIs do not have to have HTTP(s) schemes", "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "urn:uuid:deadbeef-1234-00ff-ff00-4321feebdaed", "properties": { "foo": {"$ref": "#/$defs/bar"} }, "$defs": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with NSS", "schema": { "$comment": "RFC 8141 §2.2", "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "urn:example:1/406/47452/2", "properties": { "foo": {"$ref": "#/$defs/bar"} }, "$defs": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with r-component", "schema": { "$comment": "RFC 8141 §2.3.1", "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "urn:example:foo-bar-baz-qux?+CCResolve:cc=uk", "properties": { "foo": {"$ref": "#/$defs/bar"} }, "$defs": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with q-component", "schema": { "$comment": "RFC 8141 §2.3.2", "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "urn:example:weather?=op=map&lat=39.56&lon=-104.85&datetime=1969-07-21T02:56:15Z", "properties": { "foo": {"$ref": "#/$defs/bar"} }, "$defs": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with f-component", "schema": { "$comment": "RFC 8141 §2.3.3, but we don't allow fragments", "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "https://json-schema.org/draft/2020-12/schema" }, "tests": [ { "description": "is invalid", "data": {"$id": "urn:example:foo-bar-baz-qux#somepart"}, "valid": false } ] }, { "description": "URN base URI with URN and JSON pointer ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "urn:uuid:deadbeef-1234-0000-0000-4321feebdaed", "properties": { "foo": {"$ref": "urn:uuid:deadbeef-1234-0000-0000-4321feebdaed#/$defs/bar"} }, "$defs": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with URN and anchor ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "urn:uuid:deadbeef-1234-ff00-00ff-4321feebdaed", "properties": { "foo": {"$ref": "urn:uuid:deadbeef-1234-ff00-00ff-4321feebdaed#something"} }, "$defs": { "bar": { "$anchor": "something", "type": "string" } } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN ref with nested pointer ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "urn:uuid:deadbeef-4321-ffff-ffff-1234feebdaed", "$defs": { "foo": { "$id": "urn:uuid:deadbeef-4321-ffff-ffff-1234feebdaed", "$defs": {"bar": {"type": "string"}}, "$ref": "#/$defs/bar" } } }, "tests": [ { "description": "a string is valid", "data": "bar", "valid": true }, { "description": "a non-string is invalid", "data": 12, "valid": false } ] }, { "description": "ref to if", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "http://example.com/ref/if", "if": { "$id": "http://example.com/ref/if", "type": "integer" } }, "tests": [ { "description": "a non-integer is invalid due to the $ref", "data": "foo", "valid": false }, { "description": "an integer is valid", "data": 12, "valid": true } ] }, { "description": "ref to then", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "http://example.com/ref/then", "then": { "$id": "http://example.com/ref/then", "type": "integer" } }, "tests": [ { "description": "a non-integer is invalid due to the $ref", "data": "foo", "valid": false }, { "description": "an integer is valid", "data": 12, "valid": true } ] }, { "description": "ref to else", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "http://example.com/ref/else", "else": { "$id": "http://example.com/ref/else", "type": "integer" } }, "tests": [ { "description": "a non-integer is invalid due to the $ref", "data": "foo", "valid": false }, { "description": "an integer is valid", "data": 12, "valid": true } ] }, { "description": "ref with absolute-path-reference", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://example.com/ref/absref.json", "$defs": { "a": { "$id": "http://example.com/ref/absref/foobar.json", "type": "number" }, "b": { "$id": "http://example.com/absref/foobar.json", "type": "string" } }, "$ref": "/absref/foobar.json" }, "tests": [ { "description": "a string is valid", "data": "foo", "valid": true }, { "description": "an integer is invalid", "data": 12, "valid": false } ] }, { "description": "$id with file URI still resolves pointers - *nix", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "file:///folder/file.json", "$defs": { "foo": { "type": "number" } }, "$ref": "#/$defs/foo" }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] }, { "description": "$id with file URI still resolves pointers - windows", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "file:///c:/folder/file.json", "$defs": { "foo": { "type": "number" } }, "$ref": "#/$defs/foo" }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] }, { "description": "empty tokens in $ref json-pointer", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "": { "$defs": { "": { "type": "number" } } } }, "allOf": [ { "$ref": "#/$defs//$defs/" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/refRemote.json000066400000000000000000000240331477700171100302550ustar00rootroot00000000000000[ { "description": "remote ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "http://localhost:1234/draft2020-12/integer.json" }, "tests": [ { "description": "remote ref valid", "data": 1, "valid": true }, { "description": "remote ref invalid", "data": "a", "valid": false } ] }, { "description": "fragment within remote ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "http://localhost:1234/draft2020-12/subSchemas.json#/$defs/integer" }, "tests": [ { "description": "remote fragment valid", "data": 1, "valid": true }, { "description": "remote fragment invalid", "data": "a", "valid": false } ] }, { "description": "anchor within remote ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "http://localhost:1234/draft2020-12/locationIndependentIdentifier.json#foo" }, "tests": [ { "description": "remote anchor valid", "data": 1, "valid": true }, { "description": "remote anchor invalid", "data": "a", "valid": false } ] }, { "description": "ref within remote ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "http://localhost:1234/draft2020-12/subSchemas.json#/$defs/refToInteger" }, "tests": [ { "description": "ref within ref valid", "data": 1, "valid": true }, { "description": "ref within ref invalid", "data": "a", "valid": false } ] }, { "description": "base URI change", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://localhost:1234/draft2020-12/", "items": { "$id": "baseUriChange/", "items": {"$ref": "folderInteger.json"} } }, "tests": [ { "description": "base URI change ref valid", "data": [[1]], "valid": true }, { "description": "base URI change ref invalid", "data": [["a"]], "valid": false } ] }, { "description": "base URI change - change folder", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://localhost:1234/draft2020-12/scope_change_defs1.json", "type" : "object", "properties": {"list": {"$ref": "baseUriChangeFolder/"}}, "$defs": { "baz": { "$id": "baseUriChangeFolder/", "type": "array", "items": {"$ref": "folderInteger.json"} } } }, "tests": [ { "description": "number is valid", "data": {"list": [1]}, "valid": true }, { "description": "string is invalid", "data": {"list": ["a"]}, "valid": false } ] }, { "description": "base URI change - change folder in subschema", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://localhost:1234/draft2020-12/scope_change_defs2.json", "type" : "object", "properties": {"list": {"$ref": "baseUriChangeFolderInSubschema/#/$defs/bar"}}, "$defs": { "baz": { "$id": "baseUriChangeFolderInSubschema/", "$defs": { "bar": { "type": "array", "items": {"$ref": "folderInteger.json"} } } } } }, "tests": [ { "description": "number is valid", "data": {"list": [1]}, "valid": true }, { "description": "string is invalid", "data": {"list": ["a"]}, "valid": false } ] }, { "description": "root ref in remote ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://localhost:1234/draft2020-12/object", "type": "object", "properties": { "name": {"$ref": "name-defs.json#/$defs/orNull"} } }, "tests": [ { "description": "string is valid", "data": { "name": "foo" }, "valid": true }, { "description": "null is valid", "data": { "name": null }, "valid": true }, { "description": "object is invalid", "data": { "name": { "name": null } }, "valid": false } ] }, { "description": "remote ref with ref to defs", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://localhost:1234/draft2020-12/schema-remote-ref-ref-defs1.json", "$ref": "ref-and-defs.json" }, "tests": [ { "description": "invalid", "data": { "bar": 1 }, "valid": false }, { "description": "valid", "data": { "bar": "a" }, "valid": true } ] }, { "description": "Location-independent identifier in remote ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "http://localhost:1234/draft2020-12/locationIndependentIdentifier.json#/$defs/refToInteger" }, "tests": [ { "description": "integer is valid", "data": 1, "valid": true }, { "description": "string is invalid", "data": "foo", "valid": false } ] }, { "description": "retrieved nested refs resolve relative to their URI not $id", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://localhost:1234/draft2020-12/some-id", "properties": { "name": {"$ref": "nested/foo-ref-string.json"} } }, "tests": [ { "description": "number is invalid", "data": { "name": {"foo": 1} }, "valid": false }, { "description": "string is valid", "data": { "name": {"foo": "a"} }, "valid": true } ] }, { "description": "remote HTTP ref with different $id", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "http://localhost:1234/different-id-ref-string.json" }, "tests": [ { "description": "number is invalid", "data": 1, "valid": false }, { "description": "string is valid", "data": "foo", "valid": true } ] }, { "description": "remote HTTP ref with different URN $id", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "http://localhost:1234/urn-ref-string.json" }, "tests": [ { "description": "number is invalid", "data": 1, "valid": false }, { "description": "string is valid", "data": "foo", "valid": true } ] }, { "description": "remote HTTP ref with nested absolute ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "http://localhost:1234/nested-absolute-ref-to-string.json" }, "tests": [ { "description": "number is invalid", "data": 1, "valid": false }, { "description": "string is valid", "data": "foo", "valid": true } ] }, { "description": "$ref to $ref finds detached $anchor", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "http://localhost:1234/draft2020-12/detached-ref.json#/$defs/foo" }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/required.json000066400000000000000000000110231477700171100301400ustar00rootroot00000000000000[ { "description": "required validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "foo": {}, "bar": {} }, "required": ["foo"] }, "tests": [ { "description": "present required property is valid", "data": {"foo": 1}, "valid": true }, { "description": "non-present required property is invalid", "data": {"bar": 1}, "valid": false }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores strings", "data": "", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "required default validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "foo": {} } }, "tests": [ { "description": "not required by default", "data": {}, "valid": true } ] }, { "description": "required with empty array", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "foo": {} }, "required": [] }, "tests": [ { "description": "property not required", "data": {}, "valid": true } ] }, { "description": "required with escaped characters", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "required": [ "foo\nbar", "foo\"bar", "foo\\bar", "foo\rbar", "foo\tbar", "foo\fbar" ] }, "tests": [ { "description": "object with all properties present is valid", "data": { "foo\nbar": 1, "foo\"bar": 1, "foo\\bar": 1, "foo\rbar": 1, "foo\tbar": 1, "foo\fbar": 1 }, "valid": true }, { "description": "object with some properties missing is invalid", "data": { "foo\nbar": "1", "foo\"bar": "1" }, "valid": false } ] }, { "description": "required properties whose names are Javascript object property names", "comment": "Ensure JS implementations don't universally consider e.g. __proto__ to always be present in an object.", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "required": ["__proto__", "toString", "constructor"] }, "tests": [ { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true }, { "description": "none of the properties mentioned", "data": {}, "valid": false }, { "description": "__proto__ present", "data": { "__proto__": "foo" }, "valid": false }, { "description": "toString present", "data": { "toString": { "length": 37 } }, "valid": false }, { "description": "constructor present", "data": { "constructor": { "length": 37 } }, "valid": false }, { "description": "all present", "data": { "__proto__": 12, "toString": { "length": "foo" }, "constructor": 37 }, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/type.json000066400000000000000000000340351477700171100273110ustar00rootroot00000000000000[ { "description": "integer type matches integers", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "integer" }, "tests": [ { "description": "an integer is an integer", "data": 1, "valid": true }, { "description": "a float with zero fractional part is an integer", "data": 1.0, "valid": true }, { "description": "a float is not an integer", "data": 1.1, "valid": false }, { "description": "a string is not an integer", "data": "foo", "valid": false }, { "description": "a string is still not an integer, even if it looks like one", "data": "1", "valid": false }, { "description": "an object is not an integer", "data": {}, "valid": false }, { "description": "an array is not an integer", "data": [], "valid": false }, { "description": "a boolean is not an integer", "data": true, "valid": false }, { "description": "null is not an integer", "data": null, "valid": false } ] }, { "description": "number type matches numbers", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "number" }, "tests": [ { "description": "an integer is a number", "data": 1, "valid": true }, { "description": "a float with zero fractional part is a number (and an integer)", "data": 1.0, "valid": true }, { "description": "a float is a number", "data": 1.1, "valid": true }, { "description": "a string is not a number", "data": "foo", "valid": false }, { "description": "a string is still not a number, even if it looks like one", "data": "1", "valid": false }, { "description": "an object is not a number", "data": {}, "valid": false }, { "description": "an array is not a number", "data": [], "valid": false }, { "description": "a boolean is not a number", "data": true, "valid": false }, { "description": "null is not a number", "data": null, "valid": false } ] }, { "description": "string type matches strings", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "string" }, "tests": [ { "description": "1 is not a string", "data": 1, "valid": false }, { "description": "a float is not a string", "data": 1.1, "valid": false }, { "description": "a string is a string", "data": "foo", "valid": true }, { "description": "a string is still a string, even if it looks like a number", "data": "1", "valid": true }, { "description": "an empty string is still a string", "data": "", "valid": true }, { "description": "an object is not a string", "data": {}, "valid": false }, { "description": "an array is not a string", "data": [], "valid": false }, { "description": "a boolean is not a string", "data": true, "valid": false }, { "description": "null is not a string", "data": null, "valid": false } ] }, { "description": "object type matches objects", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object" }, "tests": [ { "description": "an integer is not an object", "data": 1, "valid": false }, { "description": "a float is not an object", "data": 1.1, "valid": false }, { "description": "a string is not an object", "data": "foo", "valid": false }, { "description": "an object is an object", "data": {}, "valid": true }, { "description": "an array is not an object", "data": [], "valid": false }, { "description": "a boolean is not an object", "data": true, "valid": false }, { "description": "null is not an object", "data": null, "valid": false } ] }, { "description": "array type matches arrays", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "array" }, "tests": [ { "description": "an integer is not an array", "data": 1, "valid": false }, { "description": "a float is not an array", "data": 1.1, "valid": false }, { "description": "a string is not an array", "data": "foo", "valid": false }, { "description": "an object is not an array", "data": {}, "valid": false }, { "description": "an array is an array", "data": [], "valid": true }, { "description": "a boolean is not an array", "data": true, "valid": false }, { "description": "null is not an array", "data": null, "valid": false } ] }, { "description": "boolean type matches booleans", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "boolean" }, "tests": [ { "description": "an integer is not a boolean", "data": 1, "valid": false }, { "description": "zero is not a boolean", "data": 0, "valid": false }, { "description": "a float is not a boolean", "data": 1.1, "valid": false }, { "description": "a string is not a boolean", "data": "foo", "valid": false }, { "description": "an empty string is not a boolean", "data": "", "valid": false }, { "description": "an object is not a boolean", "data": {}, "valid": false }, { "description": "an array is not a boolean", "data": [], "valid": false }, { "description": "true is a boolean", "data": true, "valid": true }, { "description": "false is a boolean", "data": false, "valid": true }, { "description": "null is not a boolean", "data": null, "valid": false } ] }, { "description": "null type matches only the null object", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "null" }, "tests": [ { "description": "an integer is not null", "data": 1, "valid": false }, { "description": "a float is not null", "data": 1.1, "valid": false }, { "description": "zero is not null", "data": 0, "valid": false }, { "description": "a string is not null", "data": "foo", "valid": false }, { "description": "an empty string is not null", "data": "", "valid": false }, { "description": "an object is not null", "data": {}, "valid": false }, { "description": "an array is not null", "data": [], "valid": false }, { "description": "true is not null", "data": true, "valid": false }, { "description": "false is not null", "data": false, "valid": false }, { "description": "null is null", "data": null, "valid": true } ] }, { "description": "multiple types can be specified in an array", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": ["integer", "string"] }, "tests": [ { "description": "an integer is valid", "data": 1, "valid": true }, { "description": "a string is valid", "data": "foo", "valid": true }, { "description": "a float is invalid", "data": 1.1, "valid": false }, { "description": "an object is invalid", "data": {}, "valid": false }, { "description": "an array is invalid", "data": [], "valid": false }, { "description": "a boolean is invalid", "data": true, "valid": false }, { "description": "null is invalid", "data": null, "valid": false } ] }, { "description": "type as array with one item", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": ["string"] }, "tests": [ { "description": "string is valid", "data": "foo", "valid": true }, { "description": "number is invalid", "data": 123, "valid": false } ] }, { "description": "type: array or object", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": ["array", "object"] }, "tests": [ { "description": "array is valid", "data": [1,2,3], "valid": true }, { "description": "object is valid", "data": {"foo": 123}, "valid": true }, { "description": "number is invalid", "data": 123, "valid": false }, { "description": "string is invalid", "data": "foo", "valid": false }, { "description": "null is invalid", "data": null, "valid": false } ] }, { "description": "type: array, object or null", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": ["array", "object", "null"] }, "tests": [ { "description": "array is valid", "data": [1,2,3], "valid": true }, { "description": "object is valid", "data": {"foo": 123}, "valid": true }, { "description": "null is valid", "data": null, "valid": true }, { "description": "number is invalid", "data": 123, "valid": false }, { "description": "string is invalid", "data": "foo", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/unevaluatedItems.json000066400000000000000000000543751477700171100316600ustar00rootroot00000000000000[ { "description": "unevaluatedItems true", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "unevaluatedItems": true }, "tests": [ { "description": "with no unevaluated items", "data": [], "valid": true }, { "description": "with unevaluated items", "data": ["foo"], "valid": true } ] }, { "description": "unevaluatedItems false", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "unevaluatedItems": false }, "tests": [ { "description": "with no unevaluated items", "data": [], "valid": true }, { "description": "with unevaluated items", "data": ["foo"], "valid": false } ] }, { "description": "unevaluatedItems as schema", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "unevaluatedItems": { "type": "string" } }, "tests": [ { "description": "with no unevaluated items", "data": [], "valid": true }, { "description": "with valid unevaluated items", "data": ["foo"], "valid": true }, { "description": "with invalid unevaluated items", "data": [42], "valid": false } ] }, { "description": "unevaluatedItems with uniform items", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "items": { "type": "string" }, "unevaluatedItems": false }, "tests": [ { "description": "unevaluatedItems doesn't apply", "data": ["foo", "bar"], "valid": true } ] }, { "description": "unevaluatedItems with tuple", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [ { "type": "string" } ], "unevaluatedItems": false }, "tests": [ { "description": "with no unevaluated items", "data": ["foo"], "valid": true }, { "description": "with unevaluated items", "data": ["foo", "bar"], "valid": false } ] }, { "description": "unevaluatedItems with items and prefixItems", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [ { "type": "string" } ], "items": true, "unevaluatedItems": false }, "tests": [ { "description": "unevaluatedItems doesn't apply", "data": ["foo", 42], "valid": true } ] }, { "description": "unevaluatedItems with items", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "items": {"type": "number"}, "unevaluatedItems": {"type": "string"} }, "tests": [ { "description": "valid under items", "comment": "no elements are considered by unevaluatedItems", "data": [5, 6, 7, 8], "valid": true }, { "description": "invalid under items", "data": ["foo", "bar", "baz"], "valid": false } ] }, { "description": "unevaluatedItems with nested tuple", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [ { "type": "string" } ], "allOf": [ { "prefixItems": [ true, { "type": "number" } ] } ], "unevaluatedItems": false }, "tests": [ { "description": "with no unevaluated items", "data": ["foo", 42], "valid": true }, { "description": "with unevaluated items", "data": ["foo", 42, true], "valid": false } ] }, { "description": "unevaluatedItems with nested items", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "unevaluatedItems": {"type": "boolean"}, "anyOf": [ { "items": {"type": "string"} }, true ] }, "tests": [ { "description": "with only (valid) additional items", "data": [true, false], "valid": true }, { "description": "with no additional items", "data": ["yes", "no"], "valid": true }, { "description": "with invalid additional item", "data": ["yes", false], "valid": false } ] }, { "description": "unevaluatedItems with nested prefixItems and items", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ { "prefixItems": [ { "type": "string" } ], "items": true } ], "unevaluatedItems": false }, "tests": [ { "description": "with no additional items", "data": ["foo"], "valid": true }, { "description": "with additional items", "data": ["foo", 42, true], "valid": true } ] }, { "description": "unevaluatedItems with nested unevaluatedItems", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ { "prefixItems": [ { "type": "string" } ] }, { "unevaluatedItems": true } ], "unevaluatedItems": false }, "tests": [ { "description": "with no additional items", "data": ["foo"], "valid": true }, { "description": "with additional items", "data": ["foo", 42, true], "valid": true } ] }, { "description": "unevaluatedItems with anyOf", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [ { "const": "foo" } ], "anyOf": [ { "prefixItems": [ true, { "const": "bar" } ] }, { "prefixItems": [ true, true, { "const": "baz" } ] } ], "unevaluatedItems": false }, "tests": [ { "description": "when one schema matches and has no unevaluated items", "data": ["foo", "bar"], "valid": true }, { "description": "when one schema matches and has unevaluated items", "data": ["foo", "bar", 42], "valid": false }, { "description": "when two schemas match and has no unevaluated items", "data": ["foo", "bar", "baz"], "valid": true }, { "description": "when two schemas match and has unevaluated items", "data": ["foo", "bar", "baz", 42], "valid": false } ] }, { "description": "unevaluatedItems with oneOf", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [ { "const": "foo" } ], "oneOf": [ { "prefixItems": [ true, { "const": "bar" } ] }, { "prefixItems": [ true, { "const": "baz" } ] } ], "unevaluatedItems": false }, "tests": [ { "description": "with no unevaluated items", "data": ["foo", "bar"], "valid": true }, { "description": "with unevaluated items", "data": ["foo", "bar", 42], "valid": false } ] }, { "description": "unevaluatedItems with not", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [ { "const": "foo" } ], "not": { "not": { "prefixItems": [ true, { "const": "bar" } ] } }, "unevaluatedItems": false }, "tests": [ { "description": "with unevaluated items", "data": ["foo", "bar"], "valid": false } ] }, { "description": "unevaluatedItems with if/then/else", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [ { "const": "foo" } ], "if": { "prefixItems": [ true, { "const": "bar" } ] }, "then": { "prefixItems": [ true, true, { "const": "then" } ] }, "else": { "prefixItems": [ true, true, true, { "const": "else" } ] }, "unevaluatedItems": false }, "tests": [ { "description": "when if matches and it has no unevaluated items", "data": ["foo", "bar", "then"], "valid": true }, { "description": "when if matches and it has unevaluated items", "data": ["foo", "bar", "then", "else"], "valid": false }, { "description": "when if doesn't match and it has no unevaluated items", "data": ["foo", 42, 42, "else"], "valid": true }, { "description": "when if doesn't match and it has unevaluated items", "data": ["foo", 42, 42, "else", 42], "valid": false } ] }, { "description": "unevaluatedItems with boolean schemas", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [true], "unevaluatedItems": false }, "tests": [ { "description": "with no unevaluated items", "data": [], "valid": true }, { "description": "with unevaluated items", "data": ["foo"], "valid": false } ] }, { "description": "unevaluatedItems with $ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "#/$defs/bar", "prefixItems": [ { "type": "string" } ], "unevaluatedItems": false, "$defs": { "bar": { "prefixItems": [ true, { "type": "string" } ] } } }, "tests": [ { "description": "with no unevaluated items", "data": ["foo", "bar"], "valid": true }, { "description": "with unevaluated items", "data": ["foo", "bar", "baz"], "valid": false } ] }, { "description": "unevaluatedItems with $dynamicRef", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://example.com/derived", "$ref": "/baseSchema", "$defs": { "derived": { "$dynamicAnchor": "addons", "prefixItems": [ true, { "type": "string" } ] }, "baseSchema": { "$id": "/baseSchema", "$comment": "unevaluatedItems comes first so it's more likely to catch bugs with implementations that are sensitive to keyword ordering", "unevaluatedItems": false, "type": "array", "prefixItems": [ { "type": "string" } ], "$dynamicRef": "#addons", "$defs": { "defaultAddons": { "$comment": "Needed to satisfy the bookending requirement", "$dynamicAnchor": "addons" } } } } }, "tests": [ { "description": "with no unevaluated items", "data": ["foo", "bar"], "valid": true }, { "description": "with unevaluated items", "data": ["foo", "bar", "baz"], "valid": false } ] }, { "description": "unevaluatedItems can't see inside cousins", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ { "prefixItems": [ true ] }, { "unevaluatedItems": false } ] }, "tests": [ { "description": "always fails", "data": [ 1 ], "valid": false } ] }, { "description": "item is evaluated in an uncle schema to unevaluatedItems", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "foo": { "prefixItems": [ { "type": "string" } ], "unevaluatedItems": false } }, "anyOf": [ { "properties": { "foo": { "prefixItems": [ true, { "type": "string" } ] } } } ] }, "tests": [ { "description": "no extra items", "data": { "foo": [ "test" ] }, "valid": true }, { "description": "uncle keyword evaluation is not significant", "data": { "foo": [ "test", "test" ] }, "valid": false } ] }, { "description": "unevaluatedItems depends on adjacent contains", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [true], "contains": {"type": "string"}, "unevaluatedItems": false }, "tests": [ { "description": "second item is evaluated by contains", "data": [ 1, "foo" ], "valid": true }, { "description": "contains fails, second item is not evaluated", "data": [ 1, 2 ], "valid": false }, { "description": "contains passes, second item is not evaluated", "data": [ 1, 2, "foo" ], "valid": false } ] }, { "description": "unevaluatedItems depends on multiple nested contains", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ { "contains": { "multipleOf": 2 } }, { "contains": { "multipleOf": 3 } } ], "unevaluatedItems": { "multipleOf": 5 } }, "tests": [ { "description": "5 not evaluated, passes unevaluatedItems", "data": [ 2, 3, 4, 5, 6 ], "valid": true }, { "description": "7 not evaluated, fails unevaluatedItems", "data": [ 2, 3, 4, 7, 8 ], "valid": false } ] }, { "description": "unevaluatedItems and contains interact to control item dependency relationship", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "if": { "contains": {"const": "a"} }, "then": { "if": { "contains": {"const": "b"} }, "then": { "if": { "contains": {"const": "c"} } } }, "unevaluatedItems": false }, "tests": [ { "description": "empty array is valid", "data": [], "valid": true }, { "description": "only a's are valid", "data": [ "a", "a" ], "valid": true }, { "description": "a's and b's are valid", "data": [ "a", "b", "a", "b", "a" ], "valid": true }, { "description": "a's, b's and c's are valid", "data": [ "c", "a", "c", "c", "b", "a" ], "valid": true }, { "description": "only b's are invalid", "data": [ "b", "b" ], "valid": false }, { "description": "only c's are invalid", "data": [ "c", "c" ], "valid": false }, { "description": "only b's and c's are invalid", "data": [ "c", "b", "c", "b", "c" ], "valid": false }, { "description": "only a's and c's are invalid", "data": [ "c", "a", "c", "a", "c" ], "valid": false } ] }, { "description": "non-array instances are valid", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "unevaluatedItems": false }, "tests": [ { "description": "ignores booleans", "data": true, "valid": true }, { "description": "ignores integers", "data": 123, "valid": true }, { "description": "ignores floats", "data": 1.0, "valid": true }, { "description": "ignores objects", "data": {}, "valid": true }, { "description": "ignores strings", "data": "foo", "valid": true }, { "description": "ignores null", "data": null, "valid": true } ] }, { "description": "unevaluatedItems with null instance elements", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "unevaluatedItems": { "type": "null" } }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] }, { "description": "unevaluatedItems can see annotations from if without then and else", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "if": { "prefixItems": [{"const": "a"}] }, "unevaluatedItems": false }, "tests": [ { "description": "valid in case if is evaluated", "data": [ "a" ], "valid": true }, { "description": "invalid in case if is evaluated", "data": [ "b" ], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/unevaluatedProperties.json000066400000000000000000001310601477700171100327160ustar00rootroot00000000000000[ { "description": "unevaluatedProperties true", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "unevaluatedProperties": true }, "tests": [ { "description": "with no unevaluated properties", "data": {}, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo" }, "valid": true } ] }, { "description": "unevaluatedProperties schema", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "unevaluatedProperties": { "type": "string", "minLength": 3 } }, "tests": [ { "description": "with no unevaluated properties", "data": {}, "valid": true }, { "description": "with valid unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with invalid unevaluated properties", "data": { "foo": "fo" }, "valid": false } ] }, { "description": "unevaluatedProperties false", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": {}, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo" }, "valid": false } ] }, { "description": "unevaluatedProperties with adjacent properties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "unevaluatedProperties with adjacent patternProperties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "patternProperties": { "^foo": { "type": "string" } }, "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "unevaluatedProperties with adjacent additionalProperties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "additionalProperties": true, "unevaluatedProperties": false }, "tests": [ { "description": "with no additional properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with additional properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true } ] }, { "description": "unevaluatedProperties with nested properties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "properties": { "bar": { "type": "string" } } } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no additional properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with additional properties", "data": { "foo": "foo", "bar": "bar", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with nested patternProperties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "patternProperties": { "^bar": { "type": "string" } } } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no additional properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with additional properties", "data": { "foo": "foo", "bar": "bar", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with nested additionalProperties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "additionalProperties": true } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no additional properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with additional properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true } ] }, { "description": "unevaluatedProperties with nested unevaluatedProperties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "unevaluatedProperties": true } ], "unevaluatedProperties": { "type": "string", "maxLength": 2 } }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true } ] }, { "description": "unevaluatedProperties with anyOf", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "anyOf": [ { "properties": { "bar": { "const": "bar" } }, "required": ["bar"] }, { "properties": { "baz": { "const": "baz" } }, "required": ["baz"] }, { "properties": { "quux": { "const": "quux" } }, "required": ["quux"] } ], "unevaluatedProperties": false }, "tests": [ { "description": "when one matches and has no unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "when one matches and has unevaluated properties", "data": { "foo": "foo", "bar": "bar", "baz": "not-baz" }, "valid": false }, { "description": "when two match and has no unevaluated properties", "data": { "foo": "foo", "bar": "bar", "baz": "baz" }, "valid": true }, { "description": "when two match and has unevaluated properties", "data": { "foo": "foo", "bar": "bar", "baz": "baz", "quux": "not-quux" }, "valid": false } ] }, { "description": "unevaluatedProperties with oneOf", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "oneOf": [ { "properties": { "bar": { "const": "bar" } }, "required": ["bar"] }, { "properties": { "baz": { "const": "baz" } }, "required": ["baz"] } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar", "quux": "quux" }, "valid": false } ] }, { "description": "unevaluatedProperties with not", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "not": { "not": { "properties": { "bar": { "const": "bar" } }, "required": ["bar"] } }, "unevaluatedProperties": false }, "tests": [ { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "unevaluatedProperties with if/then/else", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "if": { "properties": { "foo": { "const": "then" } }, "required": ["foo"] }, "then": { "properties": { "bar": { "type": "string" } }, "required": ["bar"] }, "else": { "properties": { "baz": { "type": "string" } }, "required": ["baz"] }, "unevaluatedProperties": false }, "tests": [ { "description": "when if is true and has no unevaluated properties", "data": { "foo": "then", "bar": "bar" }, "valid": true }, { "description": "when if is true and has unevaluated properties", "data": { "foo": "then", "bar": "bar", "baz": "baz" }, "valid": false }, { "description": "when if is false and has no unevaluated properties", "data": { "baz": "baz" }, "valid": true }, { "description": "when if is false and has unevaluated properties", "data": { "foo": "else", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with if/then/else, then not defined", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "if": { "properties": { "foo": { "const": "then" } }, "required": ["foo"] }, "else": { "properties": { "baz": { "type": "string" } }, "required": ["baz"] }, "unevaluatedProperties": false }, "tests": [ { "description": "when if is true and has no unevaluated properties", "data": { "foo": "then", "bar": "bar" }, "valid": false }, { "description": "when if is true and has unevaluated properties", "data": { "foo": "then", "bar": "bar", "baz": "baz" }, "valid": false }, { "description": "when if is false and has no unevaluated properties", "data": { "baz": "baz" }, "valid": true }, { "description": "when if is false and has unevaluated properties", "data": { "foo": "else", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with if/then/else, else not defined", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "if": { "properties": { "foo": { "const": "then" } }, "required": ["foo"] }, "then": { "properties": { "bar": { "type": "string" } }, "required": ["bar"] }, "unevaluatedProperties": false }, "tests": [ { "description": "when if is true and has no unevaluated properties", "data": { "foo": "then", "bar": "bar" }, "valid": true }, { "description": "when if is true and has unevaluated properties", "data": { "foo": "then", "bar": "bar", "baz": "baz" }, "valid": false }, { "description": "when if is false and has no unevaluated properties", "data": { "baz": "baz" }, "valid": false }, { "description": "when if is false and has unevaluated properties", "data": { "foo": "else", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with dependentSchemas", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "dependentSchemas": { "foo": { "properties": { "bar": { "const": "bar" } }, "required": ["bar"] } }, "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with unevaluated properties", "data": { "bar": "bar" }, "valid": false } ] }, { "description": "unevaluatedProperties with boolean schemas", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [true], "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with unevaluated properties", "data": { "bar": "bar" }, "valid": false } ] }, { "description": "unevaluatedProperties with $ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "$ref": "#/$defs/bar", "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": false, "$defs": { "bar": { "properties": { "bar": { "type": "string" } } } } }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with $dynamicRef", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://example.com/derived", "$ref": "/baseSchema", "$defs": { "derived": { "$dynamicAnchor": "addons", "properties": { "bar": { "type": "string" } } }, "baseSchema": { "$id": "/baseSchema", "$comment": "unevaluatedProperties comes first so it's more likely to catch bugs with implementations that are sensitive to keyword ordering", "unevaluatedProperties": false, "type": "object", "properties": { "foo": { "type": "string" } }, "$dynamicRef": "#addons", "$defs": { "defaultAddons": { "$comment": "Needed to satisfy the bookending requirement", "$dynamicAnchor": "addons" } } } } }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties can't see inside cousins", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ { "properties": { "foo": true } }, { "unevaluatedProperties": false } ] }, "tests": [ { "description": "always fails", "data": { "foo": 1 }, "valid": false } ] }, { "description": "unevaluatedProperties can't see inside cousins (reverse order)", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ { "unevaluatedProperties": false }, { "properties": { "foo": true } } ] }, "tests": [ { "description": "always fails", "data": { "foo": 1 }, "valid": false } ] }, { "description": "nested unevaluatedProperties, outer false, inner true, properties outside", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "unevaluatedProperties": true } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true } ] }, { "description": "nested unevaluatedProperties, outer false, inner true, properties inside", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "allOf": [ { "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": true } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true } ] }, { "description": "nested unevaluatedProperties, outer true, inner false, properties outside", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "unevaluatedProperties": false } ], "unevaluatedProperties": true }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": false }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "nested unevaluatedProperties, outer true, inner false, properties inside", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "allOf": [ { "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": false } ], "unevaluatedProperties": true }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "cousin unevaluatedProperties, true and false, true with properties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "allOf": [ { "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": true }, { "unevaluatedProperties": false } ] }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": false }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "cousin unevaluatedProperties, true and false, false with properties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "allOf": [ { "unevaluatedProperties": true }, { "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": false } ] }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "property is evaluated in an uncle schema to unevaluatedProperties", "comment": "see https://stackoverflow.com/questions/66936884/deeply-nested-unevaluatedproperties-and-their-expectations", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "foo": { "type": "object", "properties": { "bar": { "type": "string" } }, "unevaluatedProperties": false } }, "anyOf": [ { "properties": { "foo": { "properties": { "faz": { "type": "string" } } } } } ] }, "tests": [ { "description": "no extra properties", "data": { "foo": { "bar": "test" } }, "valid": true }, { "description": "uncle keyword evaluation is not significant", "data": { "foo": { "bar": "test", "faz": "test" } }, "valid": false } ] }, { "description": "in-place applicator siblings, allOf has unevaluated", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "allOf": [ { "properties": { "foo": true }, "unevaluatedProperties": false } ], "anyOf": [ { "properties": { "bar": true } } ] }, "tests": [ { "description": "base case: both properties present", "data": { "foo": 1, "bar": 1 }, "valid": false }, { "description": "in place applicator siblings, bar is missing", "data": { "foo": 1 }, "valid": true }, { "description": "in place applicator siblings, foo is missing", "data": { "bar": 1 }, "valid": false } ] }, { "description": "in-place applicator siblings, anyOf has unevaluated", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "allOf": [ { "properties": { "foo": true } } ], "anyOf": [ { "properties": { "bar": true }, "unevaluatedProperties": false } ] }, "tests": [ { "description": "base case: both properties present", "data": { "foo": 1, "bar": 1 }, "valid": false }, { "description": "in place applicator siblings, bar is missing", "data": { "foo": 1 }, "valid": false }, { "description": "in place applicator siblings, foo is missing", "data": { "bar": 1 }, "valid": true } ] }, { "description": "unevaluatedProperties + single cyclic ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "x": { "$ref": "#" } }, "unevaluatedProperties": false }, "tests": [ { "description": "Empty is valid", "data": {}, "valid": true }, { "description": "Single is valid", "data": { "x": {} }, "valid": true }, { "description": "Unevaluated on 1st level is invalid", "data": { "x": {}, "y": {} }, "valid": false }, { "description": "Nested is valid", "data": { "x": { "x": {} } }, "valid": true }, { "description": "Unevaluated on 2nd level is invalid", "data": { "x": { "x": {}, "y": {} } }, "valid": false }, { "description": "Deep nested is valid", "data": { "x": { "x": { "x": {} } } }, "valid": true }, { "description": "Unevaluated on 3rd level is invalid", "data": { "x": { "x": { "x": {}, "y": {} } } }, "valid": false } ] }, { "description": "unevaluatedProperties + ref inside allOf / oneOf", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "one": { "properties": { "a": true } }, "two": { "required": ["x"], "properties": { "x": true } } }, "allOf": [ { "$ref": "#/$defs/one" }, { "properties": { "b": true } }, { "oneOf": [ { "$ref": "#/$defs/two" }, { "required": ["y"], "properties": { "y": true } } ] } ], "unevaluatedProperties": false }, "tests": [ { "description": "Empty is invalid (no x or y)", "data": {}, "valid": false }, { "description": "a and b are invalid (no x or y)", "data": { "a": 1, "b": 1 }, "valid": false }, { "description": "x and y are invalid", "data": { "x": 1, "y": 1 }, "valid": false }, { "description": "a and x are valid", "data": { "a": 1, "x": 1 }, "valid": true }, { "description": "a and y are valid", "data": { "a": 1, "y": 1 }, "valid": true }, { "description": "a and b and x are valid", "data": { "a": 1, "b": 1, "x": 1 }, "valid": true }, { "description": "a and b and y are valid", "data": { "a": 1, "b": 1, "y": 1 }, "valid": true }, { "description": "a and b and x and y are invalid", "data": { "a": 1, "b": 1, "x": 1, "y": 1 }, "valid": false } ] }, { "description": "dynamic evalation inside nested refs", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "one": { "oneOf": [ { "$ref": "#/$defs/two" }, { "required": ["b"], "properties": { "b": true } }, { "required": ["xx"], "patternProperties": { "x": true } }, { "required": ["all"], "unevaluatedProperties": true } ] }, "two": { "oneOf": [ { "required": ["c"], "properties": { "c": true } }, { "required": ["d"], "properties": { "d": true } } ] } }, "oneOf": [ { "$ref": "#/$defs/one" }, { "required": ["a"], "properties": { "a": true } } ], "unevaluatedProperties": false }, "tests": [ { "description": "Empty is invalid", "data": {}, "valid": false }, { "description": "a is valid", "data": { "a": 1 }, "valid": true }, { "description": "b is valid", "data": { "b": 1 }, "valid": true }, { "description": "c is valid", "data": { "c": 1 }, "valid": true }, { "description": "d is valid", "data": { "d": 1 }, "valid": true }, { "description": "a + b is invalid", "data": { "a": 1, "b": 1 }, "valid": false }, { "description": "a + c is invalid", "data": { "a": 1, "c": 1 }, "valid": false }, { "description": "a + d is invalid", "data": { "a": 1, "d": 1 }, "valid": false }, { "description": "b + c is invalid", "data": { "b": 1, "c": 1 }, "valid": false }, { "description": "b + d is invalid", "data": { "b": 1, "d": 1 }, "valid": false }, { "description": "c + d is invalid", "data": { "c": 1, "d": 1 }, "valid": false }, { "description": "xx is valid", "data": { "xx": 1 }, "valid": true }, { "description": "xx + foox is valid", "data": { "xx": 1, "foox": 1 }, "valid": true }, { "description": "xx + foo is invalid", "data": { "xx": 1, "foo": 1 }, "valid": false }, { "description": "xx + a is invalid", "data": { "xx": 1, "a": 1 }, "valid": false }, { "description": "xx + b is invalid", "data": { "xx": 1, "b": 1 }, "valid": false }, { "description": "xx + c is invalid", "data": { "xx": 1, "c": 1 }, "valid": false }, { "description": "xx + d is invalid", "data": { "xx": 1, "d": 1 }, "valid": false }, { "description": "all is valid", "data": { "all": 1 }, "valid": true }, { "description": "all + foo is valid", "data": { "all": 1, "foo": 1 }, "valid": true }, { "description": "all + a is invalid", "data": { "all": 1, "a": 1 }, "valid": false } ] }, { "description": "non-object instances are valid", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "unevaluatedProperties": false }, "tests": [ { "description": "ignores booleans", "data": true, "valid": true }, { "description": "ignores integers", "data": 123, "valid": true }, { "description": "ignores floats", "data": 1.0, "valid": true }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores strings", "data": "foo", "valid": true }, { "description": "ignores null", "data": null, "valid": true } ] }, { "description": "unevaluatedProperties with null valued instance properties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "unevaluatedProperties": { "type": "null" } }, "tests": [ { "description": "allows null valued properties", "data": {"foo": null}, "valid": true } ] }, { "description": "unevaluatedProperties not affected by propertyNames", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "propertyNames": {"maxLength": 1}, "unevaluatedProperties": { "type": "number" } }, "tests": [ { "description": "allows only number properties", "data": {"a": 1}, "valid": true }, { "description": "string property is invalid", "data": {"a": "b"}, "valid": false } ] }, { "description": "unevaluatedProperties can see annotations from if without then and else", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "if": { "patternProperties": { "foo": { "type": "string" } } }, "unevaluatedProperties": false }, "tests": [ { "description": "valid in case if is evaluated", "data": { "foo": "a" }, "valid": true }, { "description": "invalid in case if is evaluated", "data": { "bar": "a" }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/uniqueItems.json000066400000000000000000000342321477700171100306370ustar00rootroot00000000000000[ { "description": "uniqueItems validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "uniqueItems": true }, "tests": [ { "description": "unique array of integers is valid", "data": [1, 2], "valid": true }, { "description": "non-unique array of integers is invalid", "data": [1, 1], "valid": false }, { "description": "non-unique array of more than two integers is invalid", "data": [1, 2, 1], "valid": false }, { "description": "numbers are unique if mathematically unequal", "data": [1.0, 1.00, 1], "valid": false }, { "description": "false is not equal to zero", "data": [0, false], "valid": true }, { "description": "true is not equal to one", "data": [1, true], "valid": true }, { "description": "unique array of strings is valid", "data": ["foo", "bar", "baz"], "valid": true }, { "description": "non-unique array of strings is invalid", "data": ["foo", "bar", "foo"], "valid": false }, { "description": "unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "baz"}], "valid": true }, { "description": "non-unique array of objects is invalid", "data": [{"foo": "bar"}, {"foo": "bar"}], "valid": false }, { "description": "property order of array of objects is ignored", "data": [{"foo": "bar", "bar": "foo"}, {"bar": "foo", "foo": "bar"}], "valid": false }, { "description": "unique array of nested objects is valid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : false}}} ], "valid": true }, { "description": "non-unique array of nested objects is invalid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : true}}} ], "valid": false }, { "description": "unique array of arrays is valid", "data": [["foo"], ["bar"]], "valid": true }, { "description": "non-unique array of arrays is invalid", "data": [["foo"], ["foo"]], "valid": false }, { "description": "non-unique array of more than two arrays is invalid", "data": [["foo"], ["bar"], ["foo"]], "valid": false }, { "description": "1 and true are unique", "data": [1, true], "valid": true }, { "description": "0 and false are unique", "data": [0, false], "valid": true }, { "description": "[1] and [true] are unique", "data": [[1], [true]], "valid": true }, { "description": "[0] and [false] are unique", "data": [[0], [false]], "valid": true }, { "description": "nested [1] and [true] are unique", "data": [[[1], "foo"], [[true], "foo"]], "valid": true }, { "description": "nested [0] and [false] are unique", "data": [[[0], "foo"], [[false], "foo"]], "valid": true }, { "description": "unique heterogeneous types are valid", "data": [{}, [1], true, null, 1, "{}"], "valid": true }, { "description": "non-unique heterogeneous types are invalid", "data": [{}, [1], true, null, {}, 1], "valid": false }, { "description": "different objects are unique", "data": [{"a": 1, "b": 2}, {"a": 2, "b": 1}], "valid": true }, { "description": "objects are non-unique despite key order", "data": [{"a": 1, "b": 2}, {"b": 2, "a": 1}], "valid": false }, { "description": "{\"a\": false} and {\"a\": 0} are unique", "data": [{"a": false}, {"a": 0}], "valid": true }, { "description": "{\"a\": true} and {\"a\": 1} are unique", "data": [{"a": true}, {"a": 1}], "valid": true } ] }, { "description": "uniqueItems with an array of items", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": true }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is not valid", "data": [false, false], "valid": false }, { "description": "[true, true] from items array is not valid", "data": [true, true], "valid": false }, { "description": "unique array extended from [false, true] is valid", "data": [false, true, "foo", "bar"], "valid": true }, { "description": "unique array extended from [true, false] is valid", "data": [true, false, "foo", "bar"], "valid": true }, { "description": "non-unique array extended from [false, true] is not valid", "data": [false, true, "foo", "foo"], "valid": false }, { "description": "non-unique array extended from [true, false] is not valid", "data": [true, false, "foo", "foo"], "valid": false } ] }, { "description": "uniqueItems with an array of items and additionalItems=false", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": true, "items": false }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is not valid", "data": [false, false], "valid": false }, { "description": "[true, true] from items array is not valid", "data": [true, true], "valid": false }, { "description": "extra items are invalid even if unique", "data": [false, true, null], "valid": false } ] }, { "description": "uniqueItems=false validation", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "uniqueItems": false }, "tests": [ { "description": "unique array of integers is valid", "data": [1, 2], "valid": true }, { "description": "non-unique array of integers is valid", "data": [1, 1], "valid": true }, { "description": "numbers are unique if mathematically unequal", "data": [1.0, 1.00, 1], "valid": true }, { "description": "false is not equal to zero", "data": [0, false], "valid": true }, { "description": "true is not equal to one", "data": [1, true], "valid": true }, { "description": "unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "baz"}], "valid": true }, { "description": "non-unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "bar"}], "valid": true }, { "description": "unique array of nested objects is valid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : false}}} ], "valid": true }, { "description": "non-unique array of nested objects is valid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : true}}} ], "valid": true }, { "description": "unique array of arrays is valid", "data": [["foo"], ["bar"]], "valid": true }, { "description": "non-unique array of arrays is valid", "data": [["foo"], ["foo"]], "valid": true }, { "description": "1 and true are unique", "data": [1, true], "valid": true }, { "description": "0 and false are unique", "data": [0, false], "valid": true }, { "description": "unique heterogeneous types are valid", "data": [{}, [1], true, null, 1], "valid": true }, { "description": "non-unique heterogeneous types are valid", "data": [{}, [1], true, null, {}, 1], "valid": true } ] }, { "description": "uniqueItems=false with an array of items", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": false }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is valid", "data": [false, false], "valid": true }, { "description": "[true, true] from items array is valid", "data": [true, true], "valid": true }, { "description": "unique array extended from [false, true] is valid", "data": [false, true, "foo", "bar"], "valid": true }, { "description": "unique array extended from [true, false] is valid", "data": [true, false, "foo", "bar"], "valid": true }, { "description": "non-unique array extended from [false, true] is valid", "data": [false, true, "foo", "foo"], "valid": true }, { "description": "non-unique array extended from [true, false] is valid", "data": [true, false, "foo", "foo"], "valid": true } ] }, { "description": "uniqueItems=false with an array of items and additionalItems=false", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": false, "items": false }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is valid", "data": [false, false], "valid": true }, { "description": "[true, true] from items array is valid", "data": [true, true], "valid": true }, { "description": "extra items are invalid even if unique", "data": [false, true, null], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/unknownKeyword.json000066400000000000000000000041131477700171100313660ustar00rootroot00000000000000[ { "description": "$id inside an unknown keyword is not a real identifier", "comment": "the implementation must not be confused by an $id in locations we do not know how to parse", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "id_in_unknown0": { "not": { "array_of_schemas": [ { "$id": "https://localhost:1234/draft2020-12/unknownKeyword/my_identifier.json", "type": "null" } ] } }, "real_id_in_schema": { "$id": "https://localhost:1234/draft2020-12/unknownKeyword/my_identifier.json", "type": "string" }, "id_in_unknown1": { "not": { "object_of_schemas": { "foo": { "$id": "https://localhost:1234/draft2020-12/unknownKeyword/my_identifier.json", "type": "integer" } } } } }, "anyOf": [ { "$ref": "#/$defs/id_in_unknown0" }, { "$ref": "#/$defs/id_in_unknown1" }, { "$ref": "https://localhost:1234/draft2020-12/unknownKeyword/my_identifier.json" } ] }, "tests": [ { "description": "type matches second anyOf, which has a real schema in it", "data": "a string", "valid": true }, { "description": "type matches non-schema in first anyOf", "data": null, "valid": false }, { "description": "type matches non-schema in third anyOf", "data": 1, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/vocabulary.json000066400000000000000000000032521477700171100304740ustar00rootroot00000000000000[ { "description": "schema that uses custom metaschema with with no validation vocabulary", "schema": { "$id": "https://schema/using/no/validation", "$schema": "http://localhost:1234/draft2020-12/metaschema-no-validation.json", "properties": { "badProperty": false, "numberProperty": { "minimum": 10 } } }, "tests": [ { "description": "applicator vocabulary still works", "data": { "badProperty": "this property should not exist" }, "valid": false }, { "description": "no validation: valid number", "data": { "numberProperty": 20 }, "valid": true }, { "description": "no validation: invalid number, but it still validates", "data": { "numberProperty": 1 }, "valid": true } ] }, { "description": "ignore unrecognized optional vocabulary", "schema": { "$schema": "http://localhost:1234/draft2020-12/metaschema-optional-vocabulary.json", "type": "number" }, "tests": [ { "description": "string value", "data": "foobar", "valid": false }, { "description": "number value", "data": 20, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/000077500000000000000000000000001477700171100247675ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/additionalItems.json000066400000000000000000000100051477700171100307700ustar00rootroot00000000000000[ { "description": "additionalItems as schema", "schema": { "items": [], "additionalItems": {"type": "integer"} }, "tests": [ { "description": "additional items match schema", "data": [ 1, 2, 3, 4 ], "valid": true }, { "description": "additional items do not match schema", "data": [ 1, 2, 3, "foo" ], "valid": false } ] }, { "description": "when items is schema, additionalItems does nothing", "schema": { "items": {}, "additionalItems": false }, "tests": [ { "description": "all items match schema", "data": [ 1, 2, 3, 4, 5 ], "valid": true } ] }, { "description": "array of items with no additionalItems permitted", "schema": { "items": [{}, {}, {}], "additionalItems": false }, "tests": [ { "description": "empty array", "data": [ ], "valid": true }, { "description": "fewer number of items present (1)", "data": [ 1 ], "valid": true }, { "description": "fewer number of items present (2)", "data": [ 1, 2 ], "valid": true }, { "description": "equal number of items present", "data": [ 1, 2, 3 ], "valid": true }, { "description": "additional items are not permitted", "data": [ 1, 2, 3, 4 ], "valid": false } ] }, { "description": "additionalItems as false without items", "schema": {"additionalItems": false}, "tests": [ { "description": "items defaults to empty schema so everything is valid", "data": [ 1, 2, 3, 4, 5 ], "valid": true }, { "description": "ignores non-arrays", "data": {"foo" : "bar"}, "valid": true } ] }, { "description": "additionalItems are allowed by default", "schema": {"items": [{"type": "integer"}]}, "tests": [ { "description": "only the first item is validated", "data": [1, "foo", false], "valid": true } ] }, { "description": "additionalItems does not look in applicators", "schema": { "extends": [ { "items": [ { "type": "integer" } ] } ], "additionalItems": { "type": "boolean" } }, "tests": [ { "description": "items defined in extends are not examined", "data": [ 1, null ], "valid": true } ] }, { "description": "additionalItems with heterogeneous array", "schema": { "items": [{}], "additionalItems": false }, "tests": [ { "description": "heterogeneous invalid instance", "data": [ "foo", "bar", 37 ], "valid": false }, { "description": "valid instance", "data": [ null ], "valid": true } ] }, { "description": "additionalItems with null instance elements", "schema": { "additionalItems": { "type": "null" } }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/additionalProperties.json000066400000000000000000000105161477700171100320520ustar00rootroot00000000000000[ { "description": "additionalProperties being false does not allow other properties", "schema": { "properties": {"foo": {}, "bar": {}}, "patternProperties": { "^v": {} }, "additionalProperties": false }, "tests": [ { "description": "no additional properties is valid", "data": {"foo": 1}, "valid": true }, { "description": "an additional property is invalid", "data": {"foo" : 1, "bar" : 2, "quux" : "boom"}, "valid": false }, { "description": "ignores arrays", "data": [1, 2, 3], "valid": true }, { "description": "ignores strings", "data": "foobarbaz", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true }, { "description": "patternProperties are not additional properties", "data": {"foo":1, "vroom": 2}, "valid": true } ] }, { "description": "non-ASCII pattern with additionalProperties", "schema": { "patternProperties": {"^á": {}}, "additionalProperties": false }, "tests": [ { "description": "matching the pattern is valid", "data": {"ármányos": 2}, "valid": true }, { "description": "not matching the pattern is invalid", "data": {"élmény": 2}, "valid": false } ] }, { "description": "additionalProperties with schema", "schema": { "properties": {"foo": {}, "bar": {}}, "additionalProperties": {"type": "boolean"} }, "tests": [ { "description": "no additional properties is valid", "data": {"foo": 1}, "valid": true }, { "description": "an additional valid property is valid", "data": {"foo" : 1, "bar" : 2, "quux" : true}, "valid": true }, { "description": "an additional invalid property is invalid", "data": {"foo" : 1, "bar" : 2, "quux" : 12}, "valid": false } ] }, { "description": "additionalProperties can exist by itself", "schema": { "additionalProperties": {"type": "boolean"} }, "tests": [ { "description": "an additional valid property is valid", "data": {"foo" : true}, "valid": true }, { "description": "an additional invalid property is invalid", "data": {"foo" : 1}, "valid": false } ] }, { "description": "additionalProperties are allowed by default", "schema": {"properties": {"foo": {}, "bar": {}}}, "tests": [ { "description": "additional properties are allowed", "data": {"foo": 1, "bar": 2, "quux": true}, "valid": true } ] }, { "description": "additionalProperties does not look in applicators", "schema": { "extends": [ {"properties": {"foo": {}}} ], "additionalProperties": {"type": "boolean"} }, "tests": [ { "description": "properties defined in extends are not examined", "data": {"foo": 1, "bar": true}, "valid": false } ] }, { "description": "additionalProperties with null valued instance properties", "schema": { "additionalProperties": { "type": "null" } }, "tests": [ { "description": "allows null values", "data": {"foo": null}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/default.json000066400000000000000000000042671477700171100273170ustar00rootroot00000000000000[ { "description": "invalid type for default", "schema": { "properties": { "foo": { "type": "integer", "default": [] } } }, "tests": [ { "description": "valid when property is specified", "data": {"foo": 13}, "valid": true }, { "description": "still valid when the invalid default is used", "data": {}, "valid": true } ] }, { "description": "invalid string value for default", "schema": { "properties": { "bar": { "type": "string", "minLength": 4, "default": "bad" } } }, "tests": [ { "description": "valid when property is specified", "data": {"bar": "good"}, "valid": true }, { "description": "still valid when the invalid default is used", "data": {}, "valid": true } ] }, { "description": "the default keyword does not do anything if the property is missing", "schema": { "type": "object", "properties": { "alpha": { "type": "number", "maximum": 3, "default": 5 } } }, "tests": [ { "description": "an explicit property value is checked against maximum (passing)", "data": { "alpha": 1 }, "valid": true }, { "description": "an explicit property value is checked against maximum (failing)", "data": { "alpha": 5 }, "valid": false }, { "description": "missing properties are not filled in with the default", "data": {}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/dependencies.json000066400000000000000000000065401477700171100303150ustar00rootroot00000000000000[ { "description": "dependencies", "schema": { "dependencies": {"bar": "foo"} }, "tests": [ { "description": "neither", "data": {}, "valid": true }, { "description": "nondependant", "data": {"foo": 1}, "valid": true }, { "description": "with dependency", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "missing dependency", "data": {"bar": 2}, "valid": false }, { "description": "ignores arrays", "data": ["bar"], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "multiple dependencies", "schema": { "dependencies": {"quux": ["foo", "bar"]} }, "tests": [ { "description": "neither", "data": {}, "valid": true }, { "description": "nondependants", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "with dependencies", "data": {"foo": 1, "bar": 2, "quux": 3}, "valid": true }, { "description": "missing dependency", "data": {"foo": 1, "quux": 2}, "valid": false }, { "description": "missing other dependency", "data": {"bar": 1, "quux": 2}, "valid": false }, { "description": "missing both dependencies", "data": {"quux": 1}, "valid": false } ] }, { "description": "multiple dependencies subschema", "schema": { "dependencies": { "bar": { "properties": { "foo": {"type": "integer"}, "bar": {"type": "integer"} } } } }, "tests": [ { "description": "valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "no dependency", "data": {"foo": "quux"}, "valid": true }, { "description": "wrong type", "data": {"foo": "quux", "bar": 2}, "valid": false }, { "description": "wrong type other", "data": {"foo": 2, "bar": "quux"}, "valid": false }, { "description": "wrong type both", "data": {"foo": "quux", "bar": "quux"}, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/disallow.json000066400000000000000000000036201477700171100275010ustar00rootroot00000000000000[ { "description": "disallow", "schema": { "disallow": "integer" }, "tests": [ { "description": "allowed", "data": "foo", "valid": true }, { "description": "disallowed", "data": 1, "valid": false } ] }, { "description": "multiple disallow", "schema": { "disallow": ["integer", "boolean"] }, "tests": [ { "description": "valid", "data": "foo", "valid": true }, { "description": "mismatch", "data": 1, "valid": false }, { "description": "other mismatch", "data": true, "valid": false } ] }, { "description": "multiple disallow subschema", "schema": { "disallow": ["string", { "type": "object", "properties": { "foo": { "type": "string" } } }] }, "tests": [ { "description": "match", "data": 1, "valid": true }, { "description": "other match", "data": {"foo": 1}, "valid": true }, { "description": "mismatch", "data": "foo", "valid": false }, { "description": "other mismatch", "data": {"foo": "bar"}, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/divisibleBy.json000066400000000000000000000030101477700171100301210ustar00rootroot00000000000000[ { "description": "by int", "schema": {"divisibleBy": 2}, "tests": [ { "description": "int by int", "data": 10, "valid": true }, { "description": "int by int fail", "data": 7, "valid": false }, { "description": "ignores non-numbers", "data": "foo", "valid": true } ] }, { "description": "by number", "schema": {"divisibleBy": 1.5}, "tests": [ { "description": "zero is divisible by anything (except 0)", "data": 0, "valid": true }, { "description": "4.5 is divisible by 1.5", "data": 4.5, "valid": true }, { "description": "35 is not divisible by 1.5", "data": 35, "valid": false } ] }, { "description": "by small number", "schema": {"divisibleBy": 0.0001}, "tests": [ { "description": "0.0075 is divisible by 0.0001", "data": 0.0075, "valid": true }, { "description": "0.00751 is not divisible by 0.0001", "data": 0.00751, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/enum.json000066400000000000000000000064401477700171100266320ustar00rootroot00000000000000[ { "description": "simple enum validation", "schema": {"enum": [1, 2, 3]}, "tests": [ { "description": "one of the enum is valid", "data": 1, "valid": true }, { "description": "something else is invalid", "data": 4, "valid": false } ] }, { "description": "heterogeneous enum validation", "schema": {"enum": [6, "foo", [], true, {"foo": 12}]}, "tests": [ { "description": "one of the enum is valid", "data": [], "valid": true }, { "description": "something else is invalid", "data": null, "valid": false }, { "description": "objects are deep compared", "data": {"foo": false}, "valid": false } ] }, { "description": "heterogeneous enum-with-null validation", "schema": { "enum": [6, null] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "number is valid", "data": 6, "valid": true }, { "description": "something else is invalid", "data": "test", "valid": false } ] }, { "description": "enums in properties", "schema": { "type":"object", "properties": { "foo": {"enum":["foo"]}, "bar": {"enum":["bar"], "required":true} } }, "tests": [ { "description": "both properties are valid", "data": {"foo":"foo", "bar":"bar"}, "valid": true }, { "description": "wrong foo value", "data": {"foo":"foot", "bar":"bar"}, "valid": false }, { "description": "wrong bar value", "data": {"foo":"foo", "bar":"bart"}, "valid": false }, { "description": "missing optional property is valid", "data": {"bar":"bar"}, "valid": true }, { "description": "missing required property is invalid", "data": {"foo":"foo"}, "valid": false }, { "description": "missing all properties is invalid", "data": {}, "valid": false } ] }, { "description": "nul characters in strings", "schema": { "enum": [ "hello\u0000there" ] }, "tests": [ { "description": "match string with nul", "data": "hello\u0000there", "valid": true }, { "description": "do not match string lacking nul", "data": "hellothere", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/extends.json000066400000000000000000000050371477700171100273410ustar00rootroot00000000000000[ { "description": "extends", "schema": { "properties": {"bar": {"type": "integer", "required": true}}, "extends": { "properties": { "foo": {"type": "string", "required": true} } } }, "tests": [ { "description": "extends", "data": {"foo": "baz", "bar": 2}, "valid": true }, { "description": "mismatch extends", "data": {"foo": "baz"}, "valid": false }, { "description": "mismatch extended", "data": {"bar": 2}, "valid": false }, { "description": "wrong type", "data": {"foo": "baz", "bar": "quux"}, "valid": false } ] }, { "description": "multiple extends", "schema": { "properties": {"bar": {"type": "integer", "required": true}}, "extends" : [ { "properties": { "foo": {"type": "string", "required": true} } }, { "properties": { "baz": {"type": "null", "required": true} } } ] }, "tests": [ { "description": "valid", "data": {"foo": "quux", "bar": 2, "baz": null}, "valid": true }, { "description": "mismatch first extends", "data": {"bar": 2, "baz": null}, "valid": false }, { "description": "mismatch second extends", "data": {"foo": "quux", "bar": 2}, "valid": false }, { "description": "mismatch both", "data": {"bar": 2}, "valid": false } ] }, { "description": "extends simple types", "schema": { "minimum": 20, "extends": {"maximum": 30} }, "tests": [ { "description": "valid", "data": 25, "valid": true }, { "description": "mismatch extends", "data": 35, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/format.json000066400000000000000000000245231477700171100271600ustar00rootroot00000000000000[ { "description": "email format", "schema": { "format": "email" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "ip-address format", "schema": { "format": "ip-address" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "ipv6 format", "schema": { "format": "ipv6" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "host-name format", "schema": { "format": "host-name" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "date-time format", "schema": { "format": "date-time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "regex format", "schema": { "format": "regex" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "date format", "schema": { "format": "date" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "time format", "schema": { "format": "time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "color format", "schema": { "format": "color" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "uri format", "schema": { "format": "uri" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/infinite-loop-detection.json000066400000000000000000000015541477700171100324170ustar00rootroot00000000000000[ { "description": "evaluating the same schema location against the same data location twice is not a sign of an infinite loop", "schema": { "definitions": { "int": { "type": "integer" } }, "properties": { "foo": { "$ref": "#/definitions/int" } }, "extends": { "additionalProperties": { "$ref": "#/definitions/int" } } }, "tests": [ { "description": "passing case", "data": { "foo": 1 }, "valid": true }, { "description": "failing case", "data": { "foo": "a string" }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/items.json000066400000000000000000000035331477700171100270070ustar00rootroot00000000000000[ { "description": "a schema given for items", "schema": { "items": {"type": "integer"} }, "tests": [ { "description": "valid items", "data": [ 1, 2, 3 ], "valid": true }, { "description": "wrong type of items", "data": [1, "x"], "valid": false }, { "description": "ignores non-arrays", "data": {"foo" : "bar"}, "valid": true } ] }, { "description": "an array of schemas for items", "schema": { "items": [ {"type": "integer"}, {"type": "string"} ] }, "tests": [ { "description": "correct types", "data": [ 1, "foo" ], "valid": true }, { "description": "wrong types", "data": [ "foo", 1 ], "valid": false } ] }, { "description": "items with null instance elements", "schema": { "items": { "type": "null" } }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] }, { "description": "array-form items with null instance elements", "schema": { "items": [ { "type": "null" } ] }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/maxItems.json000066400000000000000000000013021477700171100274450ustar00rootroot00000000000000[ { "description": "maxItems validation", "schema": {"maxItems": 2}, "tests": [ { "description": "shorter is valid", "data": [1], "valid": true }, { "description": "exact length is valid", "data": [1, 2], "valid": true }, { "description": "too long is invalid", "data": [1, 2, 3], "valid": false }, { "description": "ignores non-arrays", "data": "foobar", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/maxLength.json000066400000000000000000000015771477700171100276230ustar00rootroot00000000000000[ { "description": "maxLength validation", "schema": {"maxLength": 2}, "tests": [ { "description": "shorter is valid", "data": "f", "valid": true }, { "description": "exact length is valid", "data": "fo", "valid": true }, { "description": "too long is invalid", "data": "foo", "valid": false }, { "description": "ignores non-strings", "data": 10, "valid": true }, { "description": "two supplementary Unicode code points is long enough", "data": "\uD83D\uDCA9\uD83D\uDCA9", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/maximum.json000066400000000000000000000052621477700171100273440ustar00rootroot00000000000000[ { "description": "maximum validation", "schema": {"maximum": 3.0}, "tests": [ { "description": "below the maximum is valid", "data": 2.6, "valid": true }, { "description": "boundary point is valid", "data": 3.0, "valid": true }, { "description": "above the maximum is invalid", "data": 3.5, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] }, { "description": "maximum validation with unsigned integer", "schema": {"maximum": 300}, "tests": [ { "description": "below the maximum is invalid", "data": 299.97, "valid": true }, { "description": "boundary point integer is valid", "data": 300, "valid": true }, { "description": "boundary point float is valid", "data": 300.00, "valid": true }, { "description": "above the maximum is invalid", "data": 300.5, "valid": false } ] }, { "description": "maximum validation (explicit false exclusivity)", "schema": {"maximum": 3.0, "exclusiveMaximum": false}, "tests": [ { "description": "below the maximum is valid", "data": 2.6, "valid": true }, { "description": "boundary point is valid", "data": 3.0, "valid": true }, { "description": "above the maximum is invalid", "data": 3.5, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] }, { "description": "exclusiveMaximum validation", "schema": { "maximum": 3.0, "exclusiveMaximum": true }, "tests": [ { "description": "below the maximum is still valid", "data": 2.2, "valid": true }, { "description": "boundary point is invalid", "data": 3.0, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/minItems.json000066400000000000000000000012651477700171100274530ustar00rootroot00000000000000[ { "description": "minItems validation", "schema": {"minItems": 1}, "tests": [ { "description": "longer is valid", "data": [1, 2], "valid": true }, { "description": "exact length is valid", "data": [1], "valid": true }, { "description": "too short is invalid", "data": [], "valid": false }, { "description": "ignores non-arrays", "data": "", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/minLength.json000066400000000000000000000015661477700171100276170ustar00rootroot00000000000000[ { "description": "minLength validation", "schema": {"minLength": 2}, "tests": [ { "description": "longer is valid", "data": "foo", "valid": true }, { "description": "exact length is valid", "data": "fo", "valid": true }, { "description": "too short is invalid", "data": "f", "valid": false }, { "description": "ignores non-strings", "data": 1, "valid": true }, { "description": "one supplementary Unicode code point is not long enough", "data": "\uD83D\uDCA9", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/minimum.json000066400000000000000000000045711477700171100273440ustar00rootroot00000000000000[ { "description": "minimum validation", "schema": {"minimum": 1.1}, "tests": [ { "description": "above the minimum is valid", "data": 2.6, "valid": true }, { "description": "boundary point is valid", "data": 1.1, "valid": true }, { "description": "below the minimum is invalid", "data": 0.6, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] }, { "description": "exclusiveMinimum validation", "schema": { "minimum": 1.1, "exclusiveMinimum": true }, "tests": [ { "description": "above the minimum is still valid", "data": 1.2, "valid": true }, { "description": "boundary point is invalid", "data": 1.1, "valid": false } ] }, { "description": "minimum validation with signed integer", "schema": {"minimum": -2}, "tests": [ { "description": "negative above the minimum is valid", "data": -1, "valid": true }, { "description": "positive above the minimum is valid", "data": 0, "valid": true }, { "description": "boundary point is valid", "data": -2, "valid": true }, { "description": "boundary point with float is valid", "data": -2.0, "valid": true }, { "description": "float below the minimum is invalid", "data": -2.0001, "valid": false }, { "description": "int below the minimum is invalid", "data": -3, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/optional/000077500000000000000000000000001477700171100266145ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/optional/bignum.json000066400000000000000000000054731477700171100310010ustar00rootroot00000000000000[ { "description": "integer", "schema": { "type": "integer" }, "tests": [ { "description": "a bignum is an integer", "data": 12345678910111213141516171819202122232425262728293031, "valid": true }, { "description": "a negative bignum is an integer", "data": -12345678910111213141516171819202122232425262728293031, "valid": true } ] }, { "description": "number", "schema": { "type": "number" }, "tests": [ { "description": "a bignum is a number", "data": 98249283749234923498293171823948729348710298301928331, "valid": true }, { "description": "a negative bignum is a number", "data": -98249283749234923498293171823948729348710298301928331, "valid": true } ] }, { "description": "string", "schema": { "type": "string" }, "tests": [ { "description": "a bignum is not a string", "data": 98249283749234923498293171823948729348710298301928331, "valid": false } ] }, { "description": "maximum integer comparison", "schema": { "maximum": 18446744073709551615 }, "tests": [ { "description": "comparison works for high numbers", "data": 18446744073709551600, "valid": true } ] }, { "description": "float comparison with high precision", "schema": { "maximum": 972783798187987123879878123.18878137, "exclusiveMaximum": true }, "tests": [ { "description": "comparison works for high numbers", "data": 972783798187987123879878123.188781371, "valid": false } ] }, { "description": "minimum integer comparison", "schema": { "minimum": -18446744073709551615 }, "tests": [ { "description": "comparison works for very negative numbers", "data": -18446744073709551600, "valid": true } ] }, { "description": "float comparison with high precision on negative numbers", "schema": { "minimum": -972783798187987123879878123.18878137, "exclusiveMinimum": true }, "tests": [ { "description": "comparison works for very negative numbers", "data": -972783798187987123879878123.188781371, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/optional/ecmascript-regex.json000066400000000000000000000007171477700171100327560ustar00rootroot00000000000000[ { "description": "ECMA 262 regex dialect recognition", "schema": { "format": "regex" }, "tests": [ { "description": "[^] is a valid regex", "data": "[^]", "valid": true }, { "description": "ECMA 262 has no support for lookbehind", "data": "(?<=foo)bar", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/optional/format/000077500000000000000000000000001477700171100301045ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/optional/format/color.json000066400000000000000000000021261477700171100321160ustar00rootroot00000000000000[ { "description": "validation of CSS colors", "schema": { "format": "color" }, "tests": [ { "description": "a valid CSS color name", "data": "fuchsia", "valid": true }, { "description": "a valid six-digit CSS color code", "data": "#CC8899", "valid": true }, { "description": "a valid three-digit CSS color code", "data": "#C89", "valid": true }, { "description": "an invalid CSS color code", "data": "#00332520", "valid": false }, { "description": "an invalid CSS color name", "data": "puce", "valid": false }, { "description": "a CSS color name containing invalid characters", "data": "light_grayish_red-violet", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/optional/format/date-time.json000066400000000000000000000022641477700171100326540ustar00rootroot00000000000000[ { "description": "validation of date-time strings", "schema": { "format": "date-time" }, "tests": [ { "description": "a valid date-time string", "data": "1963-06-19T08:30:06.283185Z", "valid": true }, { "description": "an invalid date-time string", "data": "06/19/1963 08:30:06 PST", "valid": false }, { "description": "case-insensitive T and Z", "data": "1963-06-19t08:30:06.283185z", "valid": true }, { "description": "only RFC3339 not all of ISO 8601 are valid", "data": "2013-350T01:01:01", "valid": false }, { "description": "invalid non-padded month dates", "data": "1963-6-19T08:30:06.283185Z", "valid": false }, { "description": "invalid non-padded day dates", "data": "1963-06-1T08:30:06.283185Z", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/optional/format/date.json000066400000000000000000000131321477700171100317140ustar00rootroot00000000000000[ { "description": "validation of date strings", "schema": { "format": "date" }, "tests": [ { "description": "a valid date string", "data": "1963-06-19", "valid": true }, { "description": "a valid date string with 31 days in January", "data": "2020-01-31", "valid": true }, { "description": "a invalid date string with 32 days in January", "data": "2020-01-32", "valid": false }, { "description": "a valid date string with 28 days in February (normal)", "data": "2021-02-28", "valid": true }, { "description": "a invalid date string with 29 days in February (normal)", "data": "2021-02-29", "valid": false }, { "description": "a valid date string with 29 days in February (leap)", "data": "2020-02-29", "valid": true }, { "description": "a invalid date string with 30 days in February (leap)", "data": "2020-02-30", "valid": false }, { "description": "a valid date string with 31 days in March", "data": "2020-03-31", "valid": true }, { "description": "a invalid date string with 32 days in March", "data": "2020-03-32", "valid": false }, { "description": "a valid date string with 30 days in April", "data": "2020-04-30", "valid": true }, { "description": "a invalid date string with 31 days in April", "data": "2020-04-31", "valid": false }, { "description": "a valid date string with 31 days in May", "data": "2020-05-31", "valid": true }, { "description": "a invalid date string with 32 days in May", "data": "2020-05-32", "valid": false }, { "description": "a valid date string with 30 days in June", "data": "2020-06-30", "valid": true }, { "description": "a invalid date string with 31 days in June", "data": "2020-06-31", "valid": false }, { "description": "a valid date string with 31 days in July", "data": "2020-07-31", "valid": true }, { "description": "a invalid date string with 32 days in July", "data": "2020-07-32", "valid": false }, { "description": "a valid date string with 31 days in August", "data": "2020-08-31", "valid": true }, { "description": "a invalid date string with 32 days in August", "data": "2020-08-32", "valid": false }, { "description": "a valid date string with 30 days in September", "data": "2020-09-30", "valid": true }, { "description": "a invalid date string with 31 days in September", "data": "2020-09-31", "valid": false }, { "description": "a valid date string with 31 days in October", "data": "2020-10-31", "valid": true }, { "description": "a invalid date string with 32 days in October", "data": "2020-10-32", "valid": false }, { "description": "a valid date string with 30 days in November", "data": "2020-11-30", "valid": true }, { "description": "a invalid date string with 31 days in November", "data": "2020-11-31", "valid": false }, { "description": "a valid date string with 31 days in December", "data": "2020-12-31", "valid": true }, { "description": "a invalid date string with 32 days in December", "data": "2020-12-32", "valid": false }, { "description": "a invalid date string with invalid month", "data": "2020-13-01", "valid": false }, { "description": "an invalid date string", "data": "06/19/1963", "valid": false }, { "description": "only RFC3339 not all of ISO 8601 are valid", "data": "2013-350", "valid": false }, { "description": "invalidates non-padded month dates", "data": "1998-1-20", "valid": false }, { "description": "invalidates non-padded day dates", "data": "1998-01-1", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/optional/format/email.json000066400000000000000000000032351477700171100320710ustar00rootroot00000000000000[ { "description": "validation of e-mail addresses", "schema": { "format": "email" }, "tests": [ { "description": "a valid e-mail address", "data": "joe.bloggs@example.com", "valid": true }, { "description": "an invalid e-mail address", "data": "2962", "valid": false }, { "description": "tilde in local part is valid", "data": "te~st@example.com", "valid": true }, { "description": "tilde before local part is valid", "data": "~test@example.com", "valid": true }, { "description": "tilde after local part is valid", "data": "test~@example.com", "valid": true }, { "description": "dot before local part is not valid", "data": ".test@example.com", "valid": false }, { "description": "dot after local part is not valid", "data": "test.@example.com", "valid": false }, { "description": "two separated dots inside local part are valid", "data": "te.s.t@example.com", "valid": true }, { "description": "two subsequent dots inside local part are not valid", "data": "te..st@example.com", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/optional/format/host-name.json000066400000000000000000000041011477700171100326660ustar00rootroot00000000000000[ { "description": "validation of host names", "schema": { "format": "host-name" }, "tests": [ { "description": "a valid host name", "data": "www.example.com", "valid": true }, { "description": "a host name starting with an illegal character", "data": "-a-host-name-that-starts-with--", "valid": false }, { "description": "a host name containing illegal characters", "data": "not_a_valid_host_name", "valid": false }, { "description": "a host name with a component too long", "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", "valid": false }, { "description": "starts with hyphen", "data": "-hostname", "valid": false }, { "description": "ends with hyphen", "data": "hostname-", "valid": false }, { "description": "starts with underscore", "data": "_hostname", "valid": false }, { "description": "ends with underscore", "data": "hostname_", "valid": false }, { "description": "contains underscore", "data": "host_name", "valid": false }, { "description": "maximum label length", "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.com", "valid": true }, { "description": "exceeds maximum label length", "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl.com", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/optional/format/ip-address.json000066400000000000000000000012021477700171100330250ustar00rootroot00000000000000[ { "description": "validation of IP addresses", "schema": { "format": "ip-address" }, "tests": [ { "description": "a valid IP address", "data": "192.168.0.1", "valid": true }, { "description": "an IP address with too many components", "data": "127.0.0.0.1", "valid": false }, { "description": "an IP address with out-of-range values", "data": "256.256.256.256", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/optional/format/ipv6.json000066400000000000000000000042231477700171100316640ustar00rootroot00000000000000[ { "description": "validation of IPv6 addresses", "schema": { "format": "ipv6" }, "tests": [ { "description": "a valid IPv6 address", "data": "::1", "valid": true }, { "description": "an IPv6 address with out-of-range values", "data": "12345::", "valid": false }, { "description": "an IPv6 address with too many components", "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", "valid": false }, { "description": "an IPv6 address containing illegal characters", "data": "::laptop", "valid": false }, { "description": "no digits is valid", "data": "::", "valid": true }, { "description": "leading colons is valid", "data": "::1", "valid": true }, { "description": "trailing colons is valid", "data": "d6::", "valid": true }, { "description": "two sets of double colons is invalid", "data": "1::d6::42", "valid": false }, { "description": "mixed format with the ipv4 section as decimal octets", "data": "1::d6:192.168.0.1", "valid": true }, { "description": "mixed format with double colons between the sections", "data": "1:2::192.168.0.1", "valid": true }, { "description": "mixed format with ipv4 section with octet out of range", "data": "1::2:192.168.256.1", "valid": false }, { "description": "mixed format with ipv4 section with a hex octet", "data": "1::2:192.168.ff.1", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/optional/format/regex.json000066400000000000000000000007471477700171100321210ustar00rootroot00000000000000[ { "description": "validation of regular expressions", "schema": { "format": "regex" }, "tests": [ { "description": "a valid regular expression", "data": "([abc])+\\s+$", "valid": true }, { "description": "a regular expression with unclosed parens is invalid", "data": "^(abc]", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/optional/format/time.json000066400000000000000000000006661477700171100317450ustar00rootroot00000000000000[ { "description": "validation of time strings", "schema": { "format": "time" }, "tests": [ { "description": "a valid time string", "data": "08:30:06", "valid": true }, { "description": "an invalid time string", "data": "8:30 AM", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/optional/format/uri.json000066400000000000000000000014431477700171100316000ustar00rootroot00000000000000[ { "description": "validation of URIs", "schema": { "format": "uri" }, "tests": [ { "description": "a valid URI", "data": "http://foo.bar/?baz=qux#quux", "valid": true }, { "description": "an invalid protocol-relative URI Reference", "data": "//foo.bar/?baz=qux#quux", "valid": false }, { "description": "an invalid URI", "data": "\\\\WINDOWS\\fileshare", "valid": false }, { "description": "an invalid URI though valid URI reference", "data": "abc", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/optional/non-bmp-regex.json000066400000000000000000000045361477700171100321750ustar00rootroot00000000000000[ { "description": "Proper UTF-16 surrogate pair handling: pattern", "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", "schema": { "pattern": "^🐲*$" }, "tests": [ { "description": "matches empty", "data": "", "valid": true }, { "description": "matches single", "data": "🐲", "valid": true }, { "description": "matches two", "data": "🐲🐲", "valid": true }, { "description": "doesn't match one", "data": "🐉", "valid": false }, { "description": "doesn't match two", "data": "🐉🐉", "valid": false }, { "description": "doesn't match one ASCII", "data": "D", "valid": false }, { "description": "doesn't match two ASCII", "data": "DD", "valid": false } ] }, { "description": "Proper UTF-16 surrogate pair handling: patternProperties", "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", "schema": { "patternProperties": { "^🐲*$": { "type": "integer" } } }, "tests": [ { "description": "matches empty", "data": { "": 1 }, "valid": true }, { "description": "matches single", "data": { "🐲": 1 }, "valid": true }, { "description": "matches two", "data": { "🐲🐲": 1 }, "valid": true }, { "description": "doesn't match one", "data": { "🐲": "hello" }, "valid": false }, { "description": "doesn't match two", "data": { "🐲🐲": "hello" }, "valid": false } ] } ] zeroTerminatedFloats.json000066400000000000000000000006001477700171100335710ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/optional[ { "description": "some languages do not distinguish between different types of numeric value", "schema": { "type": "integer" }, "tests": [ { "description": "a float is not an integer even without fractional part", "data": 1.0, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/pattern.json000066400000000000000000000030031477700171100273330ustar00rootroot00000000000000[ { "description": "pattern validation", "schema": {"pattern": "^a*$"}, "tests": [ { "description": "a matching pattern is valid", "data": "aaa", "valid": true }, { "description": "a non-matching pattern is invalid", "data": "abc", "valid": false }, { "description": "ignores booleans", "data": true, "valid": true }, { "description": "ignores integers", "data": 123, "valid": true }, { "description": "ignores floats", "data": 1.0, "valid": true }, { "description": "ignores objects", "data": {}, "valid": true }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores null", "data": null, "valid": true } ] }, { "description": "pattern is not anchored", "schema": {"pattern": "a+"}, "tests": [ { "description": "matches a substring", "data": "xxaayy", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/patternProperties.json000066400000000000000000000075031477700171100314210ustar00rootroot00000000000000[ { "description": "patternProperties validates properties matching a regex", "schema": { "patternProperties": { "f.*o": {"type": "integer"} } }, "tests": [ { "description": "a single valid match is valid", "data": {"foo": 1}, "valid": true }, { "description": "multiple valid matches is valid", "data": {"foo": 1, "foooooo" : 2}, "valid": true }, { "description": "a single invalid match is invalid", "data": {"foo": "bar", "fooooo": 2}, "valid": false }, { "description": "multiple invalid matches is invalid", "data": {"foo": "bar", "foooooo" : "baz"}, "valid": false }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "multiple simultaneous patternProperties are validated", "schema": { "patternProperties": { "a*": {"type": "integer"}, "aaa*": {"maximum": 20} } }, "tests": [ { "description": "a single valid match is valid", "data": {"a": 21}, "valid": true }, { "description": "a simultaneous match is valid", "data": {"aaaa": 18}, "valid": true }, { "description": "multiple matches is valid", "data": {"a": 21, "aaaa": 18}, "valid": true }, { "description": "an invalid due to one is invalid", "data": {"a": "bar"}, "valid": false }, { "description": "an invalid due to the other is invalid", "data": {"aaaa": 31}, "valid": false }, { "description": "an invalid due to both is invalid", "data": {"aaa": "foo", "aaaa": 31}, "valid": false } ] }, { "description": "regexes are not anchored by default and are case sensitive", "schema": { "patternProperties": { "[0-9]{2,}": { "type": "boolean" }, "X_": { "type": "string" } } }, "tests": [ { "description": "non recognized members are ignored", "data": { "answer 1": "42" }, "valid": true }, { "description": "recognized members are accounted for", "data": { "a31b": null }, "valid": false }, { "description": "regexes are case sensitive", "data": { "a_x_3": 3 }, "valid": true }, { "description": "regexes are case sensitive, 2", "data": { "a_X_3": 3 }, "valid": false } ] }, { "description": "patternProperties with null valued instance properties", "schema": { "patternProperties": { "^.*bar$": {"type": "null"} } }, "tests": [ { "description": "allows null values", "data": {"foobar": null}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/properties.json000066400000000000000000000065121477700171100300620ustar00rootroot00000000000000[ { "description": "object properties validation", "schema": { "properties": { "foo": {"type": "integer"}, "bar": {"type": "string"} } }, "tests": [ { "description": "both properties present and valid is valid", "data": {"foo": 1, "bar": "baz"}, "valid": true }, { "description": "one property invalid is invalid", "data": {"foo": 1, "bar": {}}, "valid": false }, { "description": "both properties invalid is invalid", "data": {"foo": [], "bar": {}}, "valid": false }, { "description": "doesn't invalidate other properties", "data": {"quux": []}, "valid": true }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "properties, patternProperties, additionalProperties interaction", "schema": { "properties": { "foo": {"type": "array", "maxItems": 3}, "bar": {"type": "array"} }, "patternProperties": {"f.o": {"minItems": 2}}, "additionalProperties": {"type": "integer"} }, "tests": [ { "description": "property validates property", "data": {"foo": [1, 2]}, "valid": true }, { "description": "property invalidates property", "data": {"foo": [1, 2, 3, 4]}, "valid": false }, { "description": "patternProperty invalidates property", "data": {"foo": []}, "valid": false }, { "description": "patternProperty validates nonproperty", "data": {"fxo": [1, 2]}, "valid": true }, { "description": "patternProperty invalidates nonproperty", "data": {"fxo": []}, "valid": false }, { "description": "additionalProperty ignores property", "data": {"bar": []}, "valid": true }, { "description": "additionalProperty validates others", "data": {"quux": 3}, "valid": true }, { "description": "additionalProperty invalidates others", "data": {"quux": "foo"}, "valid": false } ] }, { "description": "properties with null valued instance properties", "schema": { "properties": { "foo": {"type": "null"} } }, "tests": [ { "description": "allows null values", "data": {"foo": null}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/ref.json000066400000000000000000000176621477700171100264520ustar00rootroot00000000000000[ { "description": "root pointer ref", "schema": { "properties": { "foo": {"$ref": "#"} }, "additionalProperties": false }, "tests": [ { "description": "match", "data": {"foo": false}, "valid": true }, { "description": "recursive match", "data": {"foo": {"foo": false}}, "valid": true }, { "description": "mismatch", "data": {"bar": false}, "valid": false }, { "description": "recursive mismatch", "data": {"foo": {"bar": false}}, "valid": false } ] }, { "description": "relative pointer ref to object", "schema": { "properties": { "foo": {"type": "integer"}, "bar": {"$ref": "#/properties/foo"} } }, "tests": [ { "description": "match", "data": {"bar": 3}, "valid": true }, { "description": "mismatch", "data": {"bar": true}, "valid": false } ] }, { "description": "relative pointer ref to array", "schema": { "items": [ {"type": "integer"}, {"$ref": "#/items/0"} ] }, "tests": [ { "description": "match array", "data": [1, 2], "valid": true }, { "description": "mismatch array", "data": [1, "foo"], "valid": false } ] }, { "description": "escaped pointer ref", "schema": { "definitions": { "tilde~field": {"type": "integer"}, "slash/field": {"type": "integer"}, "percent%field": {"type": "integer"} }, "properties": { "tilde": {"$ref": "#/definitions/tilde~0field"}, "slash": {"$ref": "#/definitions/slash~1field"}, "percent": {"$ref": "#/definitions/percent%25field"} } }, "tests": [ { "description": "slash invalid", "data": {"slash": "aoeu"}, "valid": false }, { "description": "tilde invalid", "data": {"tilde": "aoeu"}, "valid": false }, { "description": "percent invalid", "data": {"percent": "aoeu"}, "valid": false }, { "description": "slash valid", "data": {"slash": 123}, "valid": true }, { "description": "tilde valid", "data": {"tilde": 123}, "valid": true }, { "description": "percent valid", "data": {"percent": 123}, "valid": true } ] }, { "description": "nested refs", "schema": { "definitions": { "a": {"type": "integer"}, "b": {"$ref": "#/definitions/a"}, "c": {"$ref": "#/definitions/b"} }, "$ref": "#/definitions/c" }, "tests": [ { "description": "nested ref valid", "data": 5, "valid": true }, { "description": "nested ref invalid", "data": "a", "valid": false } ] }, { "description": "ref overrides any sibling keywords", "schema": { "definitions": { "reffed": { "type": "array" } }, "properties": { "foo": { "$ref": "#/definitions/reffed", "maxItems": 2 } } }, "tests": [ { "description": "remote ref valid", "data": { "foo": [] }, "valid": true }, { "description": "remote ref valid, maxItems ignored", "data": { "foo": [ 1, 2, 3] }, "valid": true }, { "description": "ref invalid", "data": { "foo": "string" }, "valid": false } ] }, { "description": "property named $ref, containing an actual $ref", "schema": { "properties": { "$ref": {"$ref": "#/definitions/is-string"} }, "definitions": { "is-string": { "type": "string" } } }, "tests": [ { "description": "property named $ref valid", "data": {"$ref": "a"}, "valid": true }, { "description": "property named $ref invalid", "data": {"$ref": 2}, "valid": false } ] }, { "description": "$ref prevents a sibling id from changing the base uri", "schema": { "id": "http://localhost:1234/sibling_id/base/", "definitions": { "foo": { "id": "http://localhost:1234/sibling_id/foo.json", "type": "string" }, "base_foo": { "$comment": "this canonical uri is http://localhost:1234/sibling_id/base/foo.json", "id": "foo.json", "type": "number" } }, "extends": [ { "$comment": "$ref resolves to http://localhost:1234/sibling_id/base/foo.json, not http://localhost:1234/sibling_id/foo.json", "id": "http://localhost:1234/sibling_id/", "$ref": "foo.json" } ] }, "tests": [ { "description": "$ref resolves to /definitions/base_foo, data does not validate", "data": "a", "valid": false }, { "description": "$ref resolves to /definitions/base_foo, data validates", "data": 1, "valid": true } ] }, { "description": "remote ref, containing refs itself", "schema": {"$ref": "http://json-schema.org/draft-03/schema#"}, "tests": [ { "description": "remote ref valid", "data": {"items": {"type": "integer"}}, "valid": true }, { "description": "remote ref invalid", "data": {"items": {"type": 1}}, "valid": false } ] }, { "description": "naive replacement of $ref with its destination is not correct", "schema": { "definitions": { "a_string": { "type": "string" } }, "enum": [ { "$ref": "#/definitions/a_string" } ] }, "tests": [ { "description": "do not evaluate the $ref inside the enum, matching any string", "data": "this is a string", "valid": false }, { "description": "match the enum exactly", "data": { "$ref": "#/definitions/a_string" }, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/refRemote.json000066400000000000000000000037101477700171100276130ustar00rootroot00000000000000[ { "description": "remote ref", "schema": {"$ref": "http://localhost:1234/integer.json"}, "tests": [ { "description": "remote ref valid", "data": 1, "valid": true }, { "description": "remote ref invalid", "data": "a", "valid": false } ] }, { "description": "fragment within remote ref", "schema": {"$ref": "http://localhost:1234/subSchemas.json#/definitions/integer"}, "tests": [ { "description": "remote fragment valid", "data": 1, "valid": true }, { "description": "remote fragment invalid", "data": "a", "valid": false } ] }, { "description": "ref within remote ref", "schema": { "$ref": "http://localhost:1234/subSchemas.json#/definitions/refToInteger" }, "tests": [ { "description": "ref within ref valid", "data": 1, "valid": true }, { "description": "ref within ref invalid", "data": "a", "valid": false } ] }, { "description": "change resolution scope", "schema": { "id": "http://localhost:1234/", "items": { "id": "baseUriChange/", "items": {"$ref": "folderInteger.json"} } }, "tests": [ { "description": "changed scope ref valid", "data": [[1]], "valid": true }, { "description": "changed scope ref invalid", "data": [["a"]], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/required.json000066400000000000000000000024021477700171100275000ustar00rootroot00000000000000[ { "description": "required validation", "schema": { "properties": { "foo": {"required" : true}, "bar": {} } }, "tests": [ { "description": "present required property is valid", "data": {"foo": 1}, "valid": true }, { "description": "non-present required property is invalid", "data": {"bar": 1}, "valid": false } ] }, { "description": "required default validation", "schema": { "properties": { "foo": {} } }, "tests": [ { "description": "not required by default", "data": {}, "valid": true } ] }, { "description": "required explicitly false validation", "schema": { "properties": { "foo": {"required": false} } }, "tests": [ { "description": "not required if required is false", "data": {}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/type.json000066400000000000000000000330641477700171100266510ustar00rootroot00000000000000[ { "description": "integer type matches integers", "schema": {"type": "integer"}, "tests": [ { "description": "an integer is an integer", "data": 1, "valid": true }, { "description": "a float is not an integer", "data": 1.1, "valid": false }, { "description": "a string is not an integer", "data": "foo", "valid": false }, { "description": "a string is still not an integer, even if it looks like one", "data": "1", "valid": false }, { "description": "an object is not an integer", "data": {}, "valid": false }, { "description": "an array is not an integer", "data": [], "valid": false }, { "description": "a boolean is not an integer", "data": true, "valid": false }, { "description": "null is not an integer", "data": null, "valid": false } ] }, { "description": "number type matches numbers", "schema": {"type": "number"}, "tests": [ { "description": "an integer is a number", "data": 1, "valid": true }, { "description": "a float with zero fractional part is a number", "data": 1.0, "valid": true }, { "description": "a float is a number", "data": 1.1, "valid": true }, { "description": "a string is not a number", "data": "foo", "valid": false }, { "description": "a string is still not a number, even if it looks like one", "data": "1", "valid": false }, { "description": "an object is not a number", "data": {}, "valid": false }, { "description": "an array is not a number", "data": [], "valid": false }, { "description": "a boolean is not a number", "data": true, "valid": false }, { "description": "null is not a number", "data": null, "valid": false } ] }, { "description": "string type matches strings", "schema": {"type": "string"}, "tests": [ { "description": "1 is not a string", "data": 1, "valid": false }, { "description": "a float is not a string", "data": 1.1, "valid": false }, { "description": "a string is a string", "data": "foo", "valid": true }, { "description": "a string is still a string, even if it looks like a number", "data": "1", "valid": true }, { "description": "an object is not a string", "data": {}, "valid": false }, { "description": "an array is not a string", "data": [], "valid": false }, { "description": "a boolean is not a string", "data": true, "valid": false }, { "description": "null is not a string", "data": null, "valid": false } ] }, { "description": "object type matches objects", "schema": {"type": "object"}, "tests": [ { "description": "an integer is not an object", "data": 1, "valid": false }, { "description": "a float is not an object", "data": 1.1, "valid": false }, { "description": "a string is not an object", "data": "foo", "valid": false }, { "description": "an object is an object", "data": {}, "valid": true }, { "description": "an array is not an object", "data": [], "valid": false }, { "description": "a boolean is not an object", "data": true, "valid": false }, { "description": "null is not an object", "data": null, "valid": false } ] }, { "description": "array type matches arrays", "schema": {"type": "array"}, "tests": [ { "description": "an integer is not an array", "data": 1, "valid": false }, { "description": "a float is not an array", "data": 1.1, "valid": false }, { "description": "a string is not an array", "data": "foo", "valid": false }, { "description": "an object is not an array", "data": {}, "valid": false }, { "description": "an array is an array", "data": [], "valid": true }, { "description": "a boolean is not an array", "data": true, "valid": false }, { "description": "null is not an array", "data": null, "valid": false } ] }, { "description": "boolean type matches booleans", "schema": {"type": "boolean"}, "tests": [ { "description": "an integer is not a boolean", "data": 1, "valid": false }, { "description": "a float is not a boolean", "data": 1.1, "valid": false }, { "description": "a string is not a boolean", "data": "foo", "valid": false }, { "description": "an object is not a boolean", "data": {}, "valid": false }, { "description": "an array is not a boolean", "data": [], "valid": false }, { "description": "a boolean is a boolean", "data": true, "valid": true }, { "description": "null is not a boolean", "data": null, "valid": false } ] }, { "description": "null type matches only the null object", "schema": {"type": "null"}, "tests": [ { "description": "an integer is not null", "data": 1, "valid": false }, { "description": "a float is not null", "data": 1.1, "valid": false }, { "description": "a string is not null", "data": "foo", "valid": false }, { "description": "an object is not null", "data": {}, "valid": false }, { "description": "an array is not null", "data": [], "valid": false }, { "description": "a boolean is not null", "data": true, "valid": false }, { "description": "null is null", "data": null, "valid": true } ] }, { "description": "any type matches any type", "schema": {"type": "any"}, "tests": [ { "description": "any type includes integers", "data": 1, "valid": true }, { "description": "any type includes float", "data": 1.1, "valid": true }, { "description": "any type includes string", "data": "foo", "valid": true }, { "description": "any type includes object", "data": {}, "valid": true }, { "description": "any type includes array", "data": [], "valid": true }, { "description": "any type includes boolean", "data": true, "valid": true }, { "description": "any type includes null", "data": null, "valid": true } ] }, { "description": "multiple types can be specified in an array", "schema": {"type": ["integer", "string"]}, "tests": [ { "description": "an integer is valid", "data": 1, "valid": true }, { "description": "a string is valid", "data": "foo", "valid": true }, { "description": "a float is invalid", "data": 1.1, "valid": false }, { "description": "an object is invalid", "data": {}, "valid": false }, { "description": "an array is invalid", "data": [], "valid": false }, { "description": "a boolean is invalid", "data": true, "valid": false }, { "description": "null is invalid", "data": null, "valid": false } ] }, { "description": "types can include schemas", "schema": { "type": [ "array", {"type": "object"} ] }, "tests": [ { "description": "an integer is invalid", "data": 1, "valid": false }, { "description": "a string is invalid", "data": "foo", "valid": false }, { "description": "a float is invalid", "data": 1.1, "valid": false }, { "description": "an object is valid", "data": {}, "valid": true }, { "description": "an array is valid", "data": [], "valid": true }, { "description": "a boolean is invalid", "data": true, "valid": false }, { "description": "null is invalid", "data": null, "valid": false } ] }, { "description": "applies a nested schema", "schema": { "type": [ "integer", { "properties": { "foo": {"type": "null"} } } ] }, "tests": [ { "description": "an integer is valid", "data": 1, "valid": true }, { "description": "an object is valid only if it is fully valid", "data": {"foo": null}, "valid": true }, { "description": "an object is invalid otherwise", "data": {"foo": "bar"}, "valid": false } ] }, { "description": "types from separate schemas are merged", "schema": { "type": [ {"type": ["string"]}, {"type": ["array", "null"]} ] }, "tests": [ { "description": "an integer is invalid", "data": 1, "valid": false }, { "description": "a string is valid", "data": "foo", "valid": true }, { "description": "an array is valid", "data": [1, 2, 3], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft3/uniqueItems.json000066400000000000000000000307631477700171100302030ustar00rootroot00000000000000[ { "description": "uniqueItems validation", "schema": {"uniqueItems": true}, "tests": [ { "description": "unique array of integers is valid", "data": [1, 2], "valid": true }, { "description": "non-unique array of integers is invalid", "data": [1, 1], "valid": false }, { "description": "non-unique array of more than two integers is invalid", "data": [1, 2, 1], "valid": false }, { "description": "numbers are unique if mathematically unequal", "data": [1.0, 1.00, 1], "valid": false }, { "description": "unique array of strings is valid", "data": ["foo", "bar", "baz"], "valid": true }, { "description": "non-unique array of strings is invalid", "data": ["foo", "bar", "foo"], "valid": false }, { "description": "unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "baz"}], "valid": true }, { "description": "non-unique array of objects is invalid", "data": [{"foo": "bar"}, {"foo": "bar"}], "valid": false }, { "description": "unique array of nested objects is valid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : false}}} ], "valid": true }, { "description": "non-unique array of nested objects is invalid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : true}}} ], "valid": false }, { "description": "unique array of arrays is valid", "data": [["foo"], ["bar"]], "valid": true }, { "description": "non-unique array of arrays is invalid", "data": [["foo"], ["foo"]], "valid": false }, { "description": "non-unique array of more than two arrays is invalid", "data": [["foo"], ["bar"], ["foo"]], "valid": false }, { "description": "1 and true are unique", "data": [1, true], "valid": true }, { "description": "0 and false are unique", "data": [0, false], "valid": true }, { "description": "[1] and [true] are unique", "data": [[1], [true]], "valid": true }, { "description": "[0] and [false] are unique", "data": [[0], [false]], "valid": true }, { "description": "nested [1] and [true] are unique", "data": [[[1], "foo"], [[true], "foo"]], "valid": true }, { "description": "nested [0] and [false] are unique", "data": [[[0], "foo"], [[false], "foo"]], "valid": true }, { "description": "unique heterogeneous types are valid", "data": [{}, [1], true, null, 1], "valid": true }, { "description": "non-unique heterogeneous types are invalid", "data": [{}, [1], true, null, {}, 1], "valid": false }, { "description": "{\"a\": false} and {\"a\": 0} are unique", "data": [{"a": false}, {"a": 0}], "valid": true }, { "description": "{\"a\": true} and {\"a\": 1} are unique", "data": [{"a": true}, {"a": 1}], "valid": true } ] }, { "description": "uniqueItems with an array of items", "schema": { "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": true }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is not valid", "data": [false, false], "valid": false }, { "description": "[true, true] from items array is not valid", "data": [true, true], "valid": false }, { "description": "unique array extended from [false, true] is valid", "data": [false, true, "foo", "bar"], "valid": true }, { "description": "unique array extended from [true, false] is valid", "data": [true, false, "foo", "bar"], "valid": true }, { "description": "non-unique array extended from [false, true] is not valid", "data": [false, true, "foo", "foo"], "valid": false }, { "description": "non-unique array extended from [true, false] is not valid", "data": [true, false, "foo", "foo"], "valid": false } ] }, { "description": "uniqueItems with an array of items and additionalItems=false", "schema": { "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": true, "additionalItems": false }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is not valid", "data": [false, false], "valid": false }, { "description": "[true, true] from items array is not valid", "data": [true, true], "valid": false }, { "description": "extra items are invalid even if unique", "data": [false, true, null], "valid": false } ] }, { "description": "uniqueItems=false validation", "schema": { "uniqueItems": false }, "tests": [ { "description": "unique array of integers is valid", "data": [1, 2], "valid": true }, { "description": "non-unique array of integers is valid", "data": [1, 1], "valid": true }, { "description": "numbers are unique if mathematically unequal", "data": [1.0, 1.00, 1], "valid": true }, { "description": "unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "baz"}], "valid": true }, { "description": "non-unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "bar"}], "valid": true }, { "description": "unique array of nested objects is valid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : false}}} ], "valid": true }, { "description": "non-unique array of nested objects is valid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : true}}} ], "valid": true }, { "description": "unique array of arrays is valid", "data": [["foo"], ["bar"]], "valid": true }, { "description": "non-unique array of arrays is valid", "data": [["foo"], ["foo"]], "valid": true }, { "description": "1 and true are unique", "data": [1, true], "valid": true }, { "description": "0 and false are unique", "data": [0, false], "valid": true }, { "description": "unique heterogeneous types are valid", "data": [{}, [1], true, null, 1], "valid": true }, { "description": "non-unique heterogeneous types are valid", "data": [{}, [1], true, null, {}, 1], "valid": true } ] }, { "description": "uniqueItems=false with an array of items", "schema": { "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": false }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is valid", "data": [false, false], "valid": true }, { "description": "[true, true] from items array is valid", "data": [true, true], "valid": true }, { "description": "unique array extended from [false, true] is valid", "data": [false, true, "foo", "bar"], "valid": true }, { "description": "unique array extended from [true, false] is valid", "data": [true, false, "foo", "bar"], "valid": true }, { "description": "non-unique array extended from [false, true] is valid", "data": [false, true, "foo", "foo"], "valid": true }, { "description": "non-unique array extended from [true, false] is valid", "data": [true, false, "foo", "foo"], "valid": true } ] }, { "description": "uniqueItems=false with an array of items and additionalItems=false", "schema": { "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": false, "additionalItems": false }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is valid", "data": [false, false], "valid": true }, { "description": "[true, true] from items array is valid", "data": [true, true], "valid": true }, { "description": "extra items are invalid even if unique", "data": [false, true, null], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/000077500000000000000000000000001477700171100247705ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/additionalItems.json000066400000000000000000000121531477700171100307770ustar00rootroot00000000000000[ { "description": "additionalItems as schema", "schema": { "items": [{}], "additionalItems": {"type": "integer"} }, "tests": [ { "description": "additional items match schema", "data": [ null, 2, 3, 4 ], "valid": true }, { "description": "additional items do not match schema", "data": [ null, 2, 3, "foo" ], "valid": false } ] }, { "description": "when items is schema, additionalItems does nothing", "schema": { "items": {}, "additionalItems": false }, "tests": [ { "description": "all items match schema", "data": [ 1, 2, 3, 4, 5 ], "valid": true } ] }, { "description": "array of items with no additionalItems permitted", "schema": { "items": [{}, {}, {}], "additionalItems": false }, "tests": [ { "description": "empty array", "data": [ ], "valid": true }, { "description": "fewer number of items present (1)", "data": [ 1 ], "valid": true }, { "description": "fewer number of items present (2)", "data": [ 1, 2 ], "valid": true }, { "description": "equal number of items present", "data": [ 1, 2, 3 ], "valid": true }, { "description": "additional items are not permitted", "data": [ 1, 2, 3, 4 ], "valid": false } ] }, { "description": "additionalItems as false without items", "schema": {"additionalItems": false}, "tests": [ { "description": "items defaults to empty schema so everything is valid", "data": [ 1, 2, 3, 4, 5 ], "valid": true }, { "description": "ignores non-arrays", "data": {"foo" : "bar"}, "valid": true } ] }, { "description": "additionalItems are allowed by default", "schema": {"items": [{"type": "integer"}]}, "tests": [ { "description": "only the first item is validated", "data": [1, "foo", false], "valid": true } ] }, { "description": "additionalItems does not look in applicators, valid case", "schema": { "allOf": [ { "items": [ { "type": "integer" } ] } ], "additionalItems": { "type": "boolean" } }, "tests": [ { "description": "items defined in allOf are not examined", "data": [ 1, null ], "valid": true } ] }, { "description": "additionalItems does not look in applicators, invalid case", "schema": { "allOf": [ { "items": [ { "type": "integer" }, { "type": "string" } ] } ], "items": [ {"type": "integer" } ], "additionalItems": { "type": "boolean" } }, "tests": [ { "description": "items defined in allOf are not examined", "data": [ 1, "hello" ], "valid": false } ] }, { "description": "items validation adjusts the starting index for additionalItems", "schema": { "items": [ { "type": "string" } ], "additionalItems": { "type": "integer" } }, "tests": [ { "description": "valid items", "data": [ "x", 2, 3 ], "valid": true }, { "description": "wrong type of second item", "data": [ "x", "y" ], "valid": false } ] }, { "description": "additionalItems with heterogeneous array", "schema": { "items": [{}], "additionalItems": false }, "tests": [ { "description": "heterogeneous invalid instance", "data": [ "foo", "bar", 37 ], "valid": false }, { "description": "valid instance", "data": [ null ], "valid": true } ] }, { "description": "additionalItems with null instance elements", "schema": { "additionalItems": { "type": "null" } }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/additionalProperties.json000066400000000000000000000105121477700171100320470ustar00rootroot00000000000000[ { "description": "additionalProperties being false does not allow other properties", "schema": { "properties": {"foo": {}, "bar": {}}, "patternProperties": { "^v": {} }, "additionalProperties": false }, "tests": [ { "description": "no additional properties is valid", "data": {"foo": 1}, "valid": true }, { "description": "an additional property is invalid", "data": {"foo" : 1, "bar" : 2, "quux" : "boom"}, "valid": false }, { "description": "ignores arrays", "data": [1, 2, 3], "valid": true }, { "description": "ignores strings", "data": "foobarbaz", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true }, { "description": "patternProperties are not additional properties", "data": {"foo":1, "vroom": 2}, "valid": true } ] }, { "description": "non-ASCII pattern with additionalProperties", "schema": { "patternProperties": {"^á": {}}, "additionalProperties": false }, "tests": [ { "description": "matching the pattern is valid", "data": {"ármányos": 2}, "valid": true }, { "description": "not matching the pattern is invalid", "data": {"élmény": 2}, "valid": false } ] }, { "description": "additionalProperties with schema", "schema": { "properties": {"foo": {}, "bar": {}}, "additionalProperties": {"type": "boolean"} }, "tests": [ { "description": "no additional properties is valid", "data": {"foo": 1}, "valid": true }, { "description": "an additional valid property is valid", "data": {"foo" : 1, "bar" : 2, "quux" : true}, "valid": true }, { "description": "an additional invalid property is invalid", "data": {"foo" : 1, "bar" : 2, "quux" : 12}, "valid": false } ] }, { "description": "additionalProperties can exist by itself", "schema": { "additionalProperties": {"type": "boolean"} }, "tests": [ { "description": "an additional valid property is valid", "data": {"foo" : true}, "valid": true }, { "description": "an additional invalid property is invalid", "data": {"foo" : 1}, "valid": false } ] }, { "description": "additionalProperties are allowed by default", "schema": {"properties": {"foo": {}, "bar": {}}}, "tests": [ { "description": "additional properties are allowed", "data": {"foo": 1, "bar": 2, "quux": true}, "valid": true } ] }, { "description": "additionalProperties does not look in applicators", "schema": { "allOf": [ {"properties": {"foo": {}}} ], "additionalProperties": {"type": "boolean"} }, "tests": [ { "description": "properties defined in allOf are not examined", "data": {"foo": 1, "bar": true}, "valid": false } ] }, { "description": "additionalProperties with null valued instance properties", "schema": { "additionalProperties": { "type": "null" } }, "tests": [ { "description": "allows null values", "data": {"foo": null}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/allOf.json000066400000000000000000000153651477700171100267320ustar00rootroot00000000000000[ { "description": "allOf", "schema": { "allOf": [ { "properties": { "bar": {"type": "integer"} }, "required": ["bar"] }, { "properties": { "foo": {"type": "string"} }, "required": ["foo"] } ] }, "tests": [ { "description": "allOf", "data": {"foo": "baz", "bar": 2}, "valid": true }, { "description": "mismatch second", "data": {"foo": "baz"}, "valid": false }, { "description": "mismatch first", "data": {"bar": 2}, "valid": false }, { "description": "wrong type", "data": {"foo": "baz", "bar": "quux"}, "valid": false } ] }, { "description": "allOf with base schema", "schema": { "properties": {"bar": {"type": "integer"}}, "required": ["bar"], "allOf" : [ { "properties": { "foo": {"type": "string"} }, "required": ["foo"] }, { "properties": { "baz": {"type": "null"} }, "required": ["baz"] } ] }, "tests": [ { "description": "valid", "data": {"foo": "quux", "bar": 2, "baz": null}, "valid": true }, { "description": "mismatch base schema", "data": {"foo": "quux", "baz": null}, "valid": false }, { "description": "mismatch first allOf", "data": {"bar": 2, "baz": null}, "valid": false }, { "description": "mismatch second allOf", "data": {"foo": "quux", "bar": 2}, "valid": false }, { "description": "mismatch both", "data": {"bar": 2}, "valid": false } ] }, { "description": "allOf simple types", "schema": { "allOf": [ {"maximum": 30}, {"minimum": 20} ] }, "tests": [ { "description": "valid", "data": 25, "valid": true }, { "description": "mismatch one", "data": 35, "valid": false } ] }, { "description": "allOf with one empty schema", "schema": { "allOf": [ {} ] }, "tests": [ { "description": "any data is valid", "data": 1, "valid": true } ] }, { "description": "allOf with two empty schemas", "schema": { "allOf": [ {}, {} ] }, "tests": [ { "description": "any data is valid", "data": 1, "valid": true } ] }, { "description": "allOf with the first empty schema", "schema": { "allOf": [ {}, { "type": "number" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "string is invalid", "data": "foo", "valid": false } ] }, { "description": "allOf with the last empty schema", "schema": { "allOf": [ { "type": "number" }, {} ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "string is invalid", "data": "foo", "valid": false } ] }, { "description": "nested allOf, to check validation semantics", "schema": { "allOf": [ { "allOf": [ { "type": "null" } ] } ] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "anything non-null is invalid", "data": 123, "valid": false } ] }, { "description": "allOf combined with anyOf, oneOf", "schema": { "allOf": [ { "multipleOf": 2 } ], "anyOf": [ { "multipleOf": 3 } ], "oneOf": [ { "multipleOf": 5 } ] }, "tests": [ { "description": "allOf: false, anyOf: false, oneOf: false", "data": 1, "valid": false }, { "description": "allOf: false, anyOf: false, oneOf: true", "data": 5, "valid": false }, { "description": "allOf: false, anyOf: true, oneOf: false", "data": 3, "valid": false }, { "description": "allOf: false, anyOf: true, oneOf: true", "data": 15, "valid": false }, { "description": "allOf: true, anyOf: false, oneOf: false", "data": 2, "valid": false }, { "description": "allOf: true, anyOf: false, oneOf: true", "data": 10, "valid": false }, { "description": "allOf: true, anyOf: true, oneOf: false", "data": 6, "valid": false }, { "description": "allOf: true, anyOf: true, oneOf: true", "data": 30, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/anyOf.json000066400000000000000000000075551477700171100267530ustar00rootroot00000000000000[ { "description": "anyOf", "schema": { "anyOf": [ { "type": "integer" }, { "minimum": 2 } ] }, "tests": [ { "description": "first anyOf valid", "data": 1, "valid": true }, { "description": "second anyOf valid", "data": 2.5, "valid": true }, { "description": "both anyOf valid", "data": 3, "valid": true }, { "description": "neither anyOf valid", "data": 1.5, "valid": false } ] }, { "description": "anyOf with base schema", "schema": { "type": "string", "anyOf" : [ { "maxLength": 2 }, { "minLength": 4 } ] }, "tests": [ { "description": "mismatch base schema", "data": 3, "valid": false }, { "description": "one anyOf valid", "data": "foobar", "valid": true }, { "description": "both anyOf invalid", "data": "foo", "valid": false } ] }, { "description": "anyOf complex types", "schema": { "anyOf": [ { "properties": { "bar": {"type": "integer"} }, "required": ["bar"] }, { "properties": { "foo": {"type": "string"} }, "required": ["foo"] } ] }, "tests": [ { "description": "first anyOf valid (complex)", "data": {"bar": 2}, "valid": true }, { "description": "second anyOf valid (complex)", "data": {"foo": "baz"}, "valid": true }, { "description": "both anyOf valid (complex)", "data": {"foo": "baz", "bar": 2}, "valid": true }, { "description": "neither anyOf valid (complex)", "data": {"foo": 2, "bar": "quux"}, "valid": false } ] }, { "description": "anyOf with one empty schema", "schema": { "anyOf": [ { "type": "number" }, {} ] }, "tests": [ { "description": "string is valid", "data": "foo", "valid": true }, { "description": "number is valid", "data": 123, "valid": true } ] }, { "description": "nested anyOf, to check validation semantics", "schema": { "anyOf": [ { "anyOf": [ { "type": "null" } ] } ] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "anything non-null is invalid", "data": 123, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/default.json000066400000000000000000000042671477700171100273200ustar00rootroot00000000000000[ { "description": "invalid type for default", "schema": { "properties": { "foo": { "type": "integer", "default": [] } } }, "tests": [ { "description": "valid when property is specified", "data": {"foo": 13}, "valid": true }, { "description": "still valid when the invalid default is used", "data": {}, "valid": true } ] }, { "description": "invalid string value for default", "schema": { "properties": { "bar": { "type": "string", "minLength": 4, "default": "bad" } } }, "tests": [ { "description": "valid when property is specified", "data": {"bar": "good"}, "valid": true }, { "description": "still valid when the invalid default is used", "data": {}, "valid": true } ] }, { "description": "the default keyword does not do anything if the property is missing", "schema": { "type": "object", "properties": { "alpha": { "type": "number", "maximum": 3, "default": 5 } } }, "tests": [ { "description": "an explicit property value is checked against maximum (passing)", "data": { "alpha": 1 }, "valid": true }, { "description": "an explicit property value is checked against maximum (failing)", "data": { "alpha": 5 }, "valid": false }, { "description": "missing properties are not filled in with the default", "data": {}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/definitions.json000066400000000000000000000013171477700171100302000ustar00rootroot00000000000000[ { "description": "validate definition against metaschema", "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}, "tests": [ { "description": "valid definition schema", "data": { "definitions": { "foo": {"type": "integer"} } }, "valid": true }, { "description": "invalid definition schema", "data": { "definitions": { "foo": {"type": 1} } }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/dependencies.json000066400000000000000000000143641477700171100303210ustar00rootroot00000000000000[ { "description": "dependencies", "schema": { "dependencies": {"bar": ["foo"]} }, "tests": [ { "description": "neither", "data": {}, "valid": true }, { "description": "nondependant", "data": {"foo": 1}, "valid": true }, { "description": "with dependency", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "missing dependency", "data": {"bar": 2}, "valid": false }, { "description": "ignores arrays", "data": ["bar"], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "multiple dependencies", "schema": { "dependencies": {"quux": ["foo", "bar"]} }, "tests": [ { "description": "neither", "data": {}, "valid": true }, { "description": "nondependants", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "with dependencies", "data": {"foo": 1, "bar": 2, "quux": 3}, "valid": true }, { "description": "missing dependency", "data": {"foo": 1, "quux": 2}, "valid": false }, { "description": "missing other dependency", "data": {"bar": 1, "quux": 2}, "valid": false }, { "description": "missing both dependencies", "data": {"quux": 1}, "valid": false } ] }, { "description": "multiple dependencies subschema", "schema": { "dependencies": { "bar": { "properties": { "foo": {"type": "integer"}, "bar": {"type": "integer"} } } } }, "tests": [ { "description": "valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "no dependency", "data": {"foo": "quux"}, "valid": true }, { "description": "wrong type", "data": {"foo": "quux", "bar": 2}, "valid": false }, { "description": "wrong type other", "data": {"foo": 2, "bar": "quux"}, "valid": false }, { "description": "wrong type both", "data": {"foo": "quux", "bar": "quux"}, "valid": false } ] }, { "description": "dependencies with escaped characters", "schema": { "dependencies": { "foo\nbar": ["foo\rbar"], "foo\tbar": { "minProperties": 4 }, "foo'bar": {"required": ["foo\"bar"]}, "foo\"bar": ["foo'bar"] } }, "tests": [ { "description": "valid object 1", "data": { "foo\nbar": 1, "foo\rbar": 2 }, "valid": true }, { "description": "valid object 2", "data": { "foo\tbar": 1, "a": 2, "b": 3, "c": 4 }, "valid": true }, { "description": "valid object 3", "data": { "foo'bar": 1, "foo\"bar": 2 }, "valid": true }, { "description": "invalid object 1", "data": { "foo\nbar": 1, "foo": 2 }, "valid": false }, { "description": "invalid object 2", "data": { "foo\tbar": 1, "a": 2 }, "valid": false }, { "description": "invalid object 3", "data": { "foo'bar": 1 }, "valid": false }, { "description": "invalid object 4", "data": { "foo\"bar": 2 }, "valid": false } ] }, { "description": "dependent subschema incompatible with root", "schema": { "properties": { "foo": {} }, "dependencies": { "foo": { "properties": { "bar": {} }, "additionalProperties": false } } }, "tests": [ { "description": "matches root", "data": {"foo": 1}, "valid": false }, { "description": "matches dependency", "data": {"bar": 1}, "valid": true }, { "description": "matches both", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "no dependency", "data": {"baz": 1}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/enum.json000066400000000000000000000146431477700171100266370ustar00rootroot00000000000000[ { "description": "simple enum validation", "schema": {"enum": [1, 2, 3]}, "tests": [ { "description": "one of the enum is valid", "data": 1, "valid": true }, { "description": "something else is invalid", "data": 4, "valid": false } ] }, { "description": "heterogeneous enum validation", "schema": {"enum": [6, "foo", [], true, {"foo": 12}]}, "tests": [ { "description": "one of the enum is valid", "data": [], "valid": true }, { "description": "something else is invalid", "data": null, "valid": false }, { "description": "objects are deep compared", "data": {"foo": false}, "valid": false }, { "description": "valid object matches", "data": {"foo": 12}, "valid": true }, { "description": "extra properties in object is invalid", "data": {"foo": 12, "boo": 42}, "valid": false } ] }, { "description": "heterogeneous enum-with-null validation", "schema": { "enum": [6, null] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "number is valid", "data": 6, "valid": true }, { "description": "something else is invalid", "data": "test", "valid": false } ] }, { "description": "enums in properties", "schema": { "type":"object", "properties": { "foo": {"enum":["foo"]}, "bar": {"enum":["bar"]} }, "required": ["bar"] }, "tests": [ { "description": "both properties are valid", "data": {"foo":"foo", "bar":"bar"}, "valid": true }, { "description": "wrong foo value", "data": {"foo":"foot", "bar":"bar"}, "valid": false }, { "description": "wrong bar value", "data": {"foo":"foo", "bar":"bart"}, "valid": false }, { "description": "missing optional property is valid", "data": {"bar":"bar"}, "valid": true }, { "description": "missing required property is invalid", "data": {"foo":"foo"}, "valid": false }, { "description": "missing all properties is invalid", "data": {}, "valid": false } ] }, { "description": "enum with escaped characters", "schema": { "enum": ["foo\nbar", "foo\rbar"] }, "tests": [ { "description": "member 1 is valid", "data": "foo\nbar", "valid": true }, { "description": "member 2 is valid", "data": "foo\rbar", "valid": true }, { "description": "another string is invalid", "data": "abc", "valid": false } ] }, { "description": "enum with false does not match 0", "schema": {"enum": [false]}, "tests": [ { "description": "false is valid", "data": false, "valid": true }, { "description": "integer zero is invalid", "data": 0, "valid": false }, { "description": "float zero is invalid", "data": 0.0, "valid": false } ] }, { "description": "enum with true does not match 1", "schema": {"enum": [true]}, "tests": [ { "description": "true is valid", "data": true, "valid": true }, { "description": "integer one is invalid", "data": 1, "valid": false }, { "description": "float one is invalid", "data": 1.0, "valid": false } ] }, { "description": "enum with 0 does not match false", "schema": {"enum": [0]}, "tests": [ { "description": "false is invalid", "data": false, "valid": false }, { "description": "integer zero is valid", "data": 0, "valid": true }, { "description": "float zero is valid", "data": 0.0, "valid": true } ] }, { "description": "enum with 1 does not match true", "schema": {"enum": [1]}, "tests": [ { "description": "true is invalid", "data": true, "valid": false }, { "description": "integer one is valid", "data": 1, "valid": true }, { "description": "float one is valid", "data": 1.0, "valid": true } ] }, { "description": "nul characters in strings", "schema": { "enum": [ "hello\u0000there" ] }, "tests": [ { "description": "match string with nul", "data": "hello\u0000there", "valid": true }, { "description": "do not match string lacking nul", "data": "hellothere", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/format.json000066400000000000000000000143111477700171100271530ustar00rootroot00000000000000[ { "description": "email format", "schema": { "format": "email" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "ipv4 format", "schema": { "format": "ipv4" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "ipv6 format", "schema": { "format": "ipv6" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "hostname format", "schema": { "format": "hostname" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "date-time format", "schema": { "format": "date-time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "uri format", "schema": { "format": "uri" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/id.json000066400000000000000000000032671477700171100262670ustar00rootroot00000000000000[ { "description": "id inside an enum is not a real identifier", "comment": "the implementation must not be confused by an id buried in the enum", "schema": { "definitions": { "id_in_enum": { "enum": [ { "id": "https://localhost:1234/my_identifier.json", "type": "null" } ] }, "real_id_in_schema": { "id": "https://localhost:1234/my_identifier.json", "type": "string" }, "zzz_id_in_const": { "const": { "id": "https://localhost:1234/my_identifier.json", "type": "null" } } }, "anyOf": [ { "$ref": "#/definitions/id_in_enum" }, { "$ref": "https://localhost:1234/my_identifier.json" } ] }, "tests": [ { "description": "exact match to enum, and type matches", "data": { "id": "https://localhost:1234/my_identifier.json", "type": "null" }, "valid": true }, { "description": "match $ref to id", "data": "a string to match #/definitions/id_in_enum", "valid": true }, { "description": "no match on enum or $ref to id", "data": 1, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/infinite-loop-detection.json000066400000000000000000000017461477700171100324230ustar00rootroot00000000000000[ { "description": "evaluating the same schema location against the same data location twice is not a sign of an infinite loop", "schema": { "definitions": { "int": { "type": "integer" } }, "allOf": [ { "properties": { "foo": { "$ref": "#/definitions/int" } } }, { "additionalProperties": { "$ref": "#/definitions/int" } } ] }, "tests": [ { "description": "passing case", "data": { "foo": 1 }, "valid": true }, { "description": "failing case", "data": { "foo": "a string" }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/items.json000066400000000000000000000146441477700171100270150ustar00rootroot00000000000000[ { "description": "a schema given for items", "schema": { "items": {"type": "integer"} }, "tests": [ { "description": "valid items", "data": [ 1, 2, 3 ], "valid": true }, { "description": "wrong type of items", "data": [1, "x"], "valid": false }, { "description": "ignores non-arrays", "data": {"foo" : "bar"}, "valid": true }, { "description": "JavaScript pseudo-array is valid", "data": { "0": "invalid", "length": 1 }, "valid": true } ] }, { "description": "an array of schemas for items", "schema": { "items": [ {"type": "integer"}, {"type": "string"} ] }, "tests": [ { "description": "correct types", "data": [ 1, "foo" ], "valid": true }, { "description": "wrong types", "data": [ "foo", 1 ], "valid": false }, { "description": "incomplete array of items", "data": [ 1 ], "valid": true }, { "description": "array with additional items", "data": [ 1, "foo", true ], "valid": true }, { "description": "empty array", "data": [ ], "valid": true }, { "description": "JavaScript pseudo-array is valid", "data": { "0": "invalid", "1": "valid", "length": 2 }, "valid": true } ] }, { "description": "items and subitems", "schema": { "definitions": { "item": { "type": "array", "additionalItems": false, "items": [ { "$ref": "#/definitions/sub-item" }, { "$ref": "#/definitions/sub-item" } ] }, "sub-item": { "type": "object", "required": ["foo"] } }, "type": "array", "additionalItems": false, "items": [ { "$ref": "#/definitions/item" }, { "$ref": "#/definitions/item" }, { "$ref": "#/definitions/item" } ] }, "tests": [ { "description": "valid items", "data": [ [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": true }, { "description": "too many items", "data": [ [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "too many sub-items", "data": [ [ {"foo": null}, {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "wrong item", "data": [ {"foo": null}, [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "wrong sub-item", "data": [ [ {}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "fewer items is valid", "data": [ [ {"foo": null} ], [ {"foo": null} ] ], "valid": true } ] }, { "description": "nested items", "schema": { "type": "array", "items": { "type": "array", "items": { "type": "array", "items": { "type": "array", "items": { "type": "number" } } } } }, "tests": [ { "description": "valid nested array", "data": [[[[1]], [[2],[3]]], [[[4], [5], [6]]]], "valid": true }, { "description": "nested array with invalid type", "data": [[[["1"]], [[2],[3]]], [[[4], [5], [6]]]], "valid": false }, { "description": "not deep enough", "data": [[[1], [2],[3]], [[4], [5], [6]]], "valid": false } ] }, { "description": "items with null instance elements", "schema": { "items": { "type": "null" } }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] }, { "description": "array-form items with null instance elements", "schema": { "items": [ { "type": "null" } ] }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/maxItems.json000066400000000000000000000013021477700171100274460ustar00rootroot00000000000000[ { "description": "maxItems validation", "schema": {"maxItems": 2}, "tests": [ { "description": "shorter is valid", "data": [1], "valid": true }, { "description": "exact length is valid", "data": [1, 2], "valid": true }, { "description": "too long is invalid", "data": [1, 2, 3], "valid": false }, { "description": "ignores non-arrays", "data": "foobar", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/maxLength.json000066400000000000000000000016001477700171100276070ustar00rootroot00000000000000[ { "description": "maxLength validation", "schema": {"maxLength": 2}, "tests": [ { "description": "shorter is valid", "data": "f", "valid": true }, { "description": "exact length is valid", "data": "fo", "valid": true }, { "description": "too long is invalid", "data": "foo", "valid": false }, { "description": "ignores non-strings", "data": 100, "valid": true }, { "description": "two supplementary Unicode code points is long enough", "data": "\uD83D\uDCA9\uD83D\uDCA9", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/maxProperties.json000066400000000000000000000027321477700171100305310ustar00rootroot00000000000000[ { "description": "maxProperties validation", "schema": {"maxProperties": 2}, "tests": [ { "description": "shorter is valid", "data": {"foo": 1}, "valid": true }, { "description": "exact length is valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "too long is invalid", "data": {"foo": 1, "bar": 2, "baz": 3}, "valid": false }, { "description": "ignores arrays", "data": [1, 2, 3], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "maxProperties = 0 means the object is empty", "schema": { "maxProperties": 0 }, "tests": [ { "description": "no properties is valid", "data": {}, "valid": true }, { "description": "one property is invalid", "data": { "foo": 1 }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/maximum.json000066400000000000000000000052621477700171100273450ustar00rootroot00000000000000[ { "description": "maximum validation", "schema": {"maximum": 3.0}, "tests": [ { "description": "below the maximum is valid", "data": 2.6, "valid": true }, { "description": "boundary point is valid", "data": 3.0, "valid": true }, { "description": "above the maximum is invalid", "data": 3.5, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] }, { "description": "maximum validation with unsigned integer", "schema": {"maximum": 300}, "tests": [ { "description": "below the maximum is invalid", "data": 299.97, "valid": true }, { "description": "boundary point integer is valid", "data": 300, "valid": true }, { "description": "boundary point float is valid", "data": 300.00, "valid": true }, { "description": "above the maximum is invalid", "data": 300.5, "valid": false } ] }, { "description": "maximum validation (explicit false exclusivity)", "schema": {"maximum": 3.0, "exclusiveMaximum": false}, "tests": [ { "description": "below the maximum is valid", "data": 2.6, "valid": true }, { "description": "boundary point is valid", "data": 3.0, "valid": true }, { "description": "above the maximum is invalid", "data": 3.5, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] }, { "description": "exclusiveMaximum validation", "schema": { "maximum": 3.0, "exclusiveMaximum": true }, "tests": [ { "description": "below the maximum is still valid", "data": 2.2, "valid": true }, { "description": "boundary point is invalid", "data": 3.0, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/minItems.json000066400000000000000000000012651477700171100274540ustar00rootroot00000000000000[ { "description": "minItems validation", "schema": {"minItems": 1}, "tests": [ { "description": "longer is valid", "data": [1, 2], "valid": true }, { "description": "exact length is valid", "data": [1], "valid": true }, { "description": "too short is invalid", "data": [], "valid": false }, { "description": "ignores non-arrays", "data": "", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/minLength.json000066400000000000000000000015661477700171100276200ustar00rootroot00000000000000[ { "description": "minLength validation", "schema": {"minLength": 2}, "tests": [ { "description": "longer is valid", "data": "foo", "valid": true }, { "description": "exact length is valid", "data": "fo", "valid": true }, { "description": "too short is invalid", "data": "f", "valid": false }, { "description": "ignores non-strings", "data": 1, "valid": true }, { "description": "one supplementary Unicode code point is not long enough", "data": "\uD83D\uDCA9", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/minProperties.json000066400000000000000000000017541477700171100305320ustar00rootroot00000000000000[ { "description": "minProperties validation", "schema": {"minProperties": 1}, "tests": [ { "description": "longer is valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "exact length is valid", "data": {"foo": 1}, "valid": true }, { "description": "too short is invalid", "data": {}, "valid": false }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores strings", "data": "", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/minimum.json000066400000000000000000000061701477700171100273420ustar00rootroot00000000000000[ { "description": "minimum validation", "schema": {"minimum": 1.1}, "tests": [ { "description": "above the minimum is valid", "data": 2.6, "valid": true }, { "description": "boundary point is valid", "data": 1.1, "valid": true }, { "description": "below the minimum is invalid", "data": 0.6, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] }, { "description": "minimum validation (explicit false exclusivity)", "schema": {"minimum": 1.1, "exclusiveMinimum": false}, "tests": [ { "description": "above the minimum is valid", "data": 2.6, "valid": true }, { "description": "boundary point is valid", "data": 1.1, "valid": true }, { "description": "below the minimum is invalid", "data": 0.6, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] }, { "description": "exclusiveMinimum validation", "schema": { "minimum": 1.1, "exclusiveMinimum": true }, "tests": [ { "description": "above the minimum is still valid", "data": 1.2, "valid": true }, { "description": "boundary point is invalid", "data": 1.1, "valid": false } ] }, { "description": "minimum validation with signed integer", "schema": {"minimum": -2}, "tests": [ { "description": "negative above the minimum is valid", "data": -1, "valid": true }, { "description": "positive above the minimum is valid", "data": 0, "valid": true }, { "description": "boundary point is valid", "data": -2, "valid": true }, { "description": "boundary point with float is valid", "data": -2.0, "valid": true }, { "description": "float below the minimum is invalid", "data": -2.0001, "valid": false }, { "description": "int below the minimum is invalid", "data": -3, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/multipleOf.json000066400000000000000000000042151477700171100300050ustar00rootroot00000000000000[ { "description": "by int", "schema": {"multipleOf": 2}, "tests": [ { "description": "int by int", "data": 10, "valid": true }, { "description": "int by int fail", "data": 7, "valid": false }, { "description": "ignores non-numbers", "data": "foo", "valid": true } ] }, { "description": "by number", "schema": {"multipleOf": 1.5}, "tests": [ { "description": "zero is multiple of anything", "data": 0, "valid": true }, { "description": "4.5 is multiple of 1.5", "data": 4.5, "valid": true }, { "description": "35 is not multiple of 1.5", "data": 35, "valid": false } ] }, { "description": "by small number", "schema": {"multipleOf": 0.0001}, "tests": [ { "description": "0.0075 is multiple of 0.0001", "data": 0.0075, "valid": true }, { "description": "0.00751 is not multiple of 0.0001", "data": 0.00751, "valid": false } ] }, { "description": "float division = inf", "schema": {"type": "integer", "multipleOf": 0.123456789}, "tests": [ { "description": "invalid, but naive implementations may raise an overflow error", "data": 1e308, "valid": false } ] }, { "description": "small multiple of large integer", "schema": {"type": "integer", "multipleOf": 1e-8}, "tests": [ { "description": "any integer is a multiple of 1e-8", "data": 12391239123, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/not.json000066400000000000000000000043321477700171100264650ustar00rootroot00000000000000[ { "description": "not", "schema": { "not": {"type": "integer"} }, "tests": [ { "description": "allowed", "data": "foo", "valid": true }, { "description": "disallowed", "data": 1, "valid": false } ] }, { "description": "not multiple types", "schema": { "not": {"type": ["integer", "boolean"]} }, "tests": [ { "description": "valid", "data": "foo", "valid": true }, { "description": "mismatch", "data": 1, "valid": false }, { "description": "other mismatch", "data": true, "valid": false } ] }, { "description": "not more complex schema", "schema": { "not": { "type": "object", "properties": { "foo": { "type": "string" } } } }, "tests": [ { "description": "match", "data": 1, "valid": true }, { "description": "other match", "data": {"foo": 1}, "valid": true }, { "description": "mismatch", "data": {"foo": "bar"}, "valid": false } ] }, { "description": "forbidden property", "schema": { "properties": { "foo": { "not": {} } } }, "tests": [ { "description": "property present", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "property absent", "data": {"bar": 1, "baz": 2}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/oneOf.json000066400000000000000000000136231477700171100267360ustar00rootroot00000000000000[ { "description": "oneOf", "schema": { "oneOf": [ { "type": "integer" }, { "minimum": 2 } ] }, "tests": [ { "description": "first oneOf valid", "data": 1, "valid": true }, { "description": "second oneOf valid", "data": 2.5, "valid": true }, { "description": "both oneOf valid", "data": 3, "valid": false }, { "description": "neither oneOf valid", "data": 1.5, "valid": false } ] }, { "description": "oneOf with base schema", "schema": { "type": "string", "oneOf" : [ { "minLength": 2 }, { "maxLength": 4 } ] }, "tests": [ { "description": "mismatch base schema", "data": 3, "valid": false }, { "description": "one oneOf valid", "data": "foobar", "valid": true }, { "description": "both oneOf valid", "data": "foo", "valid": false } ] }, { "description": "oneOf complex types", "schema": { "oneOf": [ { "properties": { "bar": {"type": "integer"} }, "required": ["bar"] }, { "properties": { "foo": {"type": "string"} }, "required": ["foo"] } ] }, "tests": [ { "description": "first oneOf valid (complex)", "data": {"bar": 2}, "valid": true }, { "description": "second oneOf valid (complex)", "data": {"foo": "baz"}, "valid": true }, { "description": "both oneOf valid (complex)", "data": {"foo": "baz", "bar": 2}, "valid": false }, { "description": "neither oneOf valid (complex)", "data": {"foo": 2, "bar": "quux"}, "valid": false } ] }, { "description": "oneOf with empty schema", "schema": { "oneOf": [ { "type": "number" }, {} ] }, "tests": [ { "description": "one valid - valid", "data": "foo", "valid": true }, { "description": "both valid - invalid", "data": 123, "valid": false } ] }, { "description": "oneOf with required", "schema": { "type": "object", "oneOf": [ { "required": ["foo", "bar"] }, { "required": ["foo", "baz"] } ] }, "tests": [ { "description": "both invalid - invalid", "data": {"bar": 2}, "valid": false }, { "description": "first valid - valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "second valid - valid", "data": {"foo": 1, "baz": 3}, "valid": true }, { "description": "both valid - invalid", "data": {"foo": 1, "bar": 2, "baz" : 3}, "valid": false } ] }, { "description": "oneOf with missing optional property", "schema": { "oneOf": [ { "properties": { "bar": {}, "baz": {} }, "required": ["bar"] }, { "properties": { "foo": {} }, "required": ["foo"] } ] }, "tests": [ { "description": "first oneOf valid", "data": {"bar": 8}, "valid": true }, { "description": "second oneOf valid", "data": {"foo": "foo"}, "valid": true }, { "description": "both oneOf valid", "data": {"foo": "foo", "bar": 8}, "valid": false }, { "description": "neither oneOf valid", "data": {"baz": "quux"}, "valid": false } ] }, { "description": "nested oneOf, to check validation semantics", "schema": { "oneOf": [ { "oneOf": [ { "type": "null" } ] } ] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "anything non-null is invalid", "data": 123, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/000077500000000000000000000000001477700171100266155ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/bignum.json000066400000000000000000000054731477700171100310020ustar00rootroot00000000000000[ { "description": "integer", "schema": { "type": "integer" }, "tests": [ { "description": "a bignum is an integer", "data": 12345678910111213141516171819202122232425262728293031, "valid": true }, { "description": "a negative bignum is an integer", "data": -12345678910111213141516171819202122232425262728293031, "valid": true } ] }, { "description": "number", "schema": { "type": "number" }, "tests": [ { "description": "a bignum is a number", "data": 98249283749234923498293171823948729348710298301928331, "valid": true }, { "description": "a negative bignum is a number", "data": -98249283749234923498293171823948729348710298301928331, "valid": true } ] }, { "description": "string", "schema": { "type": "string" }, "tests": [ { "description": "a bignum is not a string", "data": 98249283749234923498293171823948729348710298301928331, "valid": false } ] }, { "description": "maximum integer comparison", "schema": { "maximum": 18446744073709551615 }, "tests": [ { "description": "comparison works for high numbers", "data": 18446744073709551600, "valid": true } ] }, { "description": "float comparison with high precision", "schema": { "maximum": 972783798187987123879878123.18878137, "exclusiveMaximum": true }, "tests": [ { "description": "comparison works for high numbers", "data": 972783798187987123879878123.188781371, "valid": false } ] }, { "description": "minimum integer comparison", "schema": { "minimum": -18446744073709551615 }, "tests": [ { "description": "comparison works for very negative numbers", "data": -18446744073709551600, "valid": true } ] }, { "description": "float comparison with high precision on negative numbers", "schema": { "minimum": -972783798187987123879878123.18878137, "exclusiveMinimum": true }, "tests": [ { "description": "comparison works for very negative numbers", "data": -972783798187987123879878123.188781371, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/ecmascript-regex.json000066400000000000000000000440671477700171100327650ustar00rootroot00000000000000[ { "description": "ECMA 262 regex $ does not match trailing newline", "schema": { "type": "string", "pattern": "^abc$" }, "tests": [ { "description": "matches in Python, but not in ECMA 262", "data": "abc\\n", "valid": false }, { "description": "matches", "data": "abc", "valid": true } ] }, { "description": "ECMA 262 regex converts \\t to horizontal tab", "schema": { "type": "string", "pattern": "^\\t$" }, "tests": [ { "description": "does not match", "data": "\\t", "valid": false }, { "description": "matches", "data": "\u0009", "valid": true } ] }, { "description": "ECMA 262 regex escapes control codes with \\c and upper letter", "schema": { "type": "string", "pattern": "^\\cC$" }, "tests": [ { "description": "does not match", "data": "\\cC", "valid": false }, { "description": "matches", "data": "\u0003", "valid": true } ] }, { "description": "ECMA 262 regex escapes control codes with \\c and lower letter", "schema": { "type": "string", "pattern": "^\\cc$" }, "tests": [ { "description": "does not match", "data": "\\cc", "valid": false }, { "description": "matches", "data": "\u0003", "valid": true } ] }, { "description": "ECMA 262 \\d matches ascii digits only", "schema": { "type": "string", "pattern": "^\\d$" }, "tests": [ { "description": "ASCII zero matches", "data": "0", "valid": true }, { "description": "NKO DIGIT ZERO does not match (unlike e.g. Python)", "data": "߀", "valid": false }, { "description": "NKO DIGIT ZERO (as \\u escape) does not match", "data": "\u07c0", "valid": false } ] }, { "description": "ECMA 262 \\D matches everything but ascii digits", "schema": { "type": "string", "pattern": "^\\D$" }, "tests": [ { "description": "ASCII zero does not match", "data": "0", "valid": false }, { "description": "NKO DIGIT ZERO matches (unlike e.g. Python)", "data": "߀", "valid": true }, { "description": "NKO DIGIT ZERO (as \\u escape) matches", "data": "\u07c0", "valid": true } ] }, { "description": "ECMA 262 \\w matches ascii letters only", "schema": { "type": "string", "pattern": "^\\w$" }, "tests": [ { "description": "ASCII 'a' matches", "data": "a", "valid": true }, { "description": "latin-1 e-acute does not match (unlike e.g. Python)", "data": "é", "valid": false } ] }, { "description": "ECMA 262 \\W matches everything but ascii letters", "schema": { "type": "string", "pattern": "^\\W$" }, "tests": [ { "description": "ASCII 'a' does not match", "data": "a", "valid": false }, { "description": "latin-1 e-acute matches (unlike e.g. Python)", "data": "é", "valid": true } ] }, { "description": "ECMA 262 \\s matches whitespace", "schema": { "type": "string", "pattern": "^\\s$" }, "tests": [ { "description": "ASCII space matches", "data": " ", "valid": true }, { "description": "Character tabulation matches", "data": "\t", "valid": true }, { "description": "Line tabulation matches", "data": "\u000b", "valid": true }, { "description": "Form feed matches", "data": "\u000c", "valid": true }, { "description": "latin-1 non-breaking-space matches", "data": "\u00a0", "valid": true }, { "description": "zero-width whitespace matches", "data": "\ufeff", "valid": true }, { "description": "line feed matches (line terminator)", "data": "\u000a", "valid": true }, { "description": "paragraph separator matches (line terminator)", "data": "\u2029", "valid": true }, { "description": "EM SPACE matches (Space_Separator)", "data": "\u2003", "valid": true }, { "description": "Non-whitespace control does not match", "data": "\u0001", "valid": false }, { "description": "Non-whitespace does not match", "data": "\u2013", "valid": false } ] }, { "description": "ECMA 262 \\S matches everything but whitespace", "schema": { "type": "string", "pattern": "^\\S$" }, "tests": [ { "description": "ASCII space does not match", "data": " ", "valid": false }, { "description": "Character tabulation does not match", "data": "\t", "valid": false }, { "description": "Line tabulation does not match", "data": "\u000b", "valid": false }, { "description": "Form feed does not match", "data": "\u000c", "valid": false }, { "description": "latin-1 non-breaking-space does not match", "data": "\u00a0", "valid": false }, { "description": "zero-width whitespace does not match", "data": "\ufeff", "valid": false }, { "description": "line feed does not match (line terminator)", "data": "\u000a", "valid": false }, { "description": "paragraph separator does not match (line terminator)", "data": "\u2029", "valid": false }, { "description": "EM SPACE does not match (Space_Separator)", "data": "\u2003", "valid": false }, { "description": "Non-whitespace control matches", "data": "\u0001", "valid": true }, { "description": "Non-whitespace matches", "data": "\u2013", "valid": true } ] }, { "description": "patterns always use unicode semantics with pattern", "schema": { "pattern": "\\p{Letter}cole" }, "tests": [ { "description": "ascii character in json string", "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", "valid": true }, { "description": "literal unicode character in json string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": true }, { "description": "unicode character in hex format in string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": true }, { "description": "unicode matching is case-sensitive", "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", "valid": false } ] }, { "description": "\\w in patterns matches [A-Za-z0-9_], not unicode letters", "schema": { "pattern": "\\wcole" }, "tests": [ { "description": "ascii character in json string", "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", "valid": true }, { "description": "literal unicode character in json string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "unicode character in hex format in string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "unicode matching is case-sensitive", "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", "valid": false } ] }, { "description": "pattern with ASCII ranges", "schema": { "pattern": "[a-z]cole" }, "tests": [ { "description": "literal unicode character in json string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "unicode character in hex format in string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "ascii characters match", "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", "valid": true } ] }, { "description": "\\d in pattern matches [0-9], not unicode digits", "schema": { "pattern": "^\\d+$" }, "tests": [ { "description": "ascii digits", "data": "42", "valid": true }, { "description": "ascii non-digits", "data": "-%#", "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": "৪২", "valid": false } ] }, { "description": "pattern with non-ASCII digits", "schema": { "pattern": "^\\p{digit}+$" }, "tests": [ { "description": "ascii digits", "data": "42", "valid": true }, { "description": "ascii non-digits", "data": "-%#", "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": "৪২", "valid": true } ] }, { "description": "patterns always use unicode semantics with patternProperties", "schema": { "type": "object", "patternProperties": { "\\p{Letter}cole": {} }, "additionalProperties": false }, "tests": [ { "description": "ascii character in json string", "data": { "l'ecole": "pas de vraie vie" }, "valid": true }, { "description": "literal unicode character in json string", "data": { "l'école": "pas de vraie vie" }, "valid": true }, { "description": "unicode character in hex format in string", "data": { "l'\u00e9cole": "pas de vraie vie" }, "valid": true }, { "description": "unicode matching is case-sensitive", "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, "valid": false } ] }, { "description": "\\w in patternProperties matches [A-Za-z0-9_], not unicode letters", "schema": { "type": "object", "patternProperties": { "\\wcole": {} }, "additionalProperties": false }, "tests": [ { "description": "ascii character in json string", "data": { "l'ecole": "pas de vraie vie" }, "valid": true }, { "description": "literal unicode character in json string", "data": { "l'école": "pas de vraie vie" }, "valid": false }, { "description": "unicode character in hex format in string", "data": { "l'\u00e9cole": "pas de vraie vie" }, "valid": false }, { "description": "unicode matching is case-sensitive", "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, "valid": false } ] }, { "description": "patternProperties with ASCII ranges", "schema": { "type": "object", "patternProperties": { "[a-z]cole": {} }, "additionalProperties": false }, "tests": [ { "description": "literal unicode character in json string", "data": { "l'école": "pas de vraie vie" }, "valid": false }, { "description": "unicode character in hex format in string", "data": { "l'\u00e9cole": "pas de vraie vie" }, "valid": false }, { "description": "ascii characters match", "data": { "l'ecole": "pas de vraie vie" }, "valid": true } ] }, { "description": "\\d in patternProperties matches [0-9], not unicode digits", "schema": { "type": "object", "patternProperties": { "^\\d+$": {} }, "additionalProperties": false }, "tests": [ { "description": "ascii digits", "data": { "42": "life, the universe, and everything" }, "valid": true }, { "description": "ascii non-digits", "data": { "-%#": "spending the year dead for tax reasons" }, "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": { "৪২": "khajit has wares if you have coin" }, "valid": false } ] }, { "description": "patternProperties with non-ASCII digits", "schema": { "type": "object", "patternProperties": { "^\\p{digit}+$": {} }, "additionalProperties": false }, "tests": [ { "description": "ascii digits", "data": { "42": "life, the universe, and everything" }, "valid": true }, { "description": "ascii non-digits", "data": { "-%#": "spending the year dead for tax reasons" }, "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": { "৪২": "khajit has wares if you have coin" }, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/float-overflow.json000066400000000000000000000005501477700171100324560ustar00rootroot00000000000000[ { "description": "all integers are multiples of 0.5, if overflow is handled", "schema": {"type": "number", "multipleOf": 0.5}, "tests": [ { "description": "valid if optional overflow handling is implemented", "data": 1e308, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/000077500000000000000000000000001477700171100301055ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/date-time.json000066400000000000000000000110601477700171100326470ustar00rootroot00000000000000[ { "description": "validation of date-time strings", "schema": { "format": "date-time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid date-time string", "data": "1963-06-19T08:30:06.283185Z", "valid": true }, { "description": "a valid date-time string without second fraction", "data": "1963-06-19T08:30:06Z", "valid": true }, { "description": "a valid date-time string with plus offset", "data": "1937-01-01T12:00:27.87+00:20", "valid": true }, { "description": "a valid date-time string with minus offset", "data": "1990-12-31T15:59:50.123-08:00", "valid": true }, { "description": "a valid date-time with a leap second, UTC", "data": "1998-12-31T23:59:60Z", "valid": true }, { "description": "a valid date-time with a leap second, with minus offset", "data": "1998-12-31T15:59:60.123-08:00", "valid": true }, { "description": "an invalid date-time past leap second, UTC", "data": "1998-12-31T23:59:61Z", "valid": false }, { "description": "an invalid date-time with leap second on a wrong minute, UTC", "data": "1998-12-31T23:58:60Z", "valid": false }, { "description": "an invalid date-time with leap second on a wrong hour, UTC", "data": "1998-12-31T22:59:60Z", "valid": false }, { "description": "an invalid day in date-time string", "data": "1990-02-31T15:59:59.123-08:00", "valid": false }, { "description": "an invalid offset in date-time string", "data": "1990-12-31T15:59:59-24:00", "valid": false }, { "description": "an invalid closing Z after time-zone offset", "data": "1963-06-19T08:30:06.28123+01:00Z", "valid": false }, { "description": "an invalid date-time string", "data": "06/19/1963 08:30:06 PST", "valid": false }, { "description": "case-insensitive T and Z", "data": "1963-06-19t08:30:06.283185z", "valid": true }, { "description": "only RFC3339 not all of ISO 8601 are valid", "data": "2013-350T01:01:01", "valid": false }, { "description": "invalid non-padded month dates", "data": "1963-6-19T08:30:06.283185Z", "valid": false }, { "description": "invalid non-padded day dates", "data": "1963-06-1T08:30:06.283185Z", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4) in date portion", "data": "1963-06-1৪T00:00:00Z", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4) in time portion", "data": "1963-06-11T0৪:00:00Z", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/email.json000066400000000000000000000051041477700171100320670ustar00rootroot00000000000000[ { "description": "validation of e-mail addresses", "schema": { "format": "email" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid e-mail address", "data": "joe.bloggs@example.com", "valid": true }, { "description": "an invalid e-mail address", "data": "2962", "valid": false }, { "description": "tilde in local part is valid", "data": "te~st@example.com", "valid": true }, { "description": "tilde before local part is valid", "data": "~test@example.com", "valid": true }, { "description": "tilde after local part is valid", "data": "test~@example.com", "valid": true }, { "description": "dot before local part is not valid", "data": ".test@example.com", "valid": false }, { "description": "dot after local part is not valid", "data": "test.@example.com", "valid": false }, { "description": "two separated dots inside local part are valid", "data": "te.s.t@example.com", "valid": true }, { "description": "two subsequent dots inside local part are not valid", "data": "te..st@example.com", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/hostname.json000066400000000000000000000073671477700171100326330ustar00rootroot00000000000000[ { "description": "validation of host names", "schema": { "format": "hostname" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid host name", "data": "www.example.com", "valid": true }, { "description": "a valid punycoded IDN hostname", "data": "xn--4gbwdl.xn--wgbh1c", "valid": true }, { "description": "a host name starting with an illegal character", "data": "-a-host-name-that-starts-with--", "valid": false }, { "description": "a host name containing illegal characters", "data": "not_a_valid_host_name", "valid": false }, { "description": "a host name with a component too long", "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", "valid": false }, { "description": "starts with hyphen", "data": "-hostname", "valid": false }, { "description": "ends with hyphen", "data": "hostname-", "valid": false }, { "description": "starts with underscore", "data": "_hostname", "valid": false }, { "description": "ends with underscore", "data": "hostname_", "valid": false }, { "description": "contains underscore", "data": "host_name", "valid": false }, { "description": "maximum label length", "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.com", "valid": true }, { "description": "exceeds maximum label length", "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl.com", "valid": false }, { "description": "single label", "data": "hostname", "valid": true }, { "description": "single label with hyphen", "data": "host-name", "valid": true }, { "description": "single label with digits", "data": "h0stn4me", "valid": true }, { "description": "single label ending with digit", "data": "hostnam3", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/ipv4.json000066400000000000000000000056621477700171100316730ustar00rootroot00000000000000[ { "description": "validation of IP addresses", "schema": { "format": "ipv4" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid IP address", "data": "192.168.0.1", "valid": true }, { "description": "an IP address with too many components", "data": "127.0.0.0.1", "valid": false }, { "description": "an IP address with out-of-range values", "data": "256.256.256.256", "valid": false }, { "description": "an IP address without 4 components", "data": "127.0", "valid": false }, { "description": "an IP address as an integer", "data": "0x7f000001", "valid": false }, { "description": "an IP address as an integer (decimal)", "data": "2130706433", "valid": false }, { "description": "invalid leading zeroes, as they are treated as octals", "comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/", "data": "087.10.0.1", "valid": false }, { "description": "value without leading zero is valid", "data": "87.10.0.1", "valid": true }, { "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২7.0.0.1", "valid": false }, { "description": "netmask is not a part of ipv4 address", "data": "192.168.1.0/24", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/ipv6.json000066400000000000000000000154371477700171100316760ustar00rootroot00000000000000[ { "description": "validation of IPv6 addresses", "schema": { "format": "ipv6" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid IPv6 address", "data": "::1", "valid": true }, { "description": "an IPv6 address with out-of-range values", "data": "12345::", "valid": false }, { "description": "trailing 4 hex symbols is valid", "data": "::abef", "valid": true }, { "description": "trailing 5 hex symbols is invalid", "data": "::abcef", "valid": false }, { "description": "an IPv6 address with too many components", "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", "valid": false }, { "description": "an IPv6 address containing illegal characters", "data": "::laptop", "valid": false }, { "description": "no digits is valid", "data": "::", "valid": true }, { "description": "leading colons is valid", "data": "::42:ff:1", "valid": true }, { "description": "trailing colons is valid", "data": "d6::", "valid": true }, { "description": "missing leading octet is invalid", "data": ":2:3:4:5:6:7:8", "valid": false }, { "description": "missing trailing octet is invalid", "data": "1:2:3:4:5:6:7:", "valid": false }, { "description": "missing leading octet with omitted octets later", "data": ":2:3:4::8", "valid": false }, { "description": "single set of double colons in the middle is valid", "data": "1:d6::42", "valid": true }, { "description": "two sets of double colons is invalid", "data": "1::d6::42", "valid": false }, { "description": "mixed format with the ipv4 section as decimal octets", "data": "1::d6:192.168.0.1", "valid": true }, { "description": "mixed format with double colons between the sections", "data": "1:2::192.168.0.1", "valid": true }, { "description": "mixed format with ipv4 section with octet out of range", "data": "1::2:192.168.256.1", "valid": false }, { "description": "mixed format with ipv4 section with a hex octet", "data": "1::2:192.168.ff.1", "valid": false }, { "description": "mixed format with leading double colons (ipv4-mapped ipv6 address)", "data": "::ffff:192.168.0.1", "valid": true }, { "description": "triple colons is invalid", "data": "1:2:3:4:5:::8", "valid": false }, { "description": "8 octets", "data": "1:2:3:4:5:6:7:8", "valid": true }, { "description": "insufficient octets without double colons", "data": "1:2:3:4:5:6:7", "valid": false }, { "description": "no colons is invalid", "data": "1", "valid": false }, { "description": "ipv4 is not ipv6", "data": "127.0.0.1", "valid": false }, { "description": "ipv4 segment must have 4 octets", "data": "1:2:3:4:1.2.3", "valid": false }, { "description": "leading whitespace is invalid", "data": " ::1", "valid": false }, { "description": "trailing whitespace is invalid", "data": "::1 ", "valid": false }, { "description": "netmask is not a part of ipv6 address", "data": "fe80::/64", "valid": false }, { "description": "zone id is not a part of ipv6 address", "data": "fe80::a%eth1", "valid": false }, { "description": "a long valid ipv6", "data": "1000:1000:1000:1000:1000:1000:255.255.255.255", "valid": true }, { "description": "a long invalid ipv6, below length limit, first", "data": "100:100:100:100:100:100:255.255.255.255.255", "valid": false }, { "description": "a long invalid ipv6, below length limit, second", "data": "100:100:100:100:100:100:100:255.255.255.255", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4)", "data": "1:2:3:4:5:6:7:৪", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4) in the IPv4 portion", "data": "1:2::192.16৪.0.1", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/unknown.json000066400000000000000000000022631477700171100325020ustar00rootroot00000000000000[ { "description": "unknown format", "schema": { "format": "unknown" }, "tests": [ { "description": "unknown formats ignore integers", "data": 12, "valid": true }, { "description": "unknown formats ignore floats", "data": 13.7, "valid": true }, { "description": "unknown formats ignore objects", "data": {}, "valid": true }, { "description": "unknown formats ignore arrays", "data": [], "valid": true }, { "description": "unknown formats ignore booleans", "data": false, "valid": true }, { "description": "unknown formats ignore nulls", "data": null, "valid": true }, { "description": "unknown formats ignore strings", "data": "string", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/uri.json000066400000000000000000000110341477700171100315760ustar00rootroot00000000000000[ { "description": "validation of URIs", "schema": { "format": "uri" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid URL with anchor tag", "data": "http://foo.bar/?baz=qux#quux", "valid": true }, { "description": "a valid URL with anchor tag and parentheses", "data": "http://foo.com/blah_(wikipedia)_blah#cite-1", "valid": true }, { "description": "a valid URL with URL-encoded stuff", "data": "http://foo.bar/?q=Test%20URL-encoded%20stuff", "valid": true }, { "description": "a valid puny-coded URL ", "data": "http://xn--nw2a.xn--j6w193g/", "valid": true }, { "description": "a valid URL with many special characters", "data": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", "valid": true }, { "description": "a valid URL based on IPv4", "data": "http://223.255.255.254", "valid": true }, { "description": "a valid URL with ftp scheme", "data": "ftp://ftp.is.co.za/rfc/rfc1808.txt", "valid": true }, { "description": "a valid URL for a simple text file", "data": "http://www.ietf.org/rfc/rfc2396.txt", "valid": true }, { "description": "a valid URL ", "data": "ldap://[2001:db8::7]/c=GB?objectClass?one", "valid": true }, { "description": "a valid mailto URI", "data": "mailto:John.Doe@example.com", "valid": true }, { "description": "a valid newsgroup URI", "data": "news:comp.infosystems.www.servers.unix", "valid": true }, { "description": "a valid tel URI", "data": "tel:+1-816-555-1212", "valid": true }, { "description": "a valid URN", "data": "urn:oasis:names:specification:docbook:dtd:xml:4.1.2", "valid": true }, { "description": "an invalid protocol-relative URI Reference", "data": "//foo.bar/?baz=qux#quux", "valid": false }, { "description": "an invalid relative URI Reference", "data": "/abc", "valid": false }, { "description": "an invalid URI", "data": "\\\\WINDOWS\\fileshare", "valid": false }, { "description": "an invalid URI though valid URI reference", "data": "abc", "valid": false }, { "description": "an invalid URI with spaces", "data": "http:// shouldfail.com", "valid": false }, { "description": "an invalid URI with spaces and missing scheme", "data": ":// should fail", "valid": false }, { "description": "an invalid URI with comma in scheme", "data": "bar,baz:foo", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/non-bmp-regex.json000066400000000000000000000045361477700171100321760ustar00rootroot00000000000000[ { "description": "Proper UTF-16 surrogate pair handling: pattern", "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", "schema": { "pattern": "^🐲*$" }, "tests": [ { "description": "matches empty", "data": "", "valid": true }, { "description": "matches single", "data": "🐲", "valid": true }, { "description": "matches two", "data": "🐲🐲", "valid": true }, { "description": "doesn't match one", "data": "🐉", "valid": false }, { "description": "doesn't match two", "data": "🐉🐉", "valid": false }, { "description": "doesn't match one ASCII", "data": "D", "valid": false }, { "description": "doesn't match two ASCII", "data": "DD", "valid": false } ] }, { "description": "Proper UTF-16 surrogate pair handling: patternProperties", "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", "schema": { "patternProperties": { "^🐲*$": { "type": "integer" } } }, "tests": [ { "description": "matches empty", "data": { "": 1 }, "valid": true }, { "description": "matches single", "data": { "🐲": 1 }, "valid": true }, { "description": "matches two", "data": { "🐲🐲": 1 }, "valid": true }, { "description": "doesn't match one", "data": { "🐲": "hello" }, "valid": false }, { "description": "doesn't match two", "data": { "🐲🐲": "hello" }, "valid": false } ] } ] zeroTerminatedFloats.json000066400000000000000000000006001477700171100335720ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional[ { "description": "some languages do not distinguish between different types of numeric value", "schema": { "type": "integer" }, "tests": [ { "description": "a float is not an integer even without fractional part", "data": 1.0, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/pattern.json000066400000000000000000000030031477700171100273340ustar00rootroot00000000000000[ { "description": "pattern validation", "schema": {"pattern": "^a*$"}, "tests": [ { "description": "a matching pattern is valid", "data": "aaa", "valid": true }, { "description": "a non-matching pattern is invalid", "data": "abc", "valid": false }, { "description": "ignores booleans", "data": true, "valid": true }, { "description": "ignores integers", "data": 123, "valid": true }, { "description": "ignores floats", "data": 1.0, "valid": true }, { "description": "ignores objects", "data": {}, "valid": true }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores null", "data": null, "valid": true } ] }, { "description": "pattern is not anchored", "schema": {"pattern": "a+"}, "tests": [ { "description": "matches a substring", "data": "xxaayy", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/patternProperties.json000066400000000000000000000077141477700171100314260ustar00rootroot00000000000000[ { "description": "patternProperties validates properties matching a regex", "schema": { "patternProperties": { "f.*o": {"type": "integer"} } }, "tests": [ { "description": "a single valid match is valid", "data": {"foo": 1}, "valid": true }, { "description": "multiple valid matches is valid", "data": {"foo": 1, "foooooo" : 2}, "valid": true }, { "description": "a single invalid match is invalid", "data": {"foo": "bar", "fooooo": 2}, "valid": false }, { "description": "multiple invalid matches is invalid", "data": {"foo": "bar", "foooooo" : "baz"}, "valid": false }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores strings", "data": "", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "multiple simultaneous patternProperties are validated", "schema": { "patternProperties": { "a*": {"type": "integer"}, "aaa*": {"maximum": 20} } }, "tests": [ { "description": "a single valid match is valid", "data": {"a": 21}, "valid": true }, { "description": "a simultaneous match is valid", "data": {"aaaa": 18}, "valid": true }, { "description": "multiple matches is valid", "data": {"a": 21, "aaaa": 18}, "valid": true }, { "description": "an invalid due to one is invalid", "data": {"a": "bar"}, "valid": false }, { "description": "an invalid due to the other is invalid", "data": {"aaaa": 31}, "valid": false }, { "description": "an invalid due to both is invalid", "data": {"aaa": "foo", "aaaa": 31}, "valid": false } ] }, { "description": "regexes are not anchored by default and are case sensitive", "schema": { "patternProperties": { "[0-9]{2,}": { "type": "boolean" }, "X_": { "type": "string" } } }, "tests": [ { "description": "non recognized members are ignored", "data": { "answer 1": "42" }, "valid": true }, { "description": "recognized members are accounted for", "data": { "a31b": null }, "valid": false }, { "description": "regexes are case sensitive", "data": { "a_x_3": 3 }, "valid": true }, { "description": "regexes are case sensitive, 2", "data": { "a_X_3": 3 }, "valid": false } ] }, { "description": "patternProperties with null valued instance properties", "schema": { "patternProperties": { "^.*bar$": {"type": "null"} } }, "tests": [ { "description": "allows null values", "data": {"foobar": null}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/properties.json000066400000000000000000000144151477700171100300640ustar00rootroot00000000000000[ { "description": "object properties validation", "schema": { "properties": { "foo": {"type": "integer"}, "bar": {"type": "string"} } }, "tests": [ { "description": "both properties present and valid is valid", "data": {"foo": 1, "bar": "baz"}, "valid": true }, { "description": "one property invalid is invalid", "data": {"foo": 1, "bar": {}}, "valid": false }, { "description": "both properties invalid is invalid", "data": {"foo": [], "bar": {}}, "valid": false }, { "description": "doesn't invalidate other properties", "data": {"quux": []}, "valid": true }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "properties, patternProperties, additionalProperties interaction", "schema": { "properties": { "foo": {"type": "array", "maxItems": 3}, "bar": {"type": "array"} }, "patternProperties": {"f.o": {"minItems": 2}}, "additionalProperties": {"type": "integer"} }, "tests": [ { "description": "property validates property", "data": {"foo": [1, 2]}, "valid": true }, { "description": "property invalidates property", "data": {"foo": [1, 2, 3, 4]}, "valid": false }, { "description": "patternProperty invalidates property", "data": {"foo": []}, "valid": false }, { "description": "patternProperty validates nonproperty", "data": {"fxo": [1, 2]}, "valid": true }, { "description": "patternProperty invalidates nonproperty", "data": {"fxo": []}, "valid": false }, { "description": "additionalProperty ignores property", "data": {"bar": []}, "valid": true }, { "description": "additionalProperty validates others", "data": {"quux": 3}, "valid": true }, { "description": "additionalProperty invalidates others", "data": {"quux": "foo"}, "valid": false } ] }, { "description": "properties with escaped characters", "schema": { "properties": { "foo\nbar": {"type": "number"}, "foo\"bar": {"type": "number"}, "foo\\bar": {"type": "number"}, "foo\rbar": {"type": "number"}, "foo\tbar": {"type": "number"}, "foo\fbar": {"type": "number"} } }, "tests": [ { "description": "object with all numbers is valid", "data": { "foo\nbar": 1, "foo\"bar": 1, "foo\\bar": 1, "foo\rbar": 1, "foo\tbar": 1, "foo\fbar": 1 }, "valid": true }, { "description": "object with strings is invalid", "data": { "foo\nbar": "1", "foo\"bar": "1", "foo\\bar": "1", "foo\rbar": "1", "foo\tbar": "1", "foo\fbar": "1" }, "valid": false } ] }, { "description": "properties with null valued instance properties", "schema": { "properties": { "foo": {"type": "null"} } }, "tests": [ { "description": "allows null values", "data": {"foo": null}, "valid": true } ] }, { "description": "properties whose names are Javascript object property names", "comment": "Ensure JS implementations don't universally consider e.g. __proto__ to always be present in an object.", "schema": { "properties": { "__proto__": {"type": "number"}, "toString": { "properties": { "length": { "type": "string" } } }, "constructor": {"type": "number"} } }, "tests": [ { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true }, { "description": "none of the properties mentioned", "data": {}, "valid": true }, { "description": "__proto__ not valid", "data": { "__proto__": "foo" }, "valid": false }, { "description": "toString not valid", "data": { "toString": { "length": 37 } }, "valid": false }, { "description": "constructor not valid", "data": { "constructor": { "length": 37 } }, "valid": false }, { "description": "all present and valid", "data": { "__proto__": 12, "toString": { "length": "foo" }, "constructor": 37 }, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/ref.json000066400000000000000000000413321477700171100264420ustar00rootroot00000000000000[ { "description": "root pointer ref", "schema": { "properties": { "foo": {"$ref": "#"} }, "additionalProperties": false }, "tests": [ { "description": "match", "data": {"foo": false}, "valid": true }, { "description": "recursive match", "data": {"foo": {"foo": false}}, "valid": true }, { "description": "mismatch", "data": {"bar": false}, "valid": false }, { "description": "recursive mismatch", "data": {"foo": {"bar": false}}, "valid": false } ] }, { "description": "relative pointer ref to object", "schema": { "properties": { "foo": {"type": "integer"}, "bar": {"$ref": "#/properties/foo"} } }, "tests": [ { "description": "match", "data": {"bar": 3}, "valid": true }, { "description": "mismatch", "data": {"bar": true}, "valid": false } ] }, { "description": "relative pointer ref to array", "schema": { "items": [ {"type": "integer"}, {"$ref": "#/items/0"} ] }, "tests": [ { "description": "match array", "data": [1, 2], "valid": true }, { "description": "mismatch array", "data": [1, "foo"], "valid": false } ] }, { "description": "escaped pointer ref", "schema": { "definitions": { "tilde~field": {"type": "integer"}, "slash/field": {"type": "integer"}, "percent%field": {"type": "integer"} }, "properties": { "tilde": {"$ref": "#/definitions/tilde~0field"}, "slash": {"$ref": "#/definitions/slash~1field"}, "percent": {"$ref": "#/definitions/percent%25field"} } }, "tests": [ { "description": "slash invalid", "data": {"slash": "aoeu"}, "valid": false }, { "description": "tilde invalid", "data": {"tilde": "aoeu"}, "valid": false }, { "description": "percent invalid", "data": {"percent": "aoeu"}, "valid": false }, { "description": "slash valid", "data": {"slash": 123}, "valid": true }, { "description": "tilde valid", "data": {"tilde": 123}, "valid": true }, { "description": "percent valid", "data": {"percent": 123}, "valid": true } ] }, { "description": "nested refs", "schema": { "definitions": { "a": {"type": "integer"}, "b": {"$ref": "#/definitions/a"}, "c": {"$ref": "#/definitions/b"} }, "allOf": [{ "$ref": "#/definitions/c" }] }, "tests": [ { "description": "nested ref valid", "data": 5, "valid": true }, { "description": "nested ref invalid", "data": "a", "valid": false } ] }, { "description": "ref overrides any sibling keywords", "schema": { "definitions": { "reffed": { "type": "array" } }, "properties": { "foo": { "$ref": "#/definitions/reffed", "maxItems": 2 } } }, "tests": [ { "description": "ref valid", "data": { "foo": [] }, "valid": true }, { "description": "ref valid, maxItems ignored", "data": { "foo": [ 1, 2, 3] }, "valid": true }, { "description": "ref invalid", "data": { "foo": "string" }, "valid": false } ] }, { "description": "$ref prevents a sibling id from changing the base uri", "schema": { "id": "http://localhost:1234/sibling_id/base/", "definitions": { "foo": { "id": "http://localhost:1234/sibling_id/foo.json", "type": "string" }, "base_foo": { "$comment": "this canonical uri is http://localhost:1234/sibling_id/base/foo.json", "id": "foo.json", "type": "number" } }, "allOf": [ { "$comment": "$ref resolves to http://localhost:1234/sibling_id/base/foo.json, not http://localhost:1234/sibling_id/foo.json", "id": "http://localhost:1234/sibling_id/", "$ref": "foo.json" } ] }, "tests": [ { "description": "$ref resolves to /definitions/base_foo, data does not validate", "data": "a", "valid": false }, { "description": "$ref resolves to /definitions/base_foo, data validates", "data": 1, "valid": true } ] }, { "description": "remote ref, containing refs itself", "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}, "tests": [ { "description": "remote ref valid", "data": {"minLength": 1}, "valid": true }, { "description": "remote ref invalid", "data": {"minLength": -1}, "valid": false } ] }, { "description": "property named $ref that is not a reference", "schema": { "properties": { "$ref": {"type": "string"} } }, "tests": [ { "description": "property named $ref valid", "data": {"$ref": "a"}, "valid": true }, { "description": "property named $ref invalid", "data": {"$ref": 2}, "valid": false } ] }, { "description": "property named $ref, containing an actual $ref", "schema": { "properties": { "$ref": {"$ref": "#/definitions/is-string"} }, "definitions": { "is-string": { "type": "string" } } }, "tests": [ { "description": "property named $ref valid", "data": {"$ref": "a"}, "valid": true }, { "description": "property named $ref invalid", "data": {"$ref": 2}, "valid": false } ] }, { "description": "Recursive references between schemas", "schema": { "id": "http://localhost:1234/tree", "description": "tree of nodes", "type": "object", "properties": { "meta": {"type": "string"}, "nodes": { "type": "array", "items": {"$ref": "node"} } }, "required": ["meta", "nodes"], "definitions": { "node": { "id": "http://localhost:1234/node", "description": "node", "type": "object", "properties": { "value": {"type": "number"}, "subtree": {"$ref": "tree"} }, "required": ["value"] } } }, "tests": [ { "description": "valid tree", "data": { "meta": "root", "nodes": [ { "value": 1, "subtree": { "meta": "child", "nodes": [ {"value": 1.1}, {"value": 1.2} ] } }, { "value": 2, "subtree": { "meta": "child", "nodes": [ {"value": 2.1}, {"value": 2.2} ] } } ] }, "valid": true }, { "description": "invalid tree", "data": { "meta": "root", "nodes": [ { "value": 1, "subtree": { "meta": "child", "nodes": [ {"value": "string is invalid"}, {"value": 1.2} ] } }, { "value": 2, "subtree": { "meta": "child", "nodes": [ {"value": 2.1}, {"value": 2.2} ] } } ] }, "valid": false } ] }, { "description": "refs with quote", "schema": { "properties": { "foo\"bar": {"$ref": "#/definitions/foo%22bar"} }, "definitions": { "foo\"bar": {"type": "number"} } }, "tests": [ { "description": "object with numbers is valid", "data": { "foo\"bar": 1 }, "valid": true }, { "description": "object with strings is invalid", "data": { "foo\"bar": "1" }, "valid": false } ] }, { "description": "Location-independent identifier", "schema": { "allOf": [{ "$ref": "#foo" }], "definitions": { "A": { "id": "#foo", "type": "integer" } } }, "tests": [ { "data": 1, "description": "match", "valid": true }, { "data": "a", "description": "mismatch", "valid": false } ] }, { "description": "Location-independent identifier with base URI change in subschema", "schema": { "id": "http://localhost:1234/root", "allOf": [{ "$ref": "http://localhost:1234/nested.json#foo" }], "definitions": { "A": { "id": "nested.json", "definitions": { "B": { "id": "#foo", "type": "integer" } } } } }, "tests": [ { "data": 1, "description": "match", "valid": true }, { "data": "a", "description": "mismatch", "valid": false } ] }, { "description": "naive replacement of $ref with its destination is not correct", "schema": { "definitions": { "a_string": { "type": "string" } }, "enum": [ { "$ref": "#/definitions/a_string" } ] }, "tests": [ { "description": "do not evaluate the $ref inside the enum, matching any string", "data": "this is a string", "valid": false }, { "description": "match the enum exactly", "data": { "$ref": "#/definitions/a_string" }, "valid": true } ] }, { "description": "id must be resolved against nearest parent, not just immediate parent", "schema": { "id": "http://example.com/a.json", "definitions": { "x": { "id": "http://example.com/b/c.json", "not": { "definitions": { "y": { "id": "d.json", "type": "number" } } } } }, "allOf": [ { "$ref": "http://example.com/b/d.json" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] }, { "description": "id with file URI still resolves pointers - *nix", "schema": { "id": "file:///folder/file.json", "definitions": { "foo": { "type": "number" } }, "allOf": [ { "$ref": "#/definitions/foo" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] }, { "description": "id with file URI still resolves pointers - windows", "schema": { "id": "file:///c:/folder/file.json", "definitions": { "foo": { "type": "number" } }, "allOf": [ { "$ref": "#/definitions/foo" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] }, { "description": "empty tokens in $ref json-pointer", "schema": { "definitions": { "": { "definitions": { "": { "type": "number" } } } }, "allOf": [ { "$ref": "#/definitions//definitions/" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/refRemote.json000066400000000000000000000123371477700171100276210ustar00rootroot00000000000000[ { "description": "remote ref", "schema": {"$ref": "http://localhost:1234/integer.json"}, "tests": [ { "description": "remote ref valid", "data": 1, "valid": true }, { "description": "remote ref invalid", "data": "a", "valid": false } ] }, { "description": "fragment within remote ref", "schema": {"$ref": "http://localhost:1234/subSchemas.json#/definitions/integer"}, "tests": [ { "description": "remote fragment valid", "data": 1, "valid": true }, { "description": "remote fragment invalid", "data": "a", "valid": false } ] }, { "description": "ref within remote ref", "schema": { "$ref": "http://localhost:1234/subSchemas.json#/definitions/refToInteger" }, "tests": [ { "description": "ref within ref valid", "data": 1, "valid": true }, { "description": "ref within ref invalid", "data": "a", "valid": false } ] }, { "description": "base URI change", "schema": { "id": "http://localhost:1234/", "items": { "id": "baseUriChange/", "items": {"$ref": "folderInteger.json"} } }, "tests": [ { "description": "base URI change ref valid", "data": [[1]], "valid": true }, { "description": "base URI change ref invalid", "data": [["a"]], "valid": false } ] }, { "description": "base URI change - change folder", "schema": { "id": "http://localhost:1234/scope_change_defs1.json", "type" : "object", "properties": { "list": {"$ref": "#/definitions/baz"} }, "definitions": { "baz": { "id": "baseUriChangeFolder/", "type": "array", "items": {"$ref": "folderInteger.json"} } } }, "tests": [ { "description": "number is valid", "data": {"list": [1]}, "valid": true }, { "description": "string is invalid", "data": {"list": ["a"]}, "valid": false } ] }, { "description": "base URI change - change folder in subschema", "schema": { "id": "http://localhost:1234/scope_change_defs2.json", "type" : "object", "properties": { "list": {"$ref": "#/definitions/baz/definitions/bar"} }, "definitions": { "baz": { "id": "baseUriChangeFolderInSubschema/", "definitions": { "bar": { "type": "array", "items": {"$ref": "folderInteger.json"} } } } } }, "tests": [ { "description": "number is valid", "data": {"list": [1]}, "valid": true }, { "description": "string is invalid", "data": {"list": ["a"]}, "valid": false } ] }, { "description": "root ref in remote ref", "schema": { "id": "http://localhost:1234/object", "type": "object", "properties": { "name": {"$ref": "name.json#/definitions/orNull"} } }, "tests": [ { "description": "string is valid", "data": { "name": "foo" }, "valid": true }, { "description": "null is valid", "data": { "name": null }, "valid": true }, { "description": "object is invalid", "data": { "name": { "name": null } }, "valid": false } ] }, { "description": "Location-independent identifier in remote ref", "schema": { "$ref": "http://localhost:1234/locationIndependentIdentifierDraft4.json#/definitions/refToInteger" }, "tests": [ { "description": "integer is valid", "data": 1, "valid": true }, { "description": "string is invalid", "data": "foo", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/required.json000066400000000000000000000074611477700171100275130ustar00rootroot00000000000000[ { "description": "required validation", "schema": { "properties": { "foo": {}, "bar": {} }, "required": ["foo"] }, "tests": [ { "description": "present required property is valid", "data": {"foo": 1}, "valid": true }, { "description": "non-present required property is invalid", "data": {"bar": 1}, "valid": false }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores strings", "data": "", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "required default validation", "schema": { "properties": { "foo": {} } }, "tests": [ { "description": "not required by default", "data": {}, "valid": true } ] }, { "description": "required with escaped characters", "schema": { "required": [ "foo\nbar", "foo\"bar", "foo\\bar", "foo\rbar", "foo\tbar", "foo\fbar" ] }, "tests": [ { "description": "object with all properties present is valid", "data": { "foo\nbar": 1, "foo\"bar": 1, "foo\\bar": 1, "foo\rbar": 1, "foo\tbar": 1, "foo\fbar": 1 }, "valid": true }, { "description": "object with some properties missing is invalid", "data": { "foo\nbar": "1", "foo\"bar": "1" }, "valid": false } ] }, { "description": "required properties whose names are Javascript object property names", "comment": "Ensure JS implementations don't universally consider e.g. __proto__ to always be present in an object.", "schema": { "required": ["__proto__", "toString", "constructor"] }, "tests": [ { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true }, { "description": "none of the properties mentioned", "data": {}, "valid": false }, { "description": "__proto__ present", "data": { "__proto__": "foo" }, "valid": false }, { "description": "toString present", "data": { "toString": { "length": 37 } }, "valid": false }, { "description": "constructor present", "data": { "constructor": { "length": 37 } }, "valid": false }, { "description": "all present", "data": { "__proto__": 12, "toString": { "length": "foo" }, "constructor": 37 }, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/type.json000066400000000000000000000316451477700171100266550ustar00rootroot00000000000000[ { "description": "integer type matches integers", "schema": {"type": "integer"}, "tests": [ { "description": "an integer is an integer", "data": 1, "valid": true }, { "description": "a float is not an integer", "data": 1.1, "valid": false }, { "description": "a string is not an integer", "data": "foo", "valid": false }, { "description": "a string is still not an integer, even if it looks like one", "data": "1", "valid": false }, { "description": "an object is not an integer", "data": {}, "valid": false }, { "description": "an array is not an integer", "data": [], "valid": false }, { "description": "a boolean is not an integer", "data": true, "valid": false }, { "description": "null is not an integer", "data": null, "valid": false } ] }, { "description": "number type matches numbers", "schema": {"type": "number"}, "tests": [ { "description": "an integer is a number", "data": 1, "valid": true }, { "description": "a float with zero fractional part is a number", "data": 1.0, "valid": true }, { "description": "a float is a number", "data": 1.1, "valid": true }, { "description": "a string is not a number", "data": "foo", "valid": false }, { "description": "a string is still not a number, even if it looks like one", "data": "1", "valid": false }, { "description": "an object is not a number", "data": {}, "valid": false }, { "description": "an array is not a number", "data": [], "valid": false }, { "description": "a boolean is not a number", "data": true, "valid": false }, { "description": "null is not a number", "data": null, "valid": false } ] }, { "description": "string type matches strings", "schema": {"type": "string"}, "tests": [ { "description": "1 is not a string", "data": 1, "valid": false }, { "description": "a float is not a string", "data": 1.1, "valid": false }, { "description": "a string is a string", "data": "foo", "valid": true }, { "description": "a string is still a string, even if it looks like a number", "data": "1", "valid": true }, { "description": "an empty string is still a string", "data": "", "valid": true }, { "description": "an object is not a string", "data": {}, "valid": false }, { "description": "an array is not a string", "data": [], "valid": false }, { "description": "a boolean is not a string", "data": true, "valid": false }, { "description": "null is not a string", "data": null, "valid": false } ] }, { "description": "object type matches objects", "schema": {"type": "object"}, "tests": [ { "description": "an integer is not an object", "data": 1, "valid": false }, { "description": "a float is not an object", "data": 1.1, "valid": false }, { "description": "a string is not an object", "data": "foo", "valid": false }, { "description": "an object is an object", "data": {}, "valid": true }, { "description": "an array is not an object", "data": [], "valid": false }, { "description": "a boolean is not an object", "data": true, "valid": false }, { "description": "null is not an object", "data": null, "valid": false } ] }, { "description": "array type matches arrays", "schema": {"type": "array"}, "tests": [ { "description": "an integer is not an array", "data": 1, "valid": false }, { "description": "a float is not an array", "data": 1.1, "valid": false }, { "description": "a string is not an array", "data": "foo", "valid": false }, { "description": "an object is not an array", "data": {}, "valid": false }, { "description": "an array is an array", "data": [], "valid": true }, { "description": "a boolean is not an array", "data": true, "valid": false }, { "description": "null is not an array", "data": null, "valid": false } ] }, { "description": "boolean type matches booleans", "schema": {"type": "boolean"}, "tests": [ { "description": "an integer is not a boolean", "data": 1, "valid": false }, { "description": "zero is not a boolean", "data": 0, "valid": false }, { "description": "a float is not a boolean", "data": 1.1, "valid": false }, { "description": "a string is not a boolean", "data": "foo", "valid": false }, { "description": "an empty string is not a boolean", "data": "", "valid": false }, { "description": "an object is not a boolean", "data": {}, "valid": false }, { "description": "an array is not a boolean", "data": [], "valid": false }, { "description": "true is a boolean", "data": true, "valid": true }, { "description": "false is a boolean", "data": false, "valid": true }, { "description": "null is not a boolean", "data": null, "valid": false } ] }, { "description": "null type matches only the null object", "schema": {"type": "null"}, "tests": [ { "description": "an integer is not null", "data": 1, "valid": false }, { "description": "a float is not null", "data": 1.1, "valid": false }, { "description": "zero is not null", "data": 0, "valid": false }, { "description": "a string is not null", "data": "foo", "valid": false }, { "description": "an empty string is not null", "data": "", "valid": false }, { "description": "an object is not null", "data": {}, "valid": false }, { "description": "an array is not null", "data": [], "valid": false }, { "description": "true is not null", "data": true, "valid": false }, { "description": "false is not null", "data": false, "valid": false }, { "description": "null is null", "data": null, "valid": true } ] }, { "description": "multiple types can be specified in an array", "schema": {"type": ["integer", "string"]}, "tests": [ { "description": "an integer is valid", "data": 1, "valid": true }, { "description": "a string is valid", "data": "foo", "valid": true }, { "description": "a float is invalid", "data": 1.1, "valid": false }, { "description": "an object is invalid", "data": {}, "valid": false }, { "description": "an array is invalid", "data": [], "valid": false }, { "description": "a boolean is invalid", "data": true, "valid": false }, { "description": "null is invalid", "data": null, "valid": false } ] }, { "description": "type as array with one item", "schema": { "type": ["string"] }, "tests": [ { "description": "string is valid", "data": "foo", "valid": true }, { "description": "number is invalid", "data": 123, "valid": false } ] }, { "description": "type: array or object", "schema": { "type": ["array", "object"] }, "tests": [ { "description": "array is valid", "data": [1,2,3], "valid": true }, { "description": "object is valid", "data": {"foo": 123}, "valid": true }, { "description": "number is invalid", "data": 123, "valid": false }, { "description": "string is invalid", "data": "foo", "valid": false }, { "description": "null is invalid", "data": null, "valid": false } ] }, { "description": "type: array, object or null", "schema": { "type": ["array", "object", "null"] }, "tests": [ { "description": "array is valid", "data": [1,2,3], "valid": true }, { "description": "object is valid", "data": {"foo": 123}, "valid": true }, { "description": "null is valid", "data": null, "valid": true }, { "description": "number is invalid", "data": 123, "valid": false }, { "description": "string is invalid", "data": "foo", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft4/uniqueItems.json000066400000000000000000000333021477700171100301740ustar00rootroot00000000000000[ { "description": "uniqueItems validation", "schema": {"uniqueItems": true}, "tests": [ { "description": "unique array of integers is valid", "data": [1, 2], "valid": true }, { "description": "non-unique array of integers is invalid", "data": [1, 1], "valid": false }, { "description": "non-unique array of more than two integers is invalid", "data": [1, 2, 1], "valid": false }, { "description": "numbers are unique if mathematically unequal", "data": [1.0, 1.00, 1], "valid": false }, { "description": "false is not equal to zero", "data": [0, false], "valid": true }, { "description": "true is not equal to one", "data": [1, true], "valid": true }, { "description": "unique array of strings is valid", "data": ["foo", "bar", "baz"], "valid": true }, { "description": "non-unique array of strings is invalid", "data": ["foo", "bar", "foo"], "valid": false }, { "description": "unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "baz"}], "valid": true }, { "description": "non-unique array of objects is invalid", "data": [{"foo": "bar"}, {"foo": "bar"}], "valid": false }, { "description": "property order of array of objects is ignored", "data": [{"foo": "bar", "bar": "foo"}, {"bar": "foo", "foo": "bar"}], "valid": false }, { "description": "unique array of nested objects is valid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : false}}} ], "valid": true }, { "description": "non-unique array of nested objects is invalid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : true}}} ], "valid": false }, { "description": "unique array of arrays is valid", "data": [["foo"], ["bar"]], "valid": true }, { "description": "non-unique array of arrays is invalid", "data": [["foo"], ["foo"]], "valid": false }, { "description": "non-unique array of more than two arrays is invalid", "data": [["foo"], ["bar"], ["foo"]], "valid": false }, { "description": "1 and true are unique", "data": [1, true], "valid": true }, { "description": "0 and false are unique", "data": [0, false], "valid": true }, { "description": "[1] and [true] are unique", "data": [[1], [true]], "valid": true }, { "description": "[0] and [false] are unique", "data": [[0], [false]], "valid": true }, { "description": "nested [1] and [true] are unique", "data": [[[1], "foo"], [[true], "foo"]], "valid": true }, { "description": "nested [0] and [false] are unique", "data": [[[0], "foo"], [[false], "foo"]], "valid": true }, { "description": "unique heterogeneous types are valid", "data": [{}, [1], true, null, 1, "{}"], "valid": true }, { "description": "non-unique heterogeneous types are invalid", "data": [{}, [1], true, null, {}, 1], "valid": false }, { "description": "different objects are unique", "data": [{"a": 1, "b": 2}, {"a": 2, "b": 1}], "valid": true }, { "description": "objects are non-unique despite key order", "data": [{"a": 1, "b": 2}, {"b": 2, "a": 1}], "valid": false }, { "description": "{\"a\": false} and {\"a\": 0} are unique", "data": [{"a": false}, {"a": 0}], "valid": true }, { "description": "{\"a\": true} and {\"a\": 1} are unique", "data": [{"a": true}, {"a": 1}], "valid": true } ] }, { "description": "uniqueItems with an array of items", "schema": { "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": true }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is not valid", "data": [false, false], "valid": false }, { "description": "[true, true] from items array is not valid", "data": [true, true], "valid": false }, { "description": "unique array extended from [false, true] is valid", "data": [false, true, "foo", "bar"], "valid": true }, { "description": "unique array extended from [true, false] is valid", "data": [true, false, "foo", "bar"], "valid": true }, { "description": "non-unique array extended from [false, true] is not valid", "data": [false, true, "foo", "foo"], "valid": false }, { "description": "non-unique array extended from [true, false] is not valid", "data": [true, false, "foo", "foo"], "valid": false } ] }, { "description": "uniqueItems with an array of items and additionalItems=false", "schema": { "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": true, "additionalItems": false }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is not valid", "data": [false, false], "valid": false }, { "description": "[true, true] from items array is not valid", "data": [true, true], "valid": false }, { "description": "extra items are invalid even if unique", "data": [false, true, null], "valid": false } ] }, { "description": "uniqueItems=false validation", "schema": { "uniqueItems": false }, "tests": [ { "description": "unique array of integers is valid", "data": [1, 2], "valid": true }, { "description": "non-unique array of integers is valid", "data": [1, 1], "valid": true }, { "description": "numbers are unique if mathematically unequal", "data": [1.0, 1.00, 1], "valid": true }, { "description": "false is not equal to zero", "data": [0, false], "valid": true }, { "description": "true is not equal to one", "data": [1, true], "valid": true }, { "description": "unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "baz"}], "valid": true }, { "description": "non-unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "bar"}], "valid": true }, { "description": "unique array of nested objects is valid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : false}}} ], "valid": true }, { "description": "non-unique array of nested objects is valid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : true}}} ], "valid": true }, { "description": "unique array of arrays is valid", "data": [["foo"], ["bar"]], "valid": true }, { "description": "non-unique array of arrays is valid", "data": [["foo"], ["foo"]], "valid": true }, { "description": "1 and true are unique", "data": [1, true], "valid": true }, { "description": "0 and false are unique", "data": [0, false], "valid": true }, { "description": "unique heterogeneous types are valid", "data": [{}, [1], true, null, 1], "valid": true }, { "description": "non-unique heterogeneous types are valid", "data": [{}, [1], true, null, {}, 1], "valid": true } ] }, { "description": "uniqueItems=false with an array of items", "schema": { "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": false }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is valid", "data": [false, false], "valid": true }, { "description": "[true, true] from items array is valid", "data": [true, true], "valid": true }, { "description": "unique array extended from [false, true] is valid", "data": [false, true, "foo", "bar"], "valid": true }, { "description": "unique array extended from [true, false] is valid", "data": [true, false, "foo", "bar"], "valid": true }, { "description": "non-unique array extended from [false, true] is valid", "data": [false, true, "foo", "foo"], "valid": true }, { "description": "non-unique array extended from [true, false] is valid", "data": [true, false, "foo", "foo"], "valid": true } ] }, { "description": "uniqueItems=false with an array of items and additionalItems=false", "schema": { "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": false, "additionalItems": false }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is valid", "data": [false, false], "valid": true }, { "description": "[true, true] from items array is valid", "data": [true, true], "valid": true }, { "description": "extra items are invalid even if unique", "data": [false, true, null], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/000077500000000000000000000000001477700171100247725ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/additionalItems.json000066400000000000000000000133511477700171100310020ustar00rootroot00000000000000[ { "description": "additionalItems as schema", "schema": { "items": [{}], "additionalItems": {"type": "integer"} }, "tests": [ { "description": "additional items match schema", "data": [ null, 2, 3, 4 ], "valid": true }, { "description": "additional items do not match schema", "data": [ null, 2, 3, "foo" ], "valid": false } ] }, { "description": "when items is schema, additionalItems does nothing", "schema": { "items": { "type": "integer" }, "additionalItems": { "type": "string" } }, "tests": [ { "description": "valid with a array of type integers", "data": [1,2,3], "valid": true }, { "description": "invalid with a array of mixed types", "data": [1,"2","3"], "valid": false } ] }, { "description": "when items is schema, boolean additionalItems does nothing", "schema": { "items": {}, "additionalItems": false }, "tests": [ { "description": "all items match schema", "data": [ 1, 2, 3, 4, 5 ], "valid": true } ] }, { "description": "array of items with no additionalItems permitted", "schema": { "items": [{}, {}, {}], "additionalItems": false }, "tests": [ { "description": "empty array", "data": [ ], "valid": true }, { "description": "fewer number of items present (1)", "data": [ 1 ], "valid": true }, { "description": "fewer number of items present (2)", "data": [ 1, 2 ], "valid": true }, { "description": "equal number of items present", "data": [ 1, 2, 3 ], "valid": true }, { "description": "additional items are not permitted", "data": [ 1, 2, 3, 4 ], "valid": false } ] }, { "description": "additionalItems as false without items", "schema": {"additionalItems": false}, "tests": [ { "description": "items defaults to empty schema so everything is valid", "data": [ 1, 2, 3, 4, 5 ], "valid": true }, { "description": "ignores non-arrays", "data": {"foo" : "bar"}, "valid": true } ] }, { "description": "additionalItems are allowed by default", "schema": {"items": [{"type": "integer"}]}, "tests": [ { "description": "only the first item is validated", "data": [1, "foo", false], "valid": true } ] }, { "description": "additionalItems does not look in applicators, valid case", "schema": { "allOf": [ { "items": [ { "type": "integer" } ] } ], "additionalItems": { "type": "boolean" } }, "tests": [ { "description": "items defined in allOf are not examined", "data": [ 1, null ], "valid": true } ] }, { "description": "additionalItems does not look in applicators, invalid case", "schema": { "allOf": [ { "items": [ { "type": "integer" }, { "type": "string" } ] } ], "items": [ {"type": "integer" } ], "additionalItems": { "type": "boolean" } }, "tests": [ { "description": "items defined in allOf are not examined", "data": [ 1, "hello" ], "valid": false } ] }, { "description": "items validation adjusts the starting index for additionalItems", "schema": { "items": [ { "type": "string" } ], "additionalItems": { "type": "integer" } }, "tests": [ { "description": "valid items", "data": [ "x", 2, 3 ], "valid": true }, { "description": "wrong type of second item", "data": [ "x", "y" ], "valid": false } ] }, { "description": "additionalItems with heterogeneous array", "schema": { "items": [{}], "additionalItems": false }, "tests": [ { "description": "heterogeneous invalid instance", "data": [ "foo", "bar", 37 ], "valid": false }, { "description": "valid instance", "data": [ null ], "valid": true } ] }, { "description": "additionalItems with null instance elements", "schema": { "additionalItems": { "type": "null" } }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/additionalProperties.json000066400000000000000000000105121477700171100320510ustar00rootroot00000000000000[ { "description": "additionalProperties being false does not allow other properties", "schema": { "properties": {"foo": {}, "bar": {}}, "patternProperties": { "^v": {} }, "additionalProperties": false }, "tests": [ { "description": "no additional properties is valid", "data": {"foo": 1}, "valid": true }, { "description": "an additional property is invalid", "data": {"foo" : 1, "bar" : 2, "quux" : "boom"}, "valid": false }, { "description": "ignores arrays", "data": [1, 2, 3], "valid": true }, { "description": "ignores strings", "data": "foobarbaz", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true }, { "description": "patternProperties are not additional properties", "data": {"foo":1, "vroom": 2}, "valid": true } ] }, { "description": "non-ASCII pattern with additionalProperties", "schema": { "patternProperties": {"^á": {}}, "additionalProperties": false }, "tests": [ { "description": "matching the pattern is valid", "data": {"ármányos": 2}, "valid": true }, { "description": "not matching the pattern is invalid", "data": {"élmény": 2}, "valid": false } ] }, { "description": "additionalProperties with schema", "schema": { "properties": {"foo": {}, "bar": {}}, "additionalProperties": {"type": "boolean"} }, "tests": [ { "description": "no additional properties is valid", "data": {"foo": 1}, "valid": true }, { "description": "an additional valid property is valid", "data": {"foo" : 1, "bar" : 2, "quux" : true}, "valid": true }, { "description": "an additional invalid property is invalid", "data": {"foo" : 1, "bar" : 2, "quux" : 12}, "valid": false } ] }, { "description": "additionalProperties can exist by itself", "schema": { "additionalProperties": {"type": "boolean"} }, "tests": [ { "description": "an additional valid property is valid", "data": {"foo" : true}, "valid": true }, { "description": "an additional invalid property is invalid", "data": {"foo" : 1}, "valid": false } ] }, { "description": "additionalProperties are allowed by default", "schema": {"properties": {"foo": {}, "bar": {}}}, "tests": [ { "description": "additional properties are allowed", "data": {"foo": 1, "bar": 2, "quux": true}, "valid": true } ] }, { "description": "additionalProperties does not look in applicators", "schema": { "allOf": [ {"properties": {"foo": {}}} ], "additionalProperties": {"type": "boolean"} }, "tests": [ { "description": "properties defined in allOf are not examined", "data": {"foo": 1, "bar": true}, "valid": false } ] }, { "description": "additionalProperties with null valued instance properties", "schema": { "additionalProperties": { "type": "null" } }, "tests": [ { "description": "allows null values", "data": {"foo": null}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/allOf.json000066400000000000000000000171471477700171100267340ustar00rootroot00000000000000[ { "description": "allOf", "schema": { "allOf": [ { "properties": { "bar": {"type": "integer"} }, "required": ["bar"] }, { "properties": { "foo": {"type": "string"} }, "required": ["foo"] } ] }, "tests": [ { "description": "allOf", "data": {"foo": "baz", "bar": 2}, "valid": true }, { "description": "mismatch second", "data": {"foo": "baz"}, "valid": false }, { "description": "mismatch first", "data": {"bar": 2}, "valid": false }, { "description": "wrong type", "data": {"foo": "baz", "bar": "quux"}, "valid": false } ] }, { "description": "allOf with base schema", "schema": { "properties": {"bar": {"type": "integer"}}, "required": ["bar"], "allOf" : [ { "properties": { "foo": {"type": "string"} }, "required": ["foo"] }, { "properties": { "baz": {"type": "null"} }, "required": ["baz"] } ] }, "tests": [ { "description": "valid", "data": {"foo": "quux", "bar": 2, "baz": null}, "valid": true }, { "description": "mismatch base schema", "data": {"foo": "quux", "baz": null}, "valid": false }, { "description": "mismatch first allOf", "data": {"bar": 2, "baz": null}, "valid": false }, { "description": "mismatch second allOf", "data": {"foo": "quux", "bar": 2}, "valid": false }, { "description": "mismatch both", "data": {"bar": 2}, "valid": false } ] }, { "description": "allOf simple types", "schema": { "allOf": [ {"maximum": 30}, {"minimum": 20} ] }, "tests": [ { "description": "valid", "data": 25, "valid": true }, { "description": "mismatch one", "data": 35, "valid": false } ] }, { "description": "allOf with boolean schemas, all true", "schema": {"allOf": [true, true]}, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "allOf with boolean schemas, some false", "schema": {"allOf": [true, false]}, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "allOf with boolean schemas, all false", "schema": {"allOf": [false, false]}, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "allOf with one empty schema", "schema": { "allOf": [ {} ] }, "tests": [ { "description": "any data is valid", "data": 1, "valid": true } ] }, { "description": "allOf with two empty schemas", "schema": { "allOf": [ {}, {} ] }, "tests": [ { "description": "any data is valid", "data": 1, "valid": true } ] }, { "description": "allOf with the first empty schema", "schema": { "allOf": [ {}, { "type": "number" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "string is invalid", "data": "foo", "valid": false } ] }, { "description": "allOf with the last empty schema", "schema": { "allOf": [ { "type": "number" }, {} ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "string is invalid", "data": "foo", "valid": false } ] }, { "description": "nested allOf, to check validation semantics", "schema": { "allOf": [ { "allOf": [ { "type": "null" } ] } ] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "anything non-null is invalid", "data": 123, "valid": false } ] }, { "description": "allOf combined with anyOf, oneOf", "schema": { "allOf": [ { "multipleOf": 2 } ], "anyOf": [ { "multipleOf": 3 } ], "oneOf": [ { "multipleOf": 5 } ] }, "tests": [ { "description": "allOf: false, anyOf: false, oneOf: false", "data": 1, "valid": false }, { "description": "allOf: false, anyOf: false, oneOf: true", "data": 5, "valid": false }, { "description": "allOf: false, anyOf: true, oneOf: false", "data": 3, "valid": false }, { "description": "allOf: false, anyOf: true, oneOf: true", "data": 15, "valid": false }, { "description": "allOf: true, anyOf: false, oneOf: false", "data": 2, "valid": false }, { "description": "allOf: true, anyOf: false, oneOf: true", "data": 10, "valid": false }, { "description": "allOf: true, anyOf: true, oneOf: false", "data": 6, "valid": false }, { "description": "allOf: true, anyOf: true, oneOf: true", "data": 30, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/anyOf.json000066400000000000000000000113331477700171100267420ustar00rootroot00000000000000[ { "description": "anyOf", "schema": { "anyOf": [ { "type": "integer" }, { "minimum": 2 } ] }, "tests": [ { "description": "first anyOf valid", "data": 1, "valid": true }, { "description": "second anyOf valid", "data": 2.5, "valid": true }, { "description": "both anyOf valid", "data": 3, "valid": true }, { "description": "neither anyOf valid", "data": 1.5, "valid": false } ] }, { "description": "anyOf with base schema", "schema": { "type": "string", "anyOf" : [ { "maxLength": 2 }, { "minLength": 4 } ] }, "tests": [ { "description": "mismatch base schema", "data": 3, "valid": false }, { "description": "one anyOf valid", "data": "foobar", "valid": true }, { "description": "both anyOf invalid", "data": "foo", "valid": false } ] }, { "description": "anyOf with boolean schemas, all true", "schema": {"anyOf": [true, true]}, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "anyOf with boolean schemas, some true", "schema": {"anyOf": [true, false]}, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "anyOf with boolean schemas, all false", "schema": {"anyOf": [false, false]}, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "anyOf complex types", "schema": { "anyOf": [ { "properties": { "bar": {"type": "integer"} }, "required": ["bar"] }, { "properties": { "foo": {"type": "string"} }, "required": ["foo"] } ] }, "tests": [ { "description": "first anyOf valid (complex)", "data": {"bar": 2}, "valid": true }, { "description": "second anyOf valid (complex)", "data": {"foo": "baz"}, "valid": true }, { "description": "both anyOf valid (complex)", "data": {"foo": "baz", "bar": 2}, "valid": true }, { "description": "neither anyOf valid (complex)", "data": {"foo": 2, "bar": "quux"}, "valid": false } ] }, { "description": "anyOf with one empty schema", "schema": { "anyOf": [ { "type": "number" }, {} ] }, "tests": [ { "description": "string is valid", "data": "foo", "valid": true }, { "description": "number is valid", "data": 123, "valid": true } ] }, { "description": "nested anyOf, to check validation semantics", "schema": { "anyOf": [ { "anyOf": [ { "type": "null" } ] } ] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "anything non-null is invalid", "data": 123, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/boolean_schema.json000066400000000000000000000054021477700171100306250ustar00rootroot00000000000000[ { "description": "boolean schema 'true'", "schema": true, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "string is valid", "data": "foo", "valid": true }, { "description": "boolean true is valid", "data": true, "valid": true }, { "description": "boolean false is valid", "data": false, "valid": true }, { "description": "null is valid", "data": null, "valid": true }, { "description": "object is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "empty object is valid", "data": {}, "valid": true }, { "description": "array is valid", "data": ["foo"], "valid": true }, { "description": "empty array is valid", "data": [], "valid": true } ] }, { "description": "boolean schema 'false'", "schema": false, "tests": [ { "description": "number is invalid", "data": 1, "valid": false }, { "description": "string is invalid", "data": "foo", "valid": false }, { "description": "boolean true is invalid", "data": true, "valid": false }, { "description": "boolean false is invalid", "data": false, "valid": false }, { "description": "null is invalid", "data": null, "valid": false }, { "description": "object is invalid", "data": {"foo": "bar"}, "valid": false }, { "description": "empty object is invalid", "data": {}, "valid": false }, { "description": "array is invalid", "data": ["foo"], "valid": false }, { "description": "empty array is invalid", "data": [], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/const.json000066400000000000000000000225641477700171100270240ustar00rootroot00000000000000[ { "description": "const validation", "schema": {"const": 2}, "tests": [ { "description": "same value is valid", "data": 2, "valid": true }, { "description": "another value is invalid", "data": 5, "valid": false }, { "description": "another type is invalid", "data": "a", "valid": false } ] }, { "description": "const with object", "schema": {"const": {"foo": "bar", "baz": "bax"}}, "tests": [ { "description": "same object is valid", "data": {"foo": "bar", "baz": "bax"}, "valid": true }, { "description": "same object with different property order is valid", "data": {"baz": "bax", "foo": "bar"}, "valid": true }, { "description": "another object is invalid", "data": {"foo": "bar"}, "valid": false }, { "description": "another type is invalid", "data": [1, 2], "valid": false } ] }, { "description": "const with array", "schema": {"const": [{ "foo": "bar" }]}, "tests": [ { "description": "same array is valid", "data": [{"foo": "bar"}], "valid": true }, { "description": "another array item is invalid", "data": [2], "valid": false }, { "description": "array with additional items is invalid", "data": [1, 2, 3], "valid": false } ] }, { "description": "const with null", "schema": {"const": null}, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "not null is invalid", "data": 0, "valid": false } ] }, { "description": "const with false does not match 0", "schema": {"const": false}, "tests": [ { "description": "false is valid", "data": false, "valid": true }, { "description": "integer zero is invalid", "data": 0, "valid": false }, { "description": "float zero is invalid", "data": 0.0, "valid": false } ] }, { "description": "const with true does not match 1", "schema": {"const": true}, "tests": [ { "description": "true is valid", "data": true, "valid": true }, { "description": "integer one is invalid", "data": 1, "valid": false }, { "description": "float one is invalid", "data": 1.0, "valid": false } ] }, { "description": "const with [false] does not match [0]", "schema": {"const": [false]}, "tests": [ { "description": "[false] is valid", "data": [false], "valid": true }, { "description": "[0] is invalid", "data": [0], "valid": false }, { "description": "[0.0] is invalid", "data": [0.0], "valid": false } ] }, { "description": "const with [true] does not match [1]", "schema": {"const": [true]}, "tests": [ { "description": "[true] is valid", "data": [true], "valid": true }, { "description": "[1] is invalid", "data": [1], "valid": false }, { "description": "[1.0] is invalid", "data": [1.0], "valid": false } ] }, { "description": "const with {\"a\": false} does not match {\"a\": 0}", "schema": {"const": {"a": false}}, "tests": [ { "description": "{\"a\": false} is valid", "data": {"a": false}, "valid": true }, { "description": "{\"a\": 0} is invalid", "data": {"a": 0}, "valid": false }, { "description": "{\"a\": 0.0} is invalid", "data": {"a": 0.0}, "valid": false } ] }, { "description": "const with {\"a\": true} does not match {\"a\": 1}", "schema": {"const": {"a": true}}, "tests": [ { "description": "{\"a\": true} is valid", "data": {"a": true}, "valid": true }, { "description": "{\"a\": 1} is invalid", "data": {"a": 1}, "valid": false }, { "description": "{\"a\": 1.0} is invalid", "data": {"a": 1.0}, "valid": false } ] }, { "description": "const with 0 does not match other zero-like types", "schema": {"const": 0}, "tests": [ { "description": "false is invalid", "data": false, "valid": false }, { "description": "integer zero is valid", "data": 0, "valid": true }, { "description": "float zero is valid", "data": 0.0, "valid": true }, { "description": "empty object is invalid", "data": {}, "valid": false }, { "description": "empty array is invalid", "data": [], "valid": false }, { "description": "empty string is invalid", "data": "", "valid": false } ] }, { "description": "const with 1 does not match true", "schema": {"const": 1}, "tests": [ { "description": "true is invalid", "data": true, "valid": false }, { "description": "integer one is valid", "data": 1, "valid": true }, { "description": "float one is valid", "data": 1.0, "valid": true } ] }, { "description": "const with -2.0 matches integer and float types", "schema": {"const": -2.0}, "tests": [ { "description": "integer -2 is valid", "data": -2, "valid": true }, { "description": "integer 2 is invalid", "data": 2, "valid": false }, { "description": "float -2.0 is valid", "data": -2.0, "valid": true }, { "description": "float 2.0 is invalid", "data": 2.0, "valid": false }, { "description": "float -2.00001 is invalid", "data": -2.00001, "valid": false } ] }, { "description": "float and integers are equal up to 64-bit representation limits", "schema": {"const": 9007199254740992}, "tests": [ { "description": "integer is valid", "data": 9007199254740992, "valid": true }, { "description": "integer minus one is invalid", "data": 9007199254740991, "valid": false }, { "description": "float is valid", "data": 9007199254740992.0, "valid": true }, { "description": "float minus one is invalid", "data": 9007199254740991.0, "valid": false } ] }, { "description": "nul characters in strings", "schema": { "const": "hello\u0000there" }, "tests": [ { "description": "match string with nul", "data": "hello\u0000there", "valid": true }, { "description": "do not match string lacking nul", "data": "hellothere", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/contains.json000066400000000000000000000100101477700171100274730ustar00rootroot00000000000000[ { "description": "contains keyword validation", "schema": { "contains": {"minimum": 5} }, "tests": [ { "description": "array with item matching schema (5) is valid", "data": [3, 4, 5], "valid": true }, { "description": "array with item matching schema (6) is valid", "data": [3, 4, 6], "valid": true }, { "description": "array with two items matching schema (5, 6) is valid", "data": [3, 4, 5, 6], "valid": true }, { "description": "array without items matching schema is invalid", "data": [2, 3, 4], "valid": false }, { "description": "empty array is invalid", "data": [], "valid": false }, { "description": "not array is valid", "data": {}, "valid": true } ] }, { "description": "contains keyword with const keyword", "schema": { "contains": { "const": 5 } }, "tests": [ { "description": "array with item 5 is valid", "data": [3, 4, 5], "valid": true }, { "description": "array with two items 5 is valid", "data": [3, 4, 5, 5], "valid": true }, { "description": "array without item 5 is invalid", "data": [1, 2, 3, 4], "valid": false } ] }, { "description": "contains keyword with boolean schema true", "schema": {"contains": true}, "tests": [ { "description": "any non-empty array is valid", "data": ["foo"], "valid": true }, { "description": "empty array is invalid", "data": [], "valid": false } ] }, { "description": "contains keyword with boolean schema false", "schema": {"contains": false}, "tests": [ { "description": "any non-empty array is invalid", "data": ["foo"], "valid": false }, { "description": "empty array is invalid", "data": [], "valid": false }, { "description": "non-arrays are valid", "data": "contains does not apply to strings", "valid": true } ] }, { "description": "items + contains", "schema": { "items": { "multipleOf": 2 }, "contains": { "multipleOf": 3 } }, "tests": [ { "description": "matches items, does not match contains", "data": [ 2, 4, 8 ], "valid": false }, { "description": "does not match items, matches contains", "data": [ 3, 6, 9 ], "valid": false }, { "description": "matches both items and contains", "data": [ 6, 12 ], "valid": true }, { "description": "matches neither items nor contains", "data": [ 1, 5 ], "valid": false } ] }, { "description": "contains with null instance elements", "schema": { "contains": { "type": "null" } }, "tests": [ { "description": "allows null items", "data": [ null ], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/default.json000066400000000000000000000042671477700171100273220ustar00rootroot00000000000000[ { "description": "invalid type for default", "schema": { "properties": { "foo": { "type": "integer", "default": [] } } }, "tests": [ { "description": "valid when property is specified", "data": {"foo": 13}, "valid": true }, { "description": "still valid when the invalid default is used", "data": {}, "valid": true } ] }, { "description": "invalid string value for default", "schema": { "properties": { "bar": { "type": "string", "minLength": 4, "default": "bad" } } }, "tests": [ { "description": "valid when property is specified", "data": {"bar": "good"}, "valid": true }, { "description": "still valid when the invalid default is used", "data": {}, "valid": true } ] }, { "description": "the default keyword does not do anything if the property is missing", "schema": { "type": "object", "properties": { "alpha": { "type": "number", "maximum": 3, "default": 5 } } }, "tests": [ { "description": "an explicit property value is checked against maximum (passing)", "data": { "alpha": 1 }, "valid": true }, { "description": "an explicit property value is checked against maximum (failing)", "data": { "alpha": 5 }, "valid": false }, { "description": "missing properties are not filled in with the default", "data": {}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/definitions.json000066400000000000000000000013171477700171100302020ustar00rootroot00000000000000[ { "description": "validate definition against metaschema", "schema": {"$ref": "http://json-schema.org/draft-06/schema#"}, "tests": [ { "description": "valid definition schema", "data": { "definitions": { "foo": {"type": "integer"} } }, "valid": true }, { "description": "invalid definition schema", "data": { "definitions": { "foo": {"type": 1} } }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/dependencies.json000066400000000000000000000173371477700171100303260ustar00rootroot00000000000000[ { "description": "dependencies", "schema": { "dependencies": {"bar": ["foo"]} }, "tests": [ { "description": "neither", "data": {}, "valid": true }, { "description": "nondependant", "data": {"foo": 1}, "valid": true }, { "description": "with dependency", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "missing dependency", "data": {"bar": 2}, "valid": false }, { "description": "ignores arrays", "data": ["bar"], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "dependencies with empty array", "schema": { "dependencies": {"bar": []} }, "tests": [ { "description": "empty object", "data": {}, "valid": true }, { "description": "object with one property", "data": {"bar": 2}, "valid": true }, { "description": "non-object is valid", "data": 1, "valid": true } ] }, { "description": "multiple dependencies", "schema": { "dependencies": {"quux": ["foo", "bar"]} }, "tests": [ { "description": "neither", "data": {}, "valid": true }, { "description": "nondependants", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "with dependencies", "data": {"foo": 1, "bar": 2, "quux": 3}, "valid": true }, { "description": "missing dependency", "data": {"foo": 1, "quux": 2}, "valid": false }, { "description": "missing other dependency", "data": {"bar": 1, "quux": 2}, "valid": false }, { "description": "missing both dependencies", "data": {"quux": 1}, "valid": false } ] }, { "description": "multiple dependencies subschema", "schema": { "dependencies": { "bar": { "properties": { "foo": {"type": "integer"}, "bar": {"type": "integer"} } } } }, "tests": [ { "description": "valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "no dependency", "data": {"foo": "quux"}, "valid": true }, { "description": "wrong type", "data": {"foo": "quux", "bar": 2}, "valid": false }, { "description": "wrong type other", "data": {"foo": 2, "bar": "quux"}, "valid": false }, { "description": "wrong type both", "data": {"foo": "quux", "bar": "quux"}, "valid": false } ] }, { "description": "dependencies with boolean subschemas", "schema": { "dependencies": { "foo": true, "bar": false } }, "tests": [ { "description": "object with property having schema true is valid", "data": {"foo": 1}, "valid": true }, { "description": "object with property having schema false is invalid", "data": {"bar": 2}, "valid": false }, { "description": "object with both properties is invalid", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "empty object is valid", "data": {}, "valid": true } ] }, { "description": "dependencies with escaped characters", "schema": { "dependencies": { "foo\nbar": ["foo\rbar"], "foo\tbar": { "minProperties": 4 }, "foo'bar": {"required": ["foo\"bar"]}, "foo\"bar": ["foo'bar"] } }, "tests": [ { "description": "valid object 1", "data": { "foo\nbar": 1, "foo\rbar": 2 }, "valid": true }, { "description": "valid object 2", "data": { "foo\tbar": 1, "a": 2, "b": 3, "c": 4 }, "valid": true }, { "description": "valid object 3", "data": { "foo'bar": 1, "foo\"bar": 2 }, "valid": true }, { "description": "invalid object 1", "data": { "foo\nbar": 1, "foo": 2 }, "valid": false }, { "description": "invalid object 2", "data": { "foo\tbar": 1, "a": 2 }, "valid": false }, { "description": "invalid object 3", "data": { "foo'bar": 1 }, "valid": false }, { "description": "invalid object 4", "data": { "foo\"bar": 2 }, "valid": false } ] }, { "description": "dependent subschema incompatible with root", "schema": { "properties": { "foo": {} }, "dependencies": { "foo": { "properties": { "bar": {} }, "additionalProperties": false } } }, "tests": [ { "description": "matches root", "data": {"foo": 1}, "valid": false }, { "description": "matches dependency", "data": {"bar": 1}, "valid": true }, { "description": "matches both", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "no dependency", "data": {"baz": 1}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/enum.json000066400000000000000000000146431477700171100266410ustar00rootroot00000000000000[ { "description": "simple enum validation", "schema": {"enum": [1, 2, 3]}, "tests": [ { "description": "one of the enum is valid", "data": 1, "valid": true }, { "description": "something else is invalid", "data": 4, "valid": false } ] }, { "description": "heterogeneous enum validation", "schema": {"enum": [6, "foo", [], true, {"foo": 12}]}, "tests": [ { "description": "one of the enum is valid", "data": [], "valid": true }, { "description": "something else is invalid", "data": null, "valid": false }, { "description": "objects are deep compared", "data": {"foo": false}, "valid": false }, { "description": "valid object matches", "data": {"foo": 12}, "valid": true }, { "description": "extra properties in object is invalid", "data": {"foo": 12, "boo": 42}, "valid": false } ] }, { "description": "heterogeneous enum-with-null validation", "schema": { "enum": [6, null] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "number is valid", "data": 6, "valid": true }, { "description": "something else is invalid", "data": "test", "valid": false } ] }, { "description": "enums in properties", "schema": { "type":"object", "properties": { "foo": {"enum":["foo"]}, "bar": {"enum":["bar"]} }, "required": ["bar"] }, "tests": [ { "description": "both properties are valid", "data": {"foo":"foo", "bar":"bar"}, "valid": true }, { "description": "wrong foo value", "data": {"foo":"foot", "bar":"bar"}, "valid": false }, { "description": "wrong bar value", "data": {"foo":"foo", "bar":"bart"}, "valid": false }, { "description": "missing optional property is valid", "data": {"bar":"bar"}, "valid": true }, { "description": "missing required property is invalid", "data": {"foo":"foo"}, "valid": false }, { "description": "missing all properties is invalid", "data": {}, "valid": false } ] }, { "description": "enum with escaped characters", "schema": { "enum": ["foo\nbar", "foo\rbar"] }, "tests": [ { "description": "member 1 is valid", "data": "foo\nbar", "valid": true }, { "description": "member 2 is valid", "data": "foo\rbar", "valid": true }, { "description": "another string is invalid", "data": "abc", "valid": false } ] }, { "description": "enum with false does not match 0", "schema": {"enum": [false]}, "tests": [ { "description": "false is valid", "data": false, "valid": true }, { "description": "integer zero is invalid", "data": 0, "valid": false }, { "description": "float zero is invalid", "data": 0.0, "valid": false } ] }, { "description": "enum with true does not match 1", "schema": {"enum": [true]}, "tests": [ { "description": "true is valid", "data": true, "valid": true }, { "description": "integer one is invalid", "data": 1, "valid": false }, { "description": "float one is invalid", "data": 1.0, "valid": false } ] }, { "description": "enum with 0 does not match false", "schema": {"enum": [0]}, "tests": [ { "description": "false is invalid", "data": false, "valid": false }, { "description": "integer zero is valid", "data": 0, "valid": true }, { "description": "float zero is valid", "data": 0.0, "valid": true } ] }, { "description": "enum with 1 does not match true", "schema": {"enum": [1]}, "tests": [ { "description": "true is invalid", "data": true, "valid": false }, { "description": "integer one is valid", "data": 1, "valid": true }, { "description": "float one is valid", "data": 1.0, "valid": true } ] }, { "description": "nul characters in strings", "schema": { "enum": [ "hello\u0000there" ] }, "tests": [ { "description": "match string with nul", "data": "hello\u0000there", "valid": true }, { "description": "do not match string lacking nul", "data": "hellothere", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/exclusiveMaximum.json000066400000000000000000000014071477700171100312340ustar00rootroot00000000000000[ { "description": "exclusiveMaximum validation", "schema": { "exclusiveMaximum": 3.0 }, "tests": [ { "description": "below the exclusiveMaximum is valid", "data": 2.2, "valid": true }, { "description": "boundary point is invalid", "data": 3.0, "valid": false }, { "description": "above the exclusiveMaximum is invalid", "data": 3.5, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/exclusiveMinimum.json000066400000000000000000000014071477700171100312320ustar00rootroot00000000000000[ { "description": "exclusiveMinimum validation", "schema": { "exclusiveMinimum": 1.1 }, "tests": [ { "description": "above the exclusiveMinimum is valid", "data": 1.2, "valid": true }, { "description": "boundary point is invalid", "data": 1.1, "valid": false }, { "description": "below the exclusiveMinimum is invalid", "data": 0.6, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/format.json000066400000000000000000000225251477700171100271630ustar00rootroot00000000000000[ { "description": "email format", "schema": { "format": "email" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "ipv4 format", "schema": { "format": "ipv4" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "ipv6 format", "schema": { "format": "ipv6" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "hostname format", "schema": { "format": "hostname" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "date-time format", "schema": { "format": "date-time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "json-pointer format", "schema": { "format": "json-pointer" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "uri format", "schema": { "format": "uri" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "uri-reference format", "schema": { "format": "uri-reference" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "uri-template format", "schema": { "format": "uri-template" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/id.json000066400000000000000000000101031477700171100262540ustar00rootroot00000000000000[ { "description": "id inside an enum is not a real identifier", "comment": "the implementation must not be confused by an id buried in the enum", "schema": { "definitions": { "id_in_enum": { "enum": [ { "$id": "https://localhost:1234/id/my_identifier.json", "type": "null" } ] }, "real_id_in_schema": { "$id": "https://localhost:1234/id/my_identifier.json", "type": "string" }, "zzz_id_in_const": { "const": { "$id": "https://localhost:1234/id/my_identifier.json", "type": "null" } } }, "anyOf": [ { "$ref": "#/definitions/id_in_enum" }, { "$ref": "https://localhost:1234/id/my_identifier.json" } ] }, "tests": [ { "description": "exact match to enum, and type matches", "data": { "$id": "https://localhost:1234/id/my_identifier.json", "type": "null" }, "valid": true }, { "description": "match $ref to id", "data": "a string to match #/definitions/id_in_enum", "valid": true }, { "description": "no match on enum or $ref to id", "data": 1, "valid": false } ] }, { "description": "non-schema object containing a plain-name $id property", "schema": { "definitions": { "const_not_anchor": { "const": { "$id": "#not_a_real_anchor" } } }, "oneOf": [ { "const": "skip not_a_real_anchor" }, { "allOf": [ { "not": { "const": "skip not_a_real_anchor" } }, { "$ref": "#/definitions/const_not_anchor" } ] } ] }, "tests": [ { "description": "skip traversing definition for a valid result", "data": "skip not_a_real_anchor", "valid": true }, { "description": "const at const_not_anchor does not match", "data": 1, "valid": false } ] }, { "description": "non-schema object containing an $id property", "schema": { "definitions": { "const_not_id": { "const": { "$id": "not_a_real_id" } } }, "oneOf": [ { "const":"skip not_a_real_id" }, { "allOf": [ { "not": { "const": "skip not_a_real_id" } }, { "$ref": "#/definitions/const_not_id" } ] } ] }, "tests": [ { "description": "skip traversing definition for a valid result", "data": "skip not_a_real_id", "valid": true }, { "description": "const at const_not_id does not match", "data": 1, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/infinite-loop-detection.json000066400000000000000000000017461477700171100324250ustar00rootroot00000000000000[ { "description": "evaluating the same schema location against the same data location twice is not a sign of an infinite loop", "schema": { "definitions": { "int": { "type": "integer" } }, "allOf": [ { "properties": { "foo": { "$ref": "#/definitions/int" } } }, { "additionalProperties": { "$ref": "#/definitions/int" } } ] }, "tests": [ { "description": "passing case", "data": { "foo": 1 }, "valid": true }, { "description": "failing case", "data": { "foo": "a string" }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/items.json000066400000000000000000000176141477700171100270170ustar00rootroot00000000000000[ { "description": "a schema given for items", "schema": { "items": {"type": "integer"} }, "tests": [ { "description": "valid items", "data": [ 1, 2, 3 ], "valid": true }, { "description": "wrong type of items", "data": [1, "x"], "valid": false }, { "description": "ignores non-arrays", "data": {"foo" : "bar"}, "valid": true }, { "description": "JavaScript pseudo-array is valid", "data": { "0": "invalid", "length": 1 }, "valid": true } ] }, { "description": "an array of schemas for items", "schema": { "items": [ {"type": "integer"}, {"type": "string"} ] }, "tests": [ { "description": "correct types", "data": [ 1, "foo" ], "valid": true }, { "description": "wrong types", "data": [ "foo", 1 ], "valid": false }, { "description": "incomplete array of items", "data": [ 1 ], "valid": true }, { "description": "array with additional items", "data": [ 1, "foo", true ], "valid": true }, { "description": "empty array", "data": [ ], "valid": true }, { "description": "JavaScript pseudo-array is valid", "data": { "0": "invalid", "1": "valid", "length": 2 }, "valid": true } ] }, { "description": "items with boolean schema (true)", "schema": {"items": true}, "tests": [ { "description": "any array is valid", "data": [ 1, "foo", true ], "valid": true }, { "description": "empty array is valid", "data": [], "valid": true } ] }, { "description": "items with boolean schema (false)", "schema": {"items": false}, "tests": [ { "description": "any non-empty array is invalid", "data": [ 1, "foo", true ], "valid": false }, { "description": "empty array is valid", "data": [], "valid": true } ] }, { "description": "items with boolean schemas", "schema": { "items": [true, false] }, "tests": [ { "description": "array with one item is valid", "data": [ 1 ], "valid": true }, { "description": "array with two items is invalid", "data": [ 1, "foo" ], "valid": false }, { "description": "empty array is valid", "data": [], "valid": true } ] }, { "description": "items and subitems", "schema": { "definitions": { "item": { "type": "array", "additionalItems": false, "items": [ { "$ref": "#/definitions/sub-item" }, { "$ref": "#/definitions/sub-item" } ] }, "sub-item": { "type": "object", "required": ["foo"] } }, "type": "array", "additionalItems": false, "items": [ { "$ref": "#/definitions/item" }, { "$ref": "#/definitions/item" }, { "$ref": "#/definitions/item" } ] }, "tests": [ { "description": "valid items", "data": [ [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": true }, { "description": "too many items", "data": [ [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "too many sub-items", "data": [ [ {"foo": null}, {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "wrong item", "data": [ {"foo": null}, [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "wrong sub-item", "data": [ [ {}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "fewer items is valid", "data": [ [ {"foo": null} ], [ {"foo": null} ] ], "valid": true } ] }, { "description": "nested items", "schema": { "type": "array", "items": { "type": "array", "items": { "type": "array", "items": { "type": "array", "items": { "type": "number" } } } } }, "tests": [ { "description": "valid nested array", "data": [[[[1]], [[2],[3]]], [[[4], [5], [6]]]], "valid": true }, { "description": "nested array with invalid type", "data": [[[["1"]], [[2],[3]]], [[[4], [5], [6]]]], "valid": false }, { "description": "not deep enough", "data": [[[1], [2],[3]], [[4], [5], [6]]], "valid": false } ] }, { "description": "single-form items with null instance elements", "schema": { "items": { "type": "null" } }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] }, { "description": "array-form items with null instance elements", "schema": { "items": [ { "type": "null" } ] }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/maxItems.json000066400000000000000000000021551477700171100274570ustar00rootroot00000000000000[ { "description": "maxItems validation", "schema": {"maxItems": 2}, "tests": [ { "description": "shorter is valid", "data": [1], "valid": true }, { "description": "exact length is valid", "data": [1, 2], "valid": true }, { "description": "too long is invalid", "data": [1, 2, 3], "valid": false }, { "description": "ignores non-arrays", "data": "foobar", "valid": true } ] }, { "description": "maxItems validation with a decimal", "schema": {"maxItems": 2.0}, "tests": [ { "description": "shorter is valid", "data": [1], "valid": true }, { "description": "too long is invalid", "data": [1, 2, 3], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/maxLength.json000066400000000000000000000024511477700171100276160ustar00rootroot00000000000000[ { "description": "maxLength validation", "schema": {"maxLength": 2}, "tests": [ { "description": "shorter is valid", "data": "f", "valid": true }, { "description": "exact length is valid", "data": "fo", "valid": true }, { "description": "too long is invalid", "data": "foo", "valid": false }, { "description": "ignores non-strings", "data": 100, "valid": true }, { "description": "two supplementary Unicode code points is long enough", "data": "\uD83D\uDCA9\uD83D\uDCA9", "valid": true } ] }, { "description": "maxLength validation with a decimal", "schema": {"maxLength": 2.0}, "tests": [ { "description": "shorter is valid", "data": "f", "valid": true }, { "description": "too long is invalid", "data": "foo", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/maxProperties.json000066400000000000000000000036531477700171100305360ustar00rootroot00000000000000[ { "description": "maxProperties validation", "schema": {"maxProperties": 2}, "tests": [ { "description": "shorter is valid", "data": {"foo": 1}, "valid": true }, { "description": "exact length is valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "too long is invalid", "data": {"foo": 1, "bar": 2, "baz": 3}, "valid": false }, { "description": "ignores arrays", "data": [1, 2, 3], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "maxProperties validation with a decimal", "schema": {"maxProperties": 2.0}, "tests": [ { "description": "shorter is valid", "data": {"foo": 1}, "valid": true }, { "description": "too long is invalid", "data": {"foo": 1, "bar": 2, "baz": 3}, "valid": false } ] }, { "description": "maxProperties = 0 means the object is empty", "schema": { "maxProperties": 0 }, "tests": [ { "description": "no properties is valid", "data": {}, "valid": true }, { "description": "one property is invalid", "data": { "foo": 1 }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/maximum.json000066400000000000000000000027041477700171100273450ustar00rootroot00000000000000[ { "description": "maximum validation", "schema": {"maximum": 3.0}, "tests": [ { "description": "below the maximum is valid", "data": 2.6, "valid": true }, { "description": "boundary point is valid", "data": 3.0, "valid": true }, { "description": "above the maximum is invalid", "data": 3.5, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] }, { "description": "maximum validation with unsigned integer", "schema": {"maximum": 300}, "tests": [ { "description": "below the maximum is invalid", "data": 299.97, "valid": true }, { "description": "boundary point integer is valid", "data": 300, "valid": true }, { "description": "boundary point float is valid", "data": 300.00, "valid": true }, { "description": "above the maximum is invalid", "data": 300.5, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/minItems.json000066400000000000000000000021341477700171100274520ustar00rootroot00000000000000[ { "description": "minItems validation", "schema": {"minItems": 1}, "tests": [ { "description": "longer is valid", "data": [1, 2], "valid": true }, { "description": "exact length is valid", "data": [1], "valid": true }, { "description": "too short is invalid", "data": [], "valid": false }, { "description": "ignores non-arrays", "data": "", "valid": true } ] }, { "description": "minItems validation with a decimal", "schema": {"minItems": 1.0}, "tests": [ { "description": "longer is valid", "data": [1, 2], "valid": true }, { "description": "too short is invalid", "data": [], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/minLength.json000066400000000000000000000024371477700171100276200ustar00rootroot00000000000000[ { "description": "minLength validation", "schema": {"minLength": 2}, "tests": [ { "description": "longer is valid", "data": "foo", "valid": true }, { "description": "exact length is valid", "data": "fo", "valid": true }, { "description": "too short is invalid", "data": "f", "valid": false }, { "description": "ignores non-strings", "data": 1, "valid": true }, { "description": "one supplementary Unicode code point is not long enough", "data": "\uD83D\uDCA9", "valid": false } ] }, { "description": "minLength validation with a decimal", "schema": {"minLength": 2.0}, "tests": [ { "description": "longer is valid", "data": "foo", "valid": true }, { "description": "too short is invalid", "data": "f", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/minProperties.json000066400000000000000000000026531477700171100305330ustar00rootroot00000000000000[ { "description": "minProperties validation", "schema": {"minProperties": 1}, "tests": [ { "description": "longer is valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "exact length is valid", "data": {"foo": 1}, "valid": true }, { "description": "too short is invalid", "data": {}, "valid": false }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores strings", "data": "", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "minProperties validation with a decimal", "schema": {"minProperties": 1.0}, "tests": [ { "description": "longer is valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "too short is invalid", "data": {}, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/minimum.json000066400000000000000000000036121477700171100273420ustar00rootroot00000000000000[ { "description": "minimum validation", "schema": {"minimum": 1.1}, "tests": [ { "description": "above the minimum is valid", "data": 2.6, "valid": true }, { "description": "boundary point is valid", "data": 1.1, "valid": true }, { "description": "below the minimum is invalid", "data": 0.6, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] }, { "description": "minimum validation with signed integer", "schema": {"minimum": -2}, "tests": [ { "description": "negative above the minimum is valid", "data": -1, "valid": true }, { "description": "positive above the minimum is valid", "data": 0, "valid": true }, { "description": "boundary point is valid", "data": -2, "valid": true }, { "description": "boundary point with float is valid", "data": -2.0, "valid": true }, { "description": "float below the minimum is invalid", "data": -2.0001, "valid": false }, { "description": "int below the minimum is invalid", "data": -3, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/multipleOf.json000066400000000000000000000042241477700171100300070ustar00rootroot00000000000000[ { "description": "by int", "schema": {"multipleOf": 2}, "tests": [ { "description": "int by int", "data": 10, "valid": true }, { "description": "int by int fail", "data": 7, "valid": false }, { "description": "ignores non-numbers", "data": "foo", "valid": true } ] }, { "description": "by number", "schema": {"multipleOf": 1.5}, "tests": [ { "description": "zero is multiple of anything", "data": 0, "valid": true }, { "description": "4.5 is multiple of 1.5", "data": 4.5, "valid": true }, { "description": "35 is not multiple of 1.5", "data": 35, "valid": false } ] }, { "description": "by small number", "schema": {"multipleOf": 0.0001}, "tests": [ { "description": "0.0075 is multiple of 0.0001", "data": 0.0075, "valid": true }, { "description": "0.00751 is not multiple of 0.0001", "data": 0.00751, "valid": false } ] }, { "description": "float division = inf", "schema": {"type": "integer", "multipleOf": 0.123456789}, "tests": [ { "description": "always invalid, but naive implementations may raise an overflow error", "data": 1e308, "valid": false } ] }, { "description": "small multiple of large integer", "schema": {"type": "integer", "multipleOf": 1e-8}, "tests": [ { "description": "any integer is a multiple of 1e-8", "data": 12391239123, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/not.json000066400000000000000000000053761477700171100265000ustar00rootroot00000000000000[ { "description": "not", "schema": { "not": {"type": "integer"} }, "tests": [ { "description": "allowed", "data": "foo", "valid": true }, { "description": "disallowed", "data": 1, "valid": false } ] }, { "description": "not multiple types", "schema": { "not": {"type": ["integer", "boolean"]} }, "tests": [ { "description": "valid", "data": "foo", "valid": true }, { "description": "mismatch", "data": 1, "valid": false }, { "description": "other mismatch", "data": true, "valid": false } ] }, { "description": "not more complex schema", "schema": { "not": { "type": "object", "properties": { "foo": { "type": "string" } } } }, "tests": [ { "description": "match", "data": 1, "valid": true }, { "description": "other match", "data": {"foo": 1}, "valid": true }, { "description": "mismatch", "data": {"foo": "bar"}, "valid": false } ] }, { "description": "forbidden property", "schema": { "properties": { "foo": { "not": {} } } }, "tests": [ { "description": "property present", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "property absent", "data": {"bar": 1, "baz": 2}, "valid": true } ] }, { "description": "not with boolean schema true", "schema": {"not": true}, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "not with boolean schema false", "schema": {"not": false}, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/oneOf.json000066400000000000000000000161231477700171100267360ustar00rootroot00000000000000[ { "description": "oneOf", "schema": { "oneOf": [ { "type": "integer" }, { "minimum": 2 } ] }, "tests": [ { "description": "first oneOf valid", "data": 1, "valid": true }, { "description": "second oneOf valid", "data": 2.5, "valid": true }, { "description": "both oneOf valid", "data": 3, "valid": false }, { "description": "neither oneOf valid", "data": 1.5, "valid": false } ] }, { "description": "oneOf with base schema", "schema": { "type": "string", "oneOf" : [ { "minLength": 2 }, { "maxLength": 4 } ] }, "tests": [ { "description": "mismatch base schema", "data": 3, "valid": false }, { "description": "one oneOf valid", "data": "foobar", "valid": true }, { "description": "both oneOf valid", "data": "foo", "valid": false } ] }, { "description": "oneOf with boolean schemas, all true", "schema": {"oneOf": [true, true, true]}, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "oneOf with boolean schemas, one true", "schema": {"oneOf": [true, false, false]}, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "oneOf with boolean schemas, more than one true", "schema": {"oneOf": [true, true, false]}, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "oneOf with boolean schemas, all false", "schema": {"oneOf": [false, false, false]}, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "oneOf complex types", "schema": { "oneOf": [ { "properties": { "bar": {"type": "integer"} }, "required": ["bar"] }, { "properties": { "foo": {"type": "string"} }, "required": ["foo"] } ] }, "tests": [ { "description": "first oneOf valid (complex)", "data": {"bar": 2}, "valid": true }, { "description": "second oneOf valid (complex)", "data": {"foo": "baz"}, "valid": true }, { "description": "both oneOf valid (complex)", "data": {"foo": "baz", "bar": 2}, "valid": false }, { "description": "neither oneOf valid (complex)", "data": {"foo": 2, "bar": "quux"}, "valid": false } ] }, { "description": "oneOf with empty schema", "schema": { "oneOf": [ { "type": "number" }, {} ] }, "tests": [ { "description": "one valid - valid", "data": "foo", "valid": true }, { "description": "both valid - invalid", "data": 123, "valid": false } ] }, { "description": "oneOf with required", "schema": { "type": "object", "oneOf": [ { "required": ["foo", "bar"] }, { "required": ["foo", "baz"] } ] }, "tests": [ { "description": "both invalid - invalid", "data": {"bar": 2}, "valid": false }, { "description": "first valid - valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "second valid - valid", "data": {"foo": 1, "baz": 3}, "valid": true }, { "description": "both valid - invalid", "data": {"foo": 1, "bar": 2, "baz" : 3}, "valid": false } ] }, { "description": "oneOf with missing optional property", "schema": { "oneOf": [ { "properties": { "bar": true, "baz": true }, "required": ["bar"] }, { "properties": { "foo": true }, "required": ["foo"] } ] }, "tests": [ { "description": "first oneOf valid", "data": {"bar": 8}, "valid": true }, { "description": "second oneOf valid", "data": {"foo": "foo"}, "valid": true }, { "description": "both oneOf valid", "data": {"foo": "foo", "bar": 8}, "valid": false }, { "description": "neither oneOf valid", "data": {"baz": "quux"}, "valid": false } ] }, { "description": "nested oneOf, to check validation semantics", "schema": { "oneOf": [ { "oneOf": [ { "type": "null" } ] } ] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "anything non-null is invalid", "data": 123, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/000077500000000000000000000000001477700171100266175ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/bignum.json000066400000000000000000000054011477700171100307730ustar00rootroot00000000000000[ { "description": "integer", "schema": { "type": "integer" }, "tests": [ { "description": "a bignum is an integer", "data": 12345678910111213141516171819202122232425262728293031, "valid": true }, { "description": "a negative bignum is an integer", "data": -12345678910111213141516171819202122232425262728293031, "valid": true } ] }, { "description": "number", "schema": { "type": "number" }, "tests": [ { "description": "a bignum is a number", "data": 98249283749234923498293171823948729348710298301928331, "valid": true }, { "description": "a negative bignum is a number", "data": -98249283749234923498293171823948729348710298301928331, "valid": true } ] }, { "description": "string", "schema": { "type": "string" }, "tests": [ { "description": "a bignum is not a string", "data": 98249283749234923498293171823948729348710298301928331, "valid": false } ] }, { "description": "maximum integer comparison", "schema": { "maximum": 18446744073709551615 }, "tests": [ { "description": "comparison works for high numbers", "data": 18446744073709551600, "valid": true } ] }, { "description": "float comparison with high precision", "schema": { "exclusiveMaximum": 972783798187987123879878123.18878137 }, "tests": [ { "description": "comparison works for high numbers", "data": 972783798187987123879878123.188781371, "valid": false } ] }, { "description": "minimum integer comparison", "schema": { "minimum": -18446744073709551615 }, "tests": [ { "description": "comparison works for very negative numbers", "data": -18446744073709551600, "valid": true } ] }, { "description": "float comparison with high precision on negative numbers", "schema": { "exclusiveMinimum": -972783798187987123879878123.18878137 }, "tests": [ { "description": "comparison works for very negative numbers", "data": -972783798187987123879878123.188781371, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/ecmascript-regex.json000066400000000000000000000441011477700171100327540ustar00rootroot00000000000000[ { "description": "ECMA 262 regex $ does not match trailing newline", "schema": { "type": "string", "pattern": "^abc$" }, "tests": [ { "description": "matches in Python, but not in ECMA 262", "data": "abc\\n", "valid": false }, { "description": "matches", "data": "abc", "valid": true } ] }, { "description": "ECMA 262 regex converts \\t to horizontal tab", "schema": { "type": "string", "pattern": "^\\t$" }, "tests": [ { "description": "does not match", "data": "\\t", "valid": false }, { "description": "matches", "data": "\u0009", "valid": true } ] }, { "description": "ECMA 262 regex escapes control codes with \\c and upper letter", "schema": { "type": "string", "pattern": "^\\cC$" }, "tests": [ { "description": "does not match", "data": "\\cC", "valid": false }, { "description": "matches", "data": "\u0003", "valid": true } ] }, { "description": "ECMA 262 regex escapes control codes with \\c and lower letter", "schema": { "type": "string", "pattern": "^\\cc$" }, "tests": [ { "description": "does not match", "data": "\\cc", "valid": false }, { "description": "matches", "data": "\u0003", "valid": true } ] }, { "description": "ECMA 262 \\d matches ascii digits only", "schema": { "type": "string", "pattern": "^\\d$" }, "tests": [ { "description": "ASCII zero matches", "data": "0", "valid": true }, { "description": "NKO DIGIT ZERO does not match (unlike e.g. Python)", "data": "߀", "valid": false }, { "description": "NKO DIGIT ZERO (as \\u escape) does not match", "data": "\u07c0", "valid": false } ] }, { "description": "ECMA 262 \\D matches everything but ascii digits", "schema": { "type": "string", "pattern": "^\\D$" }, "tests": [ { "description": "ASCII zero does not match", "data": "0", "valid": false }, { "description": "NKO DIGIT ZERO matches (unlike e.g. Python)", "data": "߀", "valid": true }, { "description": "NKO DIGIT ZERO (as \\u escape) matches", "data": "\u07c0", "valid": true } ] }, { "description": "ECMA 262 \\w matches ascii letters only", "schema": { "type": "string", "pattern": "^\\w$" }, "tests": [ { "description": "ASCII 'a' matches", "data": "a", "valid": true }, { "description": "latin-1 e-acute does not match (unlike e.g. Python)", "data": "é", "valid": false } ] }, { "description": "ECMA 262 \\W matches everything but ascii letters", "schema": { "type": "string", "pattern": "^\\W$" }, "tests": [ { "description": "ASCII 'a' does not match", "data": "a", "valid": false }, { "description": "latin-1 e-acute matches (unlike e.g. Python)", "data": "é", "valid": true } ] }, { "description": "ECMA 262 \\s matches whitespace", "schema": { "type": "string", "pattern": "^\\s$" }, "tests": [ { "description": "ASCII space matches", "data": " ", "valid": true }, { "description": "Character tabulation matches", "data": "\t", "valid": true }, { "description": "Line tabulation matches", "data": "\u000b", "valid": true }, { "description": "Form feed matches", "data": "\u000c", "valid": true }, { "description": "latin-1 non-breaking-space matches", "data": "\u00a0", "valid": true }, { "description": "zero-width whitespace matches", "data": "\ufeff", "valid": true }, { "description": "line feed matches (line terminator)", "data": "\u000a", "valid": true }, { "description": "paragraph separator matches (line terminator)", "data": "\u2029", "valid": true }, { "description": "EM SPACE matches (Space_Separator)", "data": "\u2003", "valid": true }, { "description": "Non-whitespace control does not match", "data": "\u0001", "valid": false }, { "description": "Non-whitespace does not match", "data": "\u2013", "valid": false } ] }, { "description": "ECMA 262 \\S matches everything but whitespace", "schema": { "type": "string", "pattern": "^\\S$" }, "tests": [ { "description": "ASCII space does not match", "data": " ", "valid": false }, { "description": "Character tabulation does not match", "data": "\t", "valid": false }, { "description": "Line tabulation does not match", "data": "\u000b", "valid": false }, { "description": "Form feed does not match", "data": "\u000c", "valid": false }, { "description": "latin-1 non-breaking-space does not match", "data": "\u00a0", "valid": false }, { "description": "zero-width whitespace does not match", "data": "\ufeff", "valid": false }, { "description": "line feed does not match (line terminator)", "data": "\u000a", "valid": false }, { "description": "paragraph separator does not match (line terminator)", "data": "\u2029", "valid": false }, { "description": "EM SPACE does not match (Space_Separator)", "data": "\u2003", "valid": false }, { "description": "Non-whitespace control matches", "data": "\u0001", "valid": true }, { "description": "Non-whitespace matches", "data": "\u2013", "valid": true } ] }, { "description": "patterns always use unicode semantics with pattern", "schema": { "pattern": "\\p{Letter}cole" }, "tests": [ { "description": "ascii character in json string", "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", "valid": true }, { "description": "literal unicode character in json string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": true }, { "description": "unicode character in hex format in string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": true }, { "description": "unicode matching is case-sensitive", "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", "valid": false } ] }, { "description": "\\w in patterns matches [A-Za-z0-9_], not unicode letters", "schema": { "pattern": "\\wcole" }, "tests": [ { "description": "ascii character in json string", "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", "valid": true }, { "description": "literal unicode character in json string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "unicode character in hex format in string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "unicode matching is case-sensitive", "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", "valid": false } ] }, { "description": "pattern with ASCII ranges", "schema": { "pattern": "[a-z]cole" }, "tests": [ { "description": "literal unicode character in json string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "unicode character in hex format in string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "ascii characters match", "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", "valid": true } ] }, { "description": "\\d in pattern matches [0-9], not unicode digits", "schema": { "pattern": "^\\d+$" }, "tests": [ { "description": "ascii digits", "data": "42", "valid": true }, { "description": "ascii non-digits", "data": "-%#", "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": "৪২", "valid": false } ] }, { "description": "pattern with non-ASCII digits", "schema": { "pattern": "^\\p{digit}+$" }, "tests": [ { "description": "ascii digits", "data": "42", "valid": true }, { "description": "ascii non-digits", "data": "-%#", "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": "৪২", "valid": true } ] }, { "description": "patterns always use unicode semantics with patternProperties", "schema": { "type": "object", "patternProperties": { "\\p{Letter}cole": true }, "additionalProperties": false }, "tests": [ { "description": "ascii character in json string", "data": { "l'ecole": "pas de vraie vie" }, "valid": true }, { "description": "literal unicode character in json string", "data": { "l'école": "pas de vraie vie" }, "valid": true }, { "description": "unicode character in hex format in string", "data": { "l'\u00e9cole": "pas de vraie vie" }, "valid": true }, { "description": "unicode matching is case-sensitive", "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, "valid": false } ] }, { "description": "\\w in patternProperties matches [A-Za-z0-9_], not unicode letters", "schema": { "type": "object", "patternProperties": { "\\wcole": true }, "additionalProperties": false }, "tests": [ { "description": "ascii character in json string", "data": { "l'ecole": "pas de vraie vie" }, "valid": true }, { "description": "literal unicode character in json string", "data": { "l'école": "pas de vraie vie" }, "valid": false }, { "description": "unicode character in hex format in string", "data": { "l'\u00e9cole": "pas de vraie vie" }, "valid": false }, { "description": "unicode matching is case-sensitive", "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, "valid": false } ] }, { "description": "patternProperties with ASCII ranges", "schema": { "type": "object", "patternProperties": { "[a-z]cole": true }, "additionalProperties": false }, "tests": [ { "description": "literal unicode character in json string", "data": { "l'école": "pas de vraie vie" }, "valid": false }, { "description": "unicode character in hex format in string", "data": { "l'\u00e9cole": "pas de vraie vie" }, "valid": false }, { "description": "ascii characters match", "data": { "l'ecole": "pas de vraie vie" }, "valid": true } ] }, { "description": "\\d in patternProperties matches [0-9], not unicode digits", "schema": { "type": "object", "patternProperties": { "^\\d+$": true }, "additionalProperties": false }, "tests": [ { "description": "ascii digits", "data": { "42": "life, the universe, and everything" }, "valid": true }, { "description": "ascii non-digits", "data": { "-%#": "spending the year dead for tax reasons" }, "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": { "৪২": "khajit has wares if you have coin" }, "valid": false } ] }, { "description": "patternProperties with non-ASCII digits", "schema": { "type": "object", "patternProperties": { "^\\p{digit}+$": true }, "additionalProperties": false }, "tests": [ { "description": "ascii digits", "data": { "42": "life, the universe, and everything" }, "valid": true }, { "description": "ascii non-digits", "data": { "-%#": "spending the year dead for tax reasons" }, "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": { "৪২": "khajit has wares if you have coin" }, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/float-overflow.json000066400000000000000000000005511477700171100324610ustar00rootroot00000000000000[ { "description": "all integers are multiples of 0.5, if overflow is handled", "schema": {"type": "integer", "multipleOf": 0.5}, "tests": [ { "description": "valid if optional overflow handling is implemented", "data": 1e308, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/000077500000000000000000000000001477700171100301075ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/date-time.json000066400000000000000000000110601477700171100326510ustar00rootroot00000000000000[ { "description": "validation of date-time strings", "schema": { "format": "date-time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid date-time string", "data": "1963-06-19T08:30:06.283185Z", "valid": true }, { "description": "a valid date-time string without second fraction", "data": "1963-06-19T08:30:06Z", "valid": true }, { "description": "a valid date-time string with plus offset", "data": "1937-01-01T12:00:27.87+00:20", "valid": true }, { "description": "a valid date-time string with minus offset", "data": "1990-12-31T15:59:50.123-08:00", "valid": true }, { "description": "a valid date-time with a leap second, UTC", "data": "1998-12-31T23:59:60Z", "valid": true }, { "description": "a valid date-time with a leap second, with minus offset", "data": "1998-12-31T15:59:60.123-08:00", "valid": true }, { "description": "an invalid date-time past leap second, UTC", "data": "1998-12-31T23:59:61Z", "valid": false }, { "description": "an invalid date-time with leap second on a wrong minute, UTC", "data": "1998-12-31T23:58:60Z", "valid": false }, { "description": "an invalid date-time with leap second on a wrong hour, UTC", "data": "1998-12-31T22:59:60Z", "valid": false }, { "description": "an invalid day in date-time string", "data": "1990-02-31T15:59:59.123-08:00", "valid": false }, { "description": "an invalid offset in date-time string", "data": "1990-12-31T15:59:59-24:00", "valid": false }, { "description": "an invalid closing Z after time-zone offset", "data": "1963-06-19T08:30:06.28123+01:00Z", "valid": false }, { "description": "an invalid date-time string", "data": "06/19/1963 08:30:06 PST", "valid": false }, { "description": "case-insensitive T and Z", "data": "1963-06-19t08:30:06.283185z", "valid": true }, { "description": "only RFC3339 not all of ISO 8601 are valid", "data": "2013-350T01:01:01", "valid": false }, { "description": "invalid non-padded month dates", "data": "1963-6-19T08:30:06.283185Z", "valid": false }, { "description": "invalid non-padded day dates", "data": "1963-06-1T08:30:06.283185Z", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4) in date portion", "data": "1963-06-1৪T00:00:00Z", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4) in time portion", "data": "1963-06-11T0৪:00:00Z", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/email.json000066400000000000000000000051041477700171100320710ustar00rootroot00000000000000[ { "description": "validation of e-mail addresses", "schema": { "format": "email" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid e-mail address", "data": "joe.bloggs@example.com", "valid": true }, { "description": "an invalid e-mail address", "data": "2962", "valid": false }, { "description": "tilde in local part is valid", "data": "te~st@example.com", "valid": true }, { "description": "tilde before local part is valid", "data": "~test@example.com", "valid": true }, { "description": "tilde after local part is valid", "data": "test~@example.com", "valid": true }, { "description": "dot before local part is not valid", "data": ".test@example.com", "valid": false }, { "description": "dot after local part is not valid", "data": "test.@example.com", "valid": false }, { "description": "two separated dots inside local part are valid", "data": "te.s.t@example.com", "valid": true }, { "description": "two subsequent dots inside local part are not valid", "data": "te..st@example.com", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/hostname.json000066400000000000000000000073671477700171100326350ustar00rootroot00000000000000[ { "description": "validation of host names", "schema": { "format": "hostname" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid host name", "data": "www.example.com", "valid": true }, { "description": "a valid punycoded IDN hostname", "data": "xn--4gbwdl.xn--wgbh1c", "valid": true }, { "description": "a host name starting with an illegal character", "data": "-a-host-name-that-starts-with--", "valid": false }, { "description": "a host name containing illegal characters", "data": "not_a_valid_host_name", "valid": false }, { "description": "a host name with a component too long", "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", "valid": false }, { "description": "starts with hyphen", "data": "-hostname", "valid": false }, { "description": "ends with hyphen", "data": "hostname-", "valid": false }, { "description": "starts with underscore", "data": "_hostname", "valid": false }, { "description": "ends with underscore", "data": "hostname_", "valid": false }, { "description": "contains underscore", "data": "host_name", "valid": false }, { "description": "maximum label length", "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.com", "valid": true }, { "description": "exceeds maximum label length", "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl.com", "valid": false }, { "description": "single label", "data": "hostname", "valid": true }, { "description": "single label with hyphen", "data": "host-name", "valid": true }, { "description": "single label with digits", "data": "h0stn4me", "valid": true }, { "description": "single label ending with digit", "data": "hostnam3", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/ipv4.json000066400000000000000000000056621477700171100316750ustar00rootroot00000000000000[ { "description": "validation of IP addresses", "schema": { "format": "ipv4" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid IP address", "data": "192.168.0.1", "valid": true }, { "description": "an IP address with too many components", "data": "127.0.0.0.1", "valid": false }, { "description": "an IP address with out-of-range values", "data": "256.256.256.256", "valid": false }, { "description": "an IP address without 4 components", "data": "127.0", "valid": false }, { "description": "an IP address as an integer", "data": "0x7f000001", "valid": false }, { "description": "an IP address as an integer (decimal)", "data": "2130706433", "valid": false }, { "description": "invalid leading zeroes, as they are treated as octals", "comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/", "data": "087.10.0.1", "valid": false }, { "description": "value without leading zero is valid", "data": "87.10.0.1", "valid": true }, { "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২7.0.0.1", "valid": false }, { "description": "netmask is not a part of ipv4 address", "data": "192.168.1.0/24", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/ipv6.json000066400000000000000000000154371477700171100317000ustar00rootroot00000000000000[ { "description": "validation of IPv6 addresses", "schema": { "format": "ipv6" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid IPv6 address", "data": "::1", "valid": true }, { "description": "an IPv6 address with out-of-range values", "data": "12345::", "valid": false }, { "description": "trailing 4 hex symbols is valid", "data": "::abef", "valid": true }, { "description": "trailing 5 hex symbols is invalid", "data": "::abcef", "valid": false }, { "description": "an IPv6 address with too many components", "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", "valid": false }, { "description": "an IPv6 address containing illegal characters", "data": "::laptop", "valid": false }, { "description": "no digits is valid", "data": "::", "valid": true }, { "description": "leading colons is valid", "data": "::42:ff:1", "valid": true }, { "description": "trailing colons is valid", "data": "d6::", "valid": true }, { "description": "missing leading octet is invalid", "data": ":2:3:4:5:6:7:8", "valid": false }, { "description": "missing trailing octet is invalid", "data": "1:2:3:4:5:6:7:", "valid": false }, { "description": "missing leading octet with omitted octets later", "data": ":2:3:4::8", "valid": false }, { "description": "single set of double colons in the middle is valid", "data": "1:d6::42", "valid": true }, { "description": "two sets of double colons is invalid", "data": "1::d6::42", "valid": false }, { "description": "mixed format with the ipv4 section as decimal octets", "data": "1::d6:192.168.0.1", "valid": true }, { "description": "mixed format with double colons between the sections", "data": "1:2::192.168.0.1", "valid": true }, { "description": "mixed format with ipv4 section with octet out of range", "data": "1::2:192.168.256.1", "valid": false }, { "description": "mixed format with ipv4 section with a hex octet", "data": "1::2:192.168.ff.1", "valid": false }, { "description": "mixed format with leading double colons (ipv4-mapped ipv6 address)", "data": "::ffff:192.168.0.1", "valid": true }, { "description": "triple colons is invalid", "data": "1:2:3:4:5:::8", "valid": false }, { "description": "8 octets", "data": "1:2:3:4:5:6:7:8", "valid": true }, { "description": "insufficient octets without double colons", "data": "1:2:3:4:5:6:7", "valid": false }, { "description": "no colons is invalid", "data": "1", "valid": false }, { "description": "ipv4 is not ipv6", "data": "127.0.0.1", "valid": false }, { "description": "ipv4 segment must have 4 octets", "data": "1:2:3:4:1.2.3", "valid": false }, { "description": "leading whitespace is invalid", "data": " ::1", "valid": false }, { "description": "trailing whitespace is invalid", "data": "::1 ", "valid": false }, { "description": "netmask is not a part of ipv6 address", "data": "fe80::/64", "valid": false }, { "description": "zone id is not a part of ipv6 address", "data": "fe80::a%eth1", "valid": false }, { "description": "a long valid ipv6", "data": "1000:1000:1000:1000:1000:1000:255.255.255.255", "valid": true }, { "description": "a long invalid ipv6, below length limit, first", "data": "100:100:100:100:100:100:255.255.255.255.255", "valid": false }, { "description": "a long invalid ipv6, below length limit, second", "data": "100:100:100:100:100:100:100:255.255.255.255", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4)", "data": "1:2:3:4:5:6:7:৪", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4) in the IPv4 portion", "data": "1:2::192.16৪.0.1", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/json-pointer.json000066400000000000000000000150631477700171100334360ustar00rootroot00000000000000[ { "description": "validation of JSON-pointers (JSON String Representation)", "schema": { "format": "json-pointer" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid JSON-pointer", "data": "/foo/bar~0/baz~1/%a", "valid": true }, { "description": "not a valid JSON-pointer (~ not escaped)", "data": "/foo/bar~", "valid": false }, { "description": "valid JSON-pointer with empty segment", "data": "/foo//bar", "valid": true }, { "description": "valid JSON-pointer with the last empty segment", "data": "/foo/bar/", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #1", "data": "", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #2", "data": "/foo", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #3", "data": "/foo/0", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #4", "data": "/", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #5", "data": "/a~1b", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #6", "data": "/c%d", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #7", "data": "/e^f", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #8", "data": "/g|h", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #9", "data": "/i\\j", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #10", "data": "/k\"l", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #11", "data": "/ ", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #12", "data": "/m~0n", "valid": true }, { "description": "valid JSON-pointer used adding to the last array position", "data": "/foo/-", "valid": true }, { "description": "valid JSON-pointer (- used as object member name)", "data": "/foo/-/bar", "valid": true }, { "description": "valid JSON-pointer (multiple escaped characters)", "data": "/~1~0~0~1~1", "valid": true }, { "description": "valid JSON-pointer (escaped with fraction part) #1", "data": "/~1.1", "valid": true }, { "description": "valid JSON-pointer (escaped with fraction part) #2", "data": "/~0.1", "valid": true }, { "description": "not a valid JSON-pointer (URI Fragment Identifier) #1", "data": "#", "valid": false }, { "description": "not a valid JSON-pointer (URI Fragment Identifier) #2", "data": "#/", "valid": false }, { "description": "not a valid JSON-pointer (URI Fragment Identifier) #3", "data": "#a", "valid": false }, { "description": "not a valid JSON-pointer (some escaped, but not all) #1", "data": "/~0~", "valid": false }, { "description": "not a valid JSON-pointer (some escaped, but not all) #2", "data": "/~0/~", "valid": false }, { "description": "not a valid JSON-pointer (wrong escape character) #1", "data": "/~2", "valid": false }, { "description": "not a valid JSON-pointer (wrong escape character) #2", "data": "/~-1", "valid": false }, { "description": "not a valid JSON-pointer (multiple characters not escaped)", "data": "/~~", "valid": false }, { "description": "not a valid JSON-pointer (isn't empty nor starts with /) #1", "data": "a", "valid": false }, { "description": "not a valid JSON-pointer (isn't empty nor starts with /) #2", "data": "0", "valid": false }, { "description": "not a valid JSON-pointer (isn't empty nor starts with /) #3", "data": "a/a", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/unknown.json000066400000000000000000000022631477700171100325040ustar00rootroot00000000000000[ { "description": "unknown format", "schema": { "format": "unknown" }, "tests": [ { "description": "unknown formats ignore integers", "data": 12, "valid": true }, { "description": "unknown formats ignore floats", "data": 13.7, "valid": true }, { "description": "unknown formats ignore objects", "data": {}, "valid": true }, { "description": "unknown formats ignore arrays", "data": [], "valid": true }, { "description": "unknown formats ignore booleans", "data": false, "valid": true }, { "description": "unknown formats ignore nulls", "data": null, "valid": true }, { "description": "unknown formats ignore strings", "data": "string", "valid": true } ] } ] uri-reference.json000066400000000000000000000042371477700171100334640ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format[ { "description": "validation of URI References", "schema": { "format": "uri-reference" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid URI", "data": "http://foo.bar/?baz=qux#quux", "valid": true }, { "description": "a valid protocol-relative URI Reference", "data": "//foo.bar/?baz=qux#quux", "valid": true }, { "description": "a valid relative URI Reference", "data": "/abc", "valid": true }, { "description": "an invalid URI Reference", "data": "\\\\WINDOWS\\fileshare", "valid": false }, { "description": "a valid URI Reference", "data": "abc", "valid": true }, { "description": "a valid URI fragment", "data": "#fragment", "valid": true }, { "description": "an invalid URI fragment", "data": "#frag\\ment", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/uri-template.json000066400000000000000000000034311477700171100334130ustar00rootroot00000000000000[ { "description": "format: uri-template", "schema": { "format": "uri-template" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid uri-template", "data": "http://example.com/dictionary/{term:1}/{term}", "valid": true }, { "description": "an invalid uri-template", "data": "http://example.com/dictionary/{term:1}/{term", "valid": false }, { "description": "a valid uri-template without variables", "data": "http://example.com/dictionary", "valid": true }, { "description": "a valid relative uri-template", "data": "dictionary/{term:1}/{term}", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/uri.json000066400000000000000000000110341477700171100316000ustar00rootroot00000000000000[ { "description": "validation of URIs", "schema": { "format": "uri" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid URL with anchor tag", "data": "http://foo.bar/?baz=qux#quux", "valid": true }, { "description": "a valid URL with anchor tag and parentheses", "data": "http://foo.com/blah_(wikipedia)_blah#cite-1", "valid": true }, { "description": "a valid URL with URL-encoded stuff", "data": "http://foo.bar/?q=Test%20URL-encoded%20stuff", "valid": true }, { "description": "a valid puny-coded URL ", "data": "http://xn--nw2a.xn--j6w193g/", "valid": true }, { "description": "a valid URL with many special characters", "data": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", "valid": true }, { "description": "a valid URL based on IPv4", "data": "http://223.255.255.254", "valid": true }, { "description": "a valid URL with ftp scheme", "data": "ftp://ftp.is.co.za/rfc/rfc1808.txt", "valid": true }, { "description": "a valid URL for a simple text file", "data": "http://www.ietf.org/rfc/rfc2396.txt", "valid": true }, { "description": "a valid URL ", "data": "ldap://[2001:db8::7]/c=GB?objectClass?one", "valid": true }, { "description": "a valid mailto URI", "data": "mailto:John.Doe@example.com", "valid": true }, { "description": "a valid newsgroup URI", "data": "news:comp.infosystems.www.servers.unix", "valid": true }, { "description": "a valid tel URI", "data": "tel:+1-816-555-1212", "valid": true }, { "description": "a valid URN", "data": "urn:oasis:names:specification:docbook:dtd:xml:4.1.2", "valid": true }, { "description": "an invalid protocol-relative URI Reference", "data": "//foo.bar/?baz=qux#quux", "valid": false }, { "description": "an invalid relative URI Reference", "data": "/abc", "valid": false }, { "description": "an invalid URI", "data": "\\\\WINDOWS\\fileshare", "valid": false }, { "description": "an invalid URI though valid URI reference", "data": "abc", "valid": false }, { "description": "an invalid URI with spaces", "data": "http:// shouldfail.com", "valid": false }, { "description": "an invalid URI with spaces and missing scheme", "data": ":// should fail", "valid": false }, { "description": "an invalid URI with comma in scheme", "data": "bar,baz:foo", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/non-bmp-regex.json000066400000000000000000000045361477700171100322000ustar00rootroot00000000000000[ { "description": "Proper UTF-16 surrogate pair handling: pattern", "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", "schema": { "pattern": "^🐲*$" }, "tests": [ { "description": "matches empty", "data": "", "valid": true }, { "description": "matches single", "data": "🐲", "valid": true }, { "description": "matches two", "data": "🐲🐲", "valid": true }, { "description": "doesn't match one", "data": "🐉", "valid": false }, { "description": "doesn't match two", "data": "🐉🐉", "valid": false }, { "description": "doesn't match one ASCII", "data": "D", "valid": false }, { "description": "doesn't match two ASCII", "data": "DD", "valid": false } ] }, { "description": "Proper UTF-16 surrogate pair handling: patternProperties", "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", "schema": { "patternProperties": { "^🐲*$": { "type": "integer" } } }, "tests": [ { "description": "matches empty", "data": { "": 1 }, "valid": true }, { "description": "matches single", "data": { "🐲": 1 }, "valid": true }, { "description": "matches two", "data": { "🐲🐲": 1 }, "valid": true }, { "description": "doesn't match one", "data": { "🐲": "hello" }, "valid": false }, { "description": "doesn't match two", "data": { "🐲🐲": "hello" }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/pattern.json000066400000000000000000000030031477700171100273360ustar00rootroot00000000000000[ { "description": "pattern validation", "schema": {"pattern": "^a*$"}, "tests": [ { "description": "a matching pattern is valid", "data": "aaa", "valid": true }, { "description": "a non-matching pattern is invalid", "data": "abc", "valid": false }, { "description": "ignores booleans", "data": true, "valid": true }, { "description": "ignores integers", "data": 123, "valid": true }, { "description": "ignores floats", "data": 1.0, "valid": true }, { "description": "ignores objects", "data": {}, "valid": true }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores null", "data": null, "valid": true } ] }, { "description": "pattern is not anchored", "schema": {"pattern": "a+"}, "tests": [ { "description": "matches a substring", "data": "xxaayy", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/patternProperties.json000066400000000000000000000120711477700171100314200ustar00rootroot00000000000000[ { "description": "patternProperties validates properties matching a regex", "schema": { "patternProperties": { "f.*o": {"type": "integer"} } }, "tests": [ { "description": "a single valid match is valid", "data": {"foo": 1}, "valid": true }, { "description": "multiple valid matches is valid", "data": {"foo": 1, "foooooo" : 2}, "valid": true }, { "description": "a single invalid match is invalid", "data": {"foo": "bar", "fooooo": 2}, "valid": false }, { "description": "multiple invalid matches is invalid", "data": {"foo": "bar", "foooooo" : "baz"}, "valid": false }, { "description": "ignores arrays", "data": ["foo"], "valid": true }, { "description": "ignores strings", "data": "foo", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "multiple simultaneous patternProperties are validated", "schema": { "patternProperties": { "a*": {"type": "integer"}, "aaa*": {"maximum": 20} } }, "tests": [ { "description": "a single valid match is valid", "data": {"a": 21}, "valid": true }, { "description": "a simultaneous match is valid", "data": {"aaaa": 18}, "valid": true }, { "description": "multiple matches is valid", "data": {"a": 21, "aaaa": 18}, "valid": true }, { "description": "an invalid due to one is invalid", "data": {"a": "bar"}, "valid": false }, { "description": "an invalid due to the other is invalid", "data": {"aaaa": 31}, "valid": false }, { "description": "an invalid due to both is invalid", "data": {"aaa": "foo", "aaaa": 31}, "valid": false } ] }, { "description": "regexes are not anchored by default and are case sensitive", "schema": { "patternProperties": { "[0-9]{2,}": { "type": "boolean" }, "X_": { "type": "string" } } }, "tests": [ { "description": "non recognized members are ignored", "data": { "answer 1": "42" }, "valid": true }, { "description": "recognized members are accounted for", "data": { "a31b": null }, "valid": false }, { "description": "regexes are case sensitive", "data": { "a_x_3": 3 }, "valid": true }, { "description": "regexes are case sensitive, 2", "data": { "a_X_3": 3 }, "valid": false } ] }, { "description": "patternProperties with boolean schemas", "schema": { "patternProperties": { "f.*": true, "b.*": false } }, "tests": [ { "description": "object with property matching schema true is valid", "data": {"foo": 1}, "valid": true }, { "description": "object with property matching schema false is invalid", "data": {"bar": 2}, "valid": false }, { "description": "object with both properties is invalid", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "object with a property matching both true and false is invalid", "data": {"foobar":1}, "valid": false }, { "description": "empty object is valid", "data": {}, "valid": true } ] }, { "description": "patternProperties with null valued instance properties", "schema": { "patternProperties": { "^.*bar$": {"type": "null"} } }, "tests": [ { "description": "allows null values", "data": {"foobar": null}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/properties.json000066400000000000000000000162111477700171100300620ustar00rootroot00000000000000[ { "description": "object properties validation", "schema": { "properties": { "foo": {"type": "integer"}, "bar": {"type": "string"} } }, "tests": [ { "description": "both properties present and valid is valid", "data": {"foo": 1, "bar": "baz"}, "valid": true }, { "description": "one property invalid is invalid", "data": {"foo": 1, "bar": {}}, "valid": false }, { "description": "both properties invalid is invalid", "data": {"foo": [], "bar": {}}, "valid": false }, { "description": "doesn't invalidate other properties", "data": {"quux": []}, "valid": true }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "properties, patternProperties, additionalProperties interaction", "schema": { "properties": { "foo": {"type": "array", "maxItems": 3}, "bar": {"type": "array"} }, "patternProperties": {"f.o": {"minItems": 2}}, "additionalProperties": {"type": "integer"} }, "tests": [ { "description": "property validates property", "data": {"foo": [1, 2]}, "valid": true }, { "description": "property invalidates property", "data": {"foo": [1, 2, 3, 4]}, "valid": false }, { "description": "patternProperty invalidates property", "data": {"foo": []}, "valid": false }, { "description": "patternProperty validates nonproperty", "data": {"fxo": [1, 2]}, "valid": true }, { "description": "patternProperty invalidates nonproperty", "data": {"fxo": []}, "valid": false }, { "description": "additionalProperty ignores property", "data": {"bar": []}, "valid": true }, { "description": "additionalProperty validates others", "data": {"quux": 3}, "valid": true }, { "description": "additionalProperty invalidates others", "data": {"quux": "foo"}, "valid": false } ] }, { "description": "properties with boolean schema", "schema": { "properties": { "foo": true, "bar": false } }, "tests": [ { "description": "no property present is valid", "data": {}, "valid": true }, { "description": "only 'true' property present is valid", "data": {"foo": 1}, "valid": true }, { "description": "only 'false' property present is invalid", "data": {"bar": 2}, "valid": false }, { "description": "both properties present is invalid", "data": {"foo": 1, "bar": 2}, "valid": false } ] }, { "description": "properties with escaped characters", "schema": { "properties": { "foo\nbar": {"type": "number"}, "foo\"bar": {"type": "number"}, "foo\\bar": {"type": "number"}, "foo\rbar": {"type": "number"}, "foo\tbar": {"type": "number"}, "foo\fbar": {"type": "number"} } }, "tests": [ { "description": "object with all numbers is valid", "data": { "foo\nbar": 1, "foo\"bar": 1, "foo\\bar": 1, "foo\rbar": 1, "foo\tbar": 1, "foo\fbar": 1 }, "valid": true }, { "description": "object with strings is invalid", "data": { "foo\nbar": "1", "foo\"bar": "1", "foo\\bar": "1", "foo\rbar": "1", "foo\tbar": "1", "foo\fbar": "1" }, "valid": false } ] }, { "description": "properties with null valued instance properties", "schema": { "properties": { "foo": {"type": "null"} } }, "tests": [ { "description": "allows null values", "data": {"foo": null}, "valid": true } ] }, { "description": "properties whose names are Javascript object property names", "comment": "Ensure JS implementations don't universally consider e.g. __proto__ to always be present in an object.", "schema": { "properties": { "__proto__": {"type": "number"}, "toString": { "properties": { "length": { "type": "string" } } }, "constructor": {"type": "number"} } }, "tests": [ { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true }, { "description": "none of the properties mentioned", "data": {}, "valid": true }, { "description": "__proto__ not valid", "data": { "__proto__": "foo" }, "valid": false }, { "description": "toString not valid", "data": { "toString": { "length": 37 } }, "valid": false }, { "description": "constructor not valid", "data": { "constructor": { "length": 37 } }, "valid": false }, { "description": "all present and valid", "data": { "__proto__": 12, "toString": { "length": "foo" }, "constructor": 37 }, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/propertyNames.json000066400000000000000000000055771477700171100305530ustar00rootroot00000000000000[ { "description": "propertyNames validation", "schema": { "propertyNames": {"maxLength": 3} }, "tests": [ { "description": "all property names valid", "data": { "f": {}, "foo": {} }, "valid": true }, { "description": "some property names invalid", "data": { "foo": {}, "foobar": {} }, "valid": false }, { "description": "object without properties is valid", "data": {}, "valid": true }, { "description": "ignores arrays", "data": [1, 2, 3, 4], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "propertyNames validation with pattern", "schema": { "propertyNames": { "pattern": "^a+$" } }, "tests": [ { "description": "matching property names valid", "data": { "a": {}, "aa": {}, "aaa": {} }, "valid": true }, { "description": "non-matching property name is invalid", "data": { "aaA": {} }, "valid": false }, { "description": "object without properties is valid", "data": {}, "valid": true } ] }, { "description": "propertyNames with boolean schema true", "schema": {"propertyNames": true}, "tests": [ { "description": "object with any properties is valid", "data": {"foo": 1}, "valid": true }, { "description": "empty object is valid", "data": {}, "valid": true } ] }, { "description": "propertyNames with boolean schema false", "schema": {"propertyNames": false}, "tests": [ { "description": "object with any properties is invalid", "data": {"foo": 1}, "valid": false }, { "description": "empty object is valid", "data": {}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/ref.json000066400000000000000000000652131477700171100264500ustar00rootroot00000000000000[ { "description": "root pointer ref", "schema": { "properties": { "foo": {"$ref": "#"} }, "additionalProperties": false }, "tests": [ { "description": "match", "data": {"foo": false}, "valid": true }, { "description": "recursive match", "data": {"foo": {"foo": false}}, "valid": true }, { "description": "mismatch", "data": {"bar": false}, "valid": false }, { "description": "recursive mismatch", "data": {"foo": {"bar": false}}, "valid": false } ] }, { "description": "relative pointer ref to object", "schema": { "properties": { "foo": {"type": "integer"}, "bar": {"$ref": "#/properties/foo"} } }, "tests": [ { "description": "match", "data": {"bar": 3}, "valid": true }, { "description": "mismatch", "data": {"bar": true}, "valid": false } ] }, { "description": "relative pointer ref to array", "schema": { "items": [ {"type": "integer"}, {"$ref": "#/items/0"} ] }, "tests": [ { "description": "match array", "data": [1, 2], "valid": true }, { "description": "mismatch array", "data": [1, "foo"], "valid": false } ] }, { "description": "escaped pointer ref", "schema": { "definitions": { "tilde~field": {"type": "integer"}, "slash/field": {"type": "integer"}, "percent%field": {"type": "integer"} }, "properties": { "tilde": {"$ref": "#/definitions/tilde~0field"}, "slash": {"$ref": "#/definitions/slash~1field"}, "percent": {"$ref": "#/definitions/percent%25field"} } }, "tests": [ { "description": "slash invalid", "data": {"slash": "aoeu"}, "valid": false }, { "description": "tilde invalid", "data": {"tilde": "aoeu"}, "valid": false }, { "description": "percent invalid", "data": {"percent": "aoeu"}, "valid": false }, { "description": "slash valid", "data": {"slash": 123}, "valid": true }, { "description": "tilde valid", "data": {"tilde": 123}, "valid": true }, { "description": "percent valid", "data": {"percent": 123}, "valid": true } ] }, { "description": "nested refs", "schema": { "definitions": { "a": {"type": "integer"}, "b": {"$ref": "#/definitions/a"}, "c": {"$ref": "#/definitions/b"} }, "allOf": [{ "$ref": "#/definitions/c" }] }, "tests": [ { "description": "nested ref valid", "data": 5, "valid": true }, { "description": "nested ref invalid", "data": "a", "valid": false } ] }, { "description": "ref overrides any sibling keywords", "schema": { "definitions": { "reffed": { "type": "array" } }, "properties": { "foo": { "$ref": "#/definitions/reffed", "maxItems": 2 } } }, "tests": [ { "description": "ref valid", "data": { "foo": [] }, "valid": true }, { "description": "ref valid, maxItems ignored", "data": { "foo": [ 1, 2, 3] }, "valid": true }, { "description": "ref invalid", "data": { "foo": "string" }, "valid": false } ] }, { "description": "$ref prevents a sibling $id from changing the base uri", "schema": { "$id": "http://localhost:1234/sibling_id/base/", "definitions": { "foo": { "$id": "http://localhost:1234/sibling_id/foo.json", "type": "string" }, "base_foo": { "$comment": "this canonical uri is http://localhost:1234/sibling_id/base/foo.json", "$id": "foo.json", "type": "number" } }, "allOf": [ { "$comment": "$ref resolves to http://localhost:1234/sibling_id/base/foo.json, not http://localhost:1234/sibling_id/foo.json", "$id": "http://localhost:1234/sibling_id/", "$ref": "foo.json" } ] }, "tests": [ { "description": "$ref resolves to /definitions/base_foo, data does not validate", "data": "a", "valid": false }, { "description": "$ref resolves to /definitions/base_foo, data validates", "data": 1, "valid": true } ] }, { "description": "remote ref, containing refs itself", "schema": {"$ref": "http://json-schema.org/draft-06/schema#"}, "tests": [ { "description": "remote ref valid", "data": {"minLength": 1}, "valid": true }, { "description": "remote ref invalid", "data": {"minLength": -1}, "valid": false } ] }, { "description": "property named $ref that is not a reference", "schema": { "properties": { "$ref": {"type": "string"} } }, "tests": [ { "description": "property named $ref valid", "data": {"$ref": "a"}, "valid": true }, { "description": "property named $ref invalid", "data": {"$ref": 2}, "valid": false } ] }, { "description": "property named $ref, containing an actual $ref", "schema": { "properties": { "$ref": {"$ref": "#/definitions/is-string"} }, "definitions": { "is-string": { "type": "string" } } }, "tests": [ { "description": "property named $ref valid", "data": {"$ref": "a"}, "valid": true }, { "description": "property named $ref invalid", "data": {"$ref": 2}, "valid": false } ] }, { "description": "$ref to boolean schema true", "schema": { "allOf": [{ "$ref": "#/definitions/bool" }], "definitions": { "bool": true } }, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "$ref to boolean schema false", "schema": { "allOf": [{ "$ref": "#/definitions/bool" }], "definitions": { "bool": false } }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "Recursive references between schemas", "schema": { "$id": "http://localhost:1234/tree", "description": "tree of nodes", "type": "object", "properties": { "meta": {"type": "string"}, "nodes": { "type": "array", "items": {"$ref": "node"} } }, "required": ["meta", "nodes"], "definitions": { "node": { "$id": "http://localhost:1234/node", "description": "node", "type": "object", "properties": { "value": {"type": "number"}, "subtree": {"$ref": "tree"} }, "required": ["value"] } } }, "tests": [ { "description": "valid tree", "data": { "meta": "root", "nodes": [ { "value": 1, "subtree": { "meta": "child", "nodes": [ {"value": 1.1}, {"value": 1.2} ] } }, { "value": 2, "subtree": { "meta": "child", "nodes": [ {"value": 2.1}, {"value": 2.2} ] } } ] }, "valid": true }, { "description": "invalid tree", "data": { "meta": "root", "nodes": [ { "value": 1, "subtree": { "meta": "child", "nodes": [ {"value": "string is invalid"}, {"value": 1.2} ] } }, { "value": 2, "subtree": { "meta": "child", "nodes": [ {"value": 2.1}, {"value": 2.2} ] } } ] }, "valid": false } ] }, { "description": "refs with quote", "schema": { "properties": { "foo\"bar": {"$ref": "#/definitions/foo%22bar"} }, "definitions": { "foo\"bar": {"type": "number"} } }, "tests": [ { "description": "object with numbers is valid", "data": { "foo\"bar": 1 }, "valid": true }, { "description": "object with strings is invalid", "data": { "foo\"bar": "1" }, "valid": false } ] }, { "description": "Location-independent identifier", "schema": { "allOf": [{ "$ref": "#foo" }], "definitions": { "A": { "$id": "#foo", "type": "integer" } } }, "tests": [ { "data": 1, "description": "match", "valid": true }, { "data": "a", "description": "mismatch", "valid": false } ] }, { "description": "Reference an anchor with a non-relative URI", "schema": { "$id": "https://example.com/schema-with-anchor", "allOf": [{ "$ref": "https://example.com/schema-with-anchor#foo" }], "definitions": { "A": { "$id": "#foo", "type": "integer" } } }, "tests": [ { "data": 1, "description": "match", "valid": true }, { "data": "a", "description": "mismatch", "valid": false } ] }, { "description": "Location-independent identifier with base URI change in subschema", "schema": { "$id": "http://localhost:1234/root", "allOf": [{ "$ref": "http://localhost:1234/nested.json#foo" }], "definitions": { "A": { "$id": "nested.json", "definitions": { "B": { "$id": "#foo", "type": "integer" } } } } }, "tests": [ { "data": 1, "description": "match", "valid": true }, { "data": "a", "description": "mismatch", "valid": false } ] }, { "description": "naive replacement of $ref with its destination is not correct", "schema": { "definitions": { "a_string": { "type": "string" } }, "enum": [ { "$ref": "#/definitions/a_string" } ] }, "tests": [ { "description": "do not evaluate the $ref inside the enum, matching any string", "data": "this is a string", "valid": false }, { "description": "do not evaluate the $ref inside the enum, definition exact match", "data": { "type": "string" }, "valid": false }, { "description": "match the enum exactly", "data": { "$ref": "#/definitions/a_string" }, "valid": true } ] }, { "description": "refs with relative uris and defs", "schema": { "$id": "http://example.com/schema-relative-uri-defs1.json", "properties": { "foo": { "$id": "schema-relative-uri-defs2.json", "definitions": { "inner": { "properties": { "bar": { "type": "string" } } } }, "allOf": [ { "$ref": "#/definitions/inner" } ] } }, "allOf": [ { "$ref": "schema-relative-uri-defs2.json" } ] }, "tests": [ { "description": "invalid on inner field", "data": { "foo": { "bar": 1 }, "bar": "a" }, "valid": false }, { "description": "invalid on outer field", "data": { "foo": { "bar": "a" }, "bar": 1 }, "valid": false }, { "description": "valid on both fields", "data": { "foo": { "bar": "a" }, "bar": "a" }, "valid": true } ] }, { "description": "relative refs with absolute uris and defs", "schema": { "$id": "http://example.com/schema-refs-absolute-uris-defs1.json", "properties": { "foo": { "$id": "http://example.com/schema-refs-absolute-uris-defs2.json", "definitions": { "inner": { "properties": { "bar": { "type": "string" } } } }, "allOf": [ { "$ref": "#/definitions/inner" } ] } }, "allOf": [ { "$ref": "schema-refs-absolute-uris-defs2.json" } ] }, "tests": [ { "description": "invalid on inner field", "data": { "foo": { "bar": 1 }, "bar": "a" }, "valid": false }, { "description": "invalid on outer field", "data": { "foo": { "bar": "a" }, "bar": 1 }, "valid": false }, { "description": "valid on both fields", "data": { "foo": { "bar": "a" }, "bar": "a" }, "valid": true } ] }, { "description": "simple URN base URI with $ref via the URN", "schema": { "$comment": "URIs do not have to have HTTP(s) schemes", "$id": "urn:uuid:deadbeef-1234-ffff-ffff-4321feebdaed", "minimum": 30, "properties": { "foo": {"$ref": "urn:uuid:deadbeef-1234-ffff-ffff-4321feebdaed"} } }, "tests": [ { "description": "valid under the URN IDed schema", "data": {"foo": 37}, "valid": true }, { "description": "invalid under the URN IDed schema", "data": {"foo": 12}, "valid": false } ] }, { "description": "simple URN base URI with JSON pointer", "schema": { "$comment": "URIs do not have to have HTTP(s) schemes", "$id": "urn:uuid:deadbeef-1234-00ff-ff00-4321feebdaed", "properties": { "foo": {"$ref": "#/definitions/bar"} }, "definitions": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with NSS", "schema": { "$comment": "RFC 8141 §2.2", "$id": "urn:example:1/406/47452/2", "properties": { "foo": {"$ref": "#/definitions/bar"} }, "definitions": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with r-component", "schema": { "$comment": "RFC 8141 §2.3.1", "$id": "urn:example:foo-bar-baz-qux?+CCResolve:cc=uk", "properties": { "foo": {"$ref": "#/definitions/bar"} }, "definitions": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with q-component", "schema": { "$comment": "RFC 8141 §2.3.2", "$id": "urn:example:weather?=op=map&lat=39.56&lon=-104.85&datetime=1969-07-21T02:56:15Z", "properties": { "foo": {"$ref": "#/definitions/bar"} }, "definitions": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with URN and JSON pointer ref", "schema": { "$id": "urn:uuid:deadbeef-1234-0000-0000-4321feebdaed", "properties": { "foo": {"$ref": "urn:uuid:deadbeef-1234-0000-0000-4321feebdaed#/definitions/bar"} }, "definitions": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with URN and anchor ref", "schema": { "$id": "urn:uuid:deadbeef-1234-ff00-00ff-4321feebdaed", "properties": { "foo": {"$ref": "urn:uuid:deadbeef-1234-ff00-00ff-4321feebdaed#something"} }, "definitions": { "bar": { "$id": "#something", "type": "string" } } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "ref with absolute-path-reference", "schema": { "$id": "http://example.com/ref/absref.json", "definitions": { "a": { "$id": "http://example.com/ref/absref/foobar.json", "type": "number" }, "b": { "$id": "http://example.com/absref/foobar.json", "type": "string" } }, "allOf": [ { "$ref": "/absref/foobar.json" } ] }, "tests": [ { "description": "a string is valid", "data": "foo", "valid": true }, { "description": "an integer is invalid", "data": 12, "valid": false } ] }, { "description": "$id with file URI still resolves pointers - *nix", "schema": { "$id": "file:///folder/file.json", "definitions": { "foo": { "type": "number" } }, "allOf": [ { "$ref": "#/definitions/foo" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] }, { "description": "$id with file URI still resolves pointers - windows", "schema": { "$id": "file:///c:/folder/file.json", "definitions": { "foo": { "type": "number" } }, "allOf": [ { "$ref": "#/definitions/foo" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] }, { "description": "empty tokens in $ref json-pointer", "schema": { "definitions": { "": { "definitions": { "": { "type": "number" } } } }, "allOf": [ { "$ref": "#/definitions//definitions/" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/refRemote.json000066400000000000000000000160651477700171100276250ustar00rootroot00000000000000[ { "description": "remote ref", "schema": {"$ref": "http://localhost:1234/integer.json"}, "tests": [ { "description": "remote ref valid", "data": 1, "valid": true }, { "description": "remote ref invalid", "data": "a", "valid": false } ] }, { "description": "fragment within remote ref", "schema": {"$ref": "http://localhost:1234/subSchemas.json#/definitions/integer"}, "tests": [ { "description": "remote fragment valid", "data": 1, "valid": true }, { "description": "remote fragment invalid", "data": "a", "valid": false } ] }, { "description": "ref within remote ref", "schema": { "$ref": "http://localhost:1234/subSchemas.json#/definitions/refToInteger" }, "tests": [ { "description": "ref within ref valid", "data": 1, "valid": true }, { "description": "ref within ref invalid", "data": "a", "valid": false } ] }, { "description": "base URI change", "schema": { "$id": "http://localhost:1234/", "items": { "$id": "baseUriChange/", "items": {"$ref": "folderInteger.json"} } }, "tests": [ { "description": "base URI change ref valid", "data": [[1]], "valid": true }, { "description": "base URI change ref invalid", "data": [["a"]], "valid": false } ] }, { "description": "base URI change - change folder", "schema": { "$id": "http://localhost:1234/scope_change_defs1.json", "type" : "object", "properties": { "list": {"$ref": "#/definitions/baz"} }, "definitions": { "baz": { "$id": "baseUriChangeFolder/", "type": "array", "items": {"$ref": "folderInteger.json"} } } }, "tests": [ { "description": "number is valid", "data": {"list": [1]}, "valid": true }, { "description": "string is invalid", "data": {"list": ["a"]}, "valid": false } ] }, { "description": "base URI change - change folder in subschema", "schema": { "$id": "http://localhost:1234/scope_change_defs2.json", "type" : "object", "properties": { "list": {"$ref": "#/definitions/baz/definitions/bar"} }, "definitions": { "baz": { "$id": "baseUriChangeFolderInSubschema/", "definitions": { "bar": { "type": "array", "items": {"$ref": "folderInteger.json"} } } } } }, "tests": [ { "description": "number is valid", "data": {"list": [1]}, "valid": true }, { "description": "string is invalid", "data": {"list": ["a"]}, "valid": false } ] }, { "description": "root ref in remote ref", "schema": { "$id": "http://localhost:1234/object", "type": "object", "properties": { "name": {"$ref": "name.json#/definitions/orNull"} } }, "tests": [ { "description": "string is valid", "data": { "name": "foo" }, "valid": true }, { "description": "null is valid", "data": { "name": null }, "valid": true }, { "description": "object is invalid", "data": { "name": { "name": null } }, "valid": false } ] }, { "description": "remote ref with ref to definitions", "schema": { "$id": "http://localhost:1234/schema-remote-ref-ref-defs1.json", "allOf": [ { "$ref": "ref-and-definitions.json" } ] }, "tests": [ { "description": "invalid", "data": { "bar": 1 }, "valid": false }, { "description": "valid", "data": { "bar": "a" }, "valid": true } ] }, { "description": "Location-independent identifier in remote ref", "schema": { "$ref": "http://localhost:1234/locationIndependentIdentifierPre2019.json#/definitions/refToInteger" }, "tests": [ { "description": "integer is valid", "data": 1, "valid": true }, { "description": "string is invalid", "data": "foo", "valid": false } ] }, { "description": "retrieved nested refs resolve relative to their URI not $id", "schema": { "$id": "http://localhost:1234/some-id", "properties": { "name": {"$ref": "nested/foo-ref-string.json"} } }, "tests": [ { "description": "number is invalid", "data": { "name": {"foo": 1} }, "valid": false }, { "description": "string is valid", "data": { "name": {"foo": "a"} }, "valid": true } ] }, { "description": "$ref to $ref finds location-independent $id", "schema": { "$ref": "http://localhost:1234/draft6/detached-ref.json#/definitions/foo" }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/required.json000066400000000000000000000102341477700171100275050ustar00rootroot00000000000000[ { "description": "required validation", "schema": { "properties": { "foo": {}, "bar": {} }, "required": ["foo"] }, "tests": [ { "description": "present required property is valid", "data": {"foo": 1}, "valid": true }, { "description": "non-present required property is invalid", "data": {"bar": 1}, "valid": false }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores strings", "data": "", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "required default validation", "schema": { "properties": { "foo": {} } }, "tests": [ { "description": "not required by default", "data": {}, "valid": true } ] }, { "description": "required with empty array", "schema": { "properties": { "foo": {} }, "required": [] }, "tests": [ { "description": "property not required", "data": {}, "valid": true } ] }, { "description": "required with escaped characters", "schema": { "required": [ "foo\nbar", "foo\"bar", "foo\\bar", "foo\rbar", "foo\tbar", "foo\fbar" ] }, "tests": [ { "description": "object with all properties present is valid", "data": { "foo\nbar": 1, "foo\"bar": 1, "foo\\bar": 1, "foo\rbar": 1, "foo\tbar": 1, "foo\fbar": 1 }, "valid": true }, { "description": "object with some properties missing is invalid", "data": { "foo\nbar": "1", "foo\"bar": "1" }, "valid": false } ] }, { "description": "required properties whose names are Javascript object property names", "comment": "Ensure JS implementations don't universally consider e.g. __proto__ to always be present in an object.", "schema": { "required": ["__proto__", "toString", "constructor"] }, "tests": [ { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true }, { "description": "none of the properties mentioned", "data": {}, "valid": false }, { "description": "__proto__ present", "data": { "__proto__": "foo" }, "valid": false }, { "description": "toString present", "data": { "toString": { "length": 37 } }, "valid": false }, { "description": "constructor present", "data": { "constructor": { "length": 37 } }, "valid": false }, { "description": "all present", "data": { "__proto__": 12, "toString": { "length": "foo" }, "constructor": 37 }, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/type.json000066400000000000000000000321401477700171100266460ustar00rootroot00000000000000[ { "description": "integer type matches integers", "schema": {"type": "integer"}, "tests": [ { "description": "an integer is an integer", "data": 1, "valid": true }, { "description": "a float with zero fractional part is an integer", "data": 1.0, "valid": true }, { "description": "a float is not an integer", "data": 1.1, "valid": false }, { "description": "a string is not an integer", "data": "foo", "valid": false }, { "description": "a string is still not an integer, even if it looks like one", "data": "1", "valid": false }, { "description": "an object is not an integer", "data": {}, "valid": false }, { "description": "an array is not an integer", "data": [], "valid": false }, { "description": "a boolean is not an integer", "data": true, "valid": false }, { "description": "null is not an integer", "data": null, "valid": false } ] }, { "description": "number type matches numbers", "schema": {"type": "number"}, "tests": [ { "description": "an integer is a number", "data": 1, "valid": true }, { "description": "a float with zero fractional part is a number (and an integer)", "data": 1.0, "valid": true }, { "description": "a float is a number", "data": 1.1, "valid": true }, { "description": "a string is not a number", "data": "foo", "valid": false }, { "description": "a string is still not a number, even if it looks like one", "data": "1", "valid": false }, { "description": "an object is not a number", "data": {}, "valid": false }, { "description": "an array is not a number", "data": [], "valid": false }, { "description": "a boolean is not a number", "data": true, "valid": false }, { "description": "null is not a number", "data": null, "valid": false } ] }, { "description": "string type matches strings", "schema": {"type": "string"}, "tests": [ { "description": "1 is not a string", "data": 1, "valid": false }, { "description": "a float is not a string", "data": 1.1, "valid": false }, { "description": "a string is a string", "data": "foo", "valid": true }, { "description": "a string is still a string, even if it looks like a number", "data": "1", "valid": true }, { "description": "an empty string is still a string", "data": "", "valid": true }, { "description": "an object is not a string", "data": {}, "valid": false }, { "description": "an array is not a string", "data": [], "valid": false }, { "description": "a boolean is not a string", "data": true, "valid": false }, { "description": "null is not a string", "data": null, "valid": false } ] }, { "description": "object type matches objects", "schema": {"type": "object"}, "tests": [ { "description": "an integer is not an object", "data": 1, "valid": false }, { "description": "a float is not an object", "data": 1.1, "valid": false }, { "description": "a string is not an object", "data": "foo", "valid": false }, { "description": "an object is an object", "data": {}, "valid": true }, { "description": "an array is not an object", "data": [], "valid": false }, { "description": "a boolean is not an object", "data": true, "valid": false }, { "description": "null is not an object", "data": null, "valid": false } ] }, { "description": "array type matches arrays", "schema": {"type": "array"}, "tests": [ { "description": "an integer is not an array", "data": 1, "valid": false }, { "description": "a float is not an array", "data": 1.1, "valid": false }, { "description": "a string is not an array", "data": "foo", "valid": false }, { "description": "an object is not an array", "data": {}, "valid": false }, { "description": "an array is an array", "data": [], "valid": true }, { "description": "a boolean is not an array", "data": true, "valid": false }, { "description": "null is not an array", "data": null, "valid": false } ] }, { "description": "boolean type matches booleans", "schema": {"type": "boolean"}, "tests": [ { "description": "an integer is not a boolean", "data": 1, "valid": false }, { "description": "zero is not a boolean", "data": 0, "valid": false }, { "description": "a float is not a boolean", "data": 1.1, "valid": false }, { "description": "a string is not a boolean", "data": "foo", "valid": false }, { "description": "an empty string is not a boolean", "data": "", "valid": false }, { "description": "an object is not a boolean", "data": {}, "valid": false }, { "description": "an array is not a boolean", "data": [], "valid": false }, { "description": "true is a boolean", "data": true, "valid": true }, { "description": "false is a boolean", "data": false, "valid": true }, { "description": "null is not a boolean", "data": null, "valid": false } ] }, { "description": "null type matches only the null object", "schema": {"type": "null"}, "tests": [ { "description": "an integer is not null", "data": 1, "valid": false }, { "description": "a float is not null", "data": 1.1, "valid": false }, { "description": "zero is not null", "data": 0, "valid": false }, { "description": "a string is not null", "data": "foo", "valid": false }, { "description": "an empty string is not null", "data": "", "valid": false }, { "description": "an object is not null", "data": {}, "valid": false }, { "description": "an array is not null", "data": [], "valid": false }, { "description": "true is not null", "data": true, "valid": false }, { "description": "false is not null", "data": false, "valid": false }, { "description": "null is null", "data": null, "valid": true } ] }, { "description": "multiple types can be specified in an array", "schema": {"type": ["integer", "string"]}, "tests": [ { "description": "an integer is valid", "data": 1, "valid": true }, { "description": "a string is valid", "data": "foo", "valid": true }, { "description": "a float is invalid", "data": 1.1, "valid": false }, { "description": "an object is invalid", "data": {}, "valid": false }, { "description": "an array is invalid", "data": [], "valid": false }, { "description": "a boolean is invalid", "data": true, "valid": false }, { "description": "null is invalid", "data": null, "valid": false } ] }, { "description": "type as array with one item", "schema": { "type": ["string"] }, "tests": [ { "description": "string is valid", "data": "foo", "valid": true }, { "description": "number is invalid", "data": 123, "valid": false } ] }, { "description": "type: array or object", "schema": { "type": ["array", "object"] }, "tests": [ { "description": "array is valid", "data": [1,2,3], "valid": true }, { "description": "object is valid", "data": {"foo": 123}, "valid": true }, { "description": "number is invalid", "data": 123, "valid": false }, { "description": "string is invalid", "data": "foo", "valid": false }, { "description": "null is invalid", "data": null, "valid": false } ] }, { "description": "type: array, object or null", "schema": { "type": ["array", "object", "null"] }, "tests": [ { "description": "array is valid", "data": [1,2,3], "valid": true }, { "description": "object is valid", "data": {"foo": 123}, "valid": true }, { "description": "null is valid", "data": null, "valid": true }, { "description": "number is invalid", "data": 123, "valid": false }, { "description": "string is invalid", "data": "foo", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/uniqueItems.json000066400000000000000000000333021477700171100301760ustar00rootroot00000000000000[ { "description": "uniqueItems validation", "schema": {"uniqueItems": true}, "tests": [ { "description": "unique array of integers is valid", "data": [1, 2], "valid": true }, { "description": "non-unique array of integers is invalid", "data": [1, 1], "valid": false }, { "description": "non-unique array of more than two integers is invalid", "data": [1, 2, 1], "valid": false }, { "description": "numbers are unique if mathematically unequal", "data": [1.0, 1.00, 1], "valid": false }, { "description": "false is not equal to zero", "data": [0, false], "valid": true }, { "description": "true is not equal to one", "data": [1, true], "valid": true }, { "description": "unique array of strings is valid", "data": ["foo", "bar", "baz"], "valid": true }, { "description": "non-unique array of strings is invalid", "data": ["foo", "bar", "foo"], "valid": false }, { "description": "unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "baz"}], "valid": true }, { "description": "non-unique array of objects is invalid", "data": [{"foo": "bar"}, {"foo": "bar"}], "valid": false }, { "description": "property order of array of objects is ignored", "data": [{"foo": "bar", "bar": "foo"}, {"bar": "foo", "foo": "bar"}], "valid": false }, { "description": "unique array of nested objects is valid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : false}}} ], "valid": true }, { "description": "non-unique array of nested objects is invalid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : true}}} ], "valid": false }, { "description": "unique array of arrays is valid", "data": [["foo"], ["bar"]], "valid": true }, { "description": "non-unique array of arrays is invalid", "data": [["foo"], ["foo"]], "valid": false }, { "description": "non-unique array of more than two arrays is invalid", "data": [["foo"], ["bar"], ["foo"]], "valid": false }, { "description": "1 and true are unique", "data": [1, true], "valid": true }, { "description": "0 and false are unique", "data": [0, false], "valid": true }, { "description": "[1] and [true] are unique", "data": [[1], [true]], "valid": true }, { "description": "[0] and [false] are unique", "data": [[0], [false]], "valid": true }, { "description": "nested [1] and [true] are unique", "data": [[[1], "foo"], [[true], "foo"]], "valid": true }, { "description": "nested [0] and [false] are unique", "data": [[[0], "foo"], [[false], "foo"]], "valid": true }, { "description": "unique heterogeneous types are valid", "data": [{}, [1], true, null, 1, "{}"], "valid": true }, { "description": "non-unique heterogeneous types are invalid", "data": [{}, [1], true, null, {}, 1], "valid": false }, { "description": "different objects are unique", "data": [{"a": 1, "b": 2}, {"a": 2, "b": 1}], "valid": true }, { "description": "objects are non-unique despite key order", "data": [{"a": 1, "b": 2}, {"b": 2, "a": 1}], "valid": false }, { "description": "{\"a\": false} and {\"a\": 0} are unique", "data": [{"a": false}, {"a": 0}], "valid": true }, { "description": "{\"a\": true} and {\"a\": 1} are unique", "data": [{"a": true}, {"a": 1}], "valid": true } ] }, { "description": "uniqueItems with an array of items", "schema": { "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": true }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is not valid", "data": [false, false], "valid": false }, { "description": "[true, true] from items array is not valid", "data": [true, true], "valid": false }, { "description": "unique array extended from [false, true] is valid", "data": [false, true, "foo", "bar"], "valid": true }, { "description": "unique array extended from [true, false] is valid", "data": [true, false, "foo", "bar"], "valid": true }, { "description": "non-unique array extended from [false, true] is not valid", "data": [false, true, "foo", "foo"], "valid": false }, { "description": "non-unique array extended from [true, false] is not valid", "data": [true, false, "foo", "foo"], "valid": false } ] }, { "description": "uniqueItems with an array of items and additionalItems=false", "schema": { "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": true, "additionalItems": false }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is not valid", "data": [false, false], "valid": false }, { "description": "[true, true] from items array is not valid", "data": [true, true], "valid": false }, { "description": "extra items are invalid even if unique", "data": [false, true, null], "valid": false } ] }, { "description": "uniqueItems=false validation", "schema": { "uniqueItems": false }, "tests": [ { "description": "unique array of integers is valid", "data": [1, 2], "valid": true }, { "description": "non-unique array of integers is valid", "data": [1, 1], "valid": true }, { "description": "numbers are unique if mathematically unequal", "data": [1.0, 1.00, 1], "valid": true }, { "description": "false is not equal to zero", "data": [0, false], "valid": true }, { "description": "true is not equal to one", "data": [1, true], "valid": true }, { "description": "unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "baz"}], "valid": true }, { "description": "non-unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "bar"}], "valid": true }, { "description": "unique array of nested objects is valid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : false}}} ], "valid": true }, { "description": "non-unique array of nested objects is valid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : true}}} ], "valid": true }, { "description": "unique array of arrays is valid", "data": [["foo"], ["bar"]], "valid": true }, { "description": "non-unique array of arrays is valid", "data": [["foo"], ["foo"]], "valid": true }, { "description": "1 and true are unique", "data": [1, true], "valid": true }, { "description": "0 and false are unique", "data": [0, false], "valid": true }, { "description": "unique heterogeneous types are valid", "data": [{}, [1], true, null, 1], "valid": true }, { "description": "non-unique heterogeneous types are valid", "data": [{}, [1], true, null, {}, 1], "valid": true } ] }, { "description": "uniqueItems=false with an array of items", "schema": { "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": false }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is valid", "data": [false, false], "valid": true }, { "description": "[true, true] from items array is valid", "data": [true, true], "valid": true }, { "description": "unique array extended from [false, true] is valid", "data": [false, true, "foo", "bar"], "valid": true }, { "description": "unique array extended from [true, false] is valid", "data": [true, false, "foo", "bar"], "valid": true }, { "description": "non-unique array extended from [false, true] is valid", "data": [false, true, "foo", "foo"], "valid": true }, { "description": "non-unique array extended from [true, false] is valid", "data": [true, false, "foo", "foo"], "valid": true } ] }, { "description": "uniqueItems=false with an array of items and additionalItems=false", "schema": { "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": false, "additionalItems": false }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is valid", "data": [false, false], "valid": true }, { "description": "[true, true] from items array is valid", "data": [true, true], "valid": true }, { "description": "extra items are invalid even if unique", "data": [false, true, null], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft6/unknownKeyword.json000066400000000000000000000037421477700171100307370ustar00rootroot00000000000000[ { "description": "$id inside an unknown keyword is not a real identifier", "comment": "the implementation must not be confused by an $id in locations we do not know how to parse", "schema": { "definitions": { "id_in_unknown0": { "not": { "array_of_schemas": [ { "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", "type": "null" } ] } }, "real_id_in_schema": { "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", "type": "string" }, "id_in_unknown1": { "not": { "object_of_schemas": { "foo": { "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", "type": "integer" } } } } }, "anyOf": [ { "$ref": "#/definitions/id_in_unknown0" }, { "$ref": "#/definitions/id_in_unknown1" }, { "$ref": "https://localhost:1234/unknownKeyword/my_identifier.json" } ] }, "tests": [ { "description": "type matches second anyOf, which has a real schema in it", "data": "a string", "valid": true }, { "description": "type matches non-schema in first anyOf", "data": null, "valid": false }, { "description": "type matches non-schema in third anyOf", "data": 1, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/000077500000000000000000000000001477700171100247735ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/additionalItems.json000066400000000000000000000133511477700171100310030ustar00rootroot00000000000000[ { "description": "additionalItems as schema", "schema": { "items": [{}], "additionalItems": {"type": "integer"} }, "tests": [ { "description": "additional items match schema", "data": [ null, 2, 3, 4 ], "valid": true }, { "description": "additional items do not match schema", "data": [ null, 2, 3, "foo" ], "valid": false } ] }, { "description": "when items is schema, additionalItems does nothing", "schema": { "items": { "type": "integer" }, "additionalItems": { "type": "string" } }, "tests": [ { "description": "valid with a array of type integers", "data": [1,2,3], "valid": true }, { "description": "invalid with a array of mixed types", "data": [1,"2","3"], "valid": false } ] }, { "description": "when items is schema, boolean additionalItems does nothing", "schema": { "items": {}, "additionalItems": false }, "tests": [ { "description": "all items match schema", "data": [ 1, 2, 3, 4, 5 ], "valid": true } ] }, { "description": "array of items with no additionalItems permitted", "schema": { "items": [{}, {}, {}], "additionalItems": false }, "tests": [ { "description": "empty array", "data": [ ], "valid": true }, { "description": "fewer number of items present (1)", "data": [ 1 ], "valid": true }, { "description": "fewer number of items present (2)", "data": [ 1, 2 ], "valid": true }, { "description": "equal number of items present", "data": [ 1, 2, 3 ], "valid": true }, { "description": "additional items are not permitted", "data": [ 1, 2, 3, 4 ], "valid": false } ] }, { "description": "additionalItems as false without items", "schema": {"additionalItems": false}, "tests": [ { "description": "items defaults to empty schema so everything is valid", "data": [ 1, 2, 3, 4, 5 ], "valid": true }, { "description": "ignores non-arrays", "data": {"foo" : "bar"}, "valid": true } ] }, { "description": "additionalItems are allowed by default", "schema": {"items": [{"type": "integer"}]}, "tests": [ { "description": "only the first item is validated", "data": [1, "foo", false], "valid": true } ] }, { "description": "additionalItems does not look in applicators, valid case", "schema": { "allOf": [ { "items": [ { "type": "integer" } ] } ], "additionalItems": { "type": "boolean" } }, "tests": [ { "description": "items defined in allOf are not examined", "data": [ 1, null ], "valid": true } ] }, { "description": "additionalItems does not look in applicators, invalid case", "schema": { "allOf": [ { "items": [ { "type": "integer" }, { "type": "string" } ] } ], "items": [ {"type": "integer" } ], "additionalItems": { "type": "boolean" } }, "tests": [ { "description": "items defined in allOf are not examined", "data": [ 1, "hello" ], "valid": false } ] }, { "description": "items validation adjusts the starting index for additionalItems", "schema": { "items": [ { "type": "string" } ], "additionalItems": { "type": "integer" } }, "tests": [ { "description": "valid items", "data": [ "x", 2, 3 ], "valid": true }, { "description": "wrong type of second item", "data": [ "x", "y" ], "valid": false } ] }, { "description": "additionalItems with heterogeneous array", "schema": { "items": [{}], "additionalItems": false }, "tests": [ { "description": "heterogeneous invalid instance", "data": [ "foo", "bar", 37 ], "valid": false }, { "description": "valid instance", "data": [ null ], "valid": true } ] }, { "description": "additionalItems with null instance elements", "schema": { "additionalItems": { "type": "null" } }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/additionalProperties.json000066400000000000000000000105121477700171100320520ustar00rootroot00000000000000[ { "description": "additionalProperties being false does not allow other properties", "schema": { "properties": {"foo": {}, "bar": {}}, "patternProperties": { "^v": {} }, "additionalProperties": false }, "tests": [ { "description": "no additional properties is valid", "data": {"foo": 1}, "valid": true }, { "description": "an additional property is invalid", "data": {"foo" : 1, "bar" : 2, "quux" : "boom"}, "valid": false }, { "description": "ignores arrays", "data": [1, 2, 3], "valid": true }, { "description": "ignores strings", "data": "foobarbaz", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true }, { "description": "patternProperties are not additional properties", "data": {"foo":1, "vroom": 2}, "valid": true } ] }, { "description": "non-ASCII pattern with additionalProperties", "schema": { "patternProperties": {"^á": {}}, "additionalProperties": false }, "tests": [ { "description": "matching the pattern is valid", "data": {"ármányos": 2}, "valid": true }, { "description": "not matching the pattern is invalid", "data": {"élmény": 2}, "valid": false } ] }, { "description": "additionalProperties with schema", "schema": { "properties": {"foo": {}, "bar": {}}, "additionalProperties": {"type": "boolean"} }, "tests": [ { "description": "no additional properties is valid", "data": {"foo": 1}, "valid": true }, { "description": "an additional valid property is valid", "data": {"foo" : 1, "bar" : 2, "quux" : true}, "valid": true }, { "description": "an additional invalid property is invalid", "data": {"foo" : 1, "bar" : 2, "quux" : 12}, "valid": false } ] }, { "description": "additionalProperties can exist by itself", "schema": { "additionalProperties": {"type": "boolean"} }, "tests": [ { "description": "an additional valid property is valid", "data": {"foo" : true}, "valid": true }, { "description": "an additional invalid property is invalid", "data": {"foo" : 1}, "valid": false } ] }, { "description": "additionalProperties are allowed by default", "schema": {"properties": {"foo": {}, "bar": {}}}, "tests": [ { "description": "additional properties are allowed", "data": {"foo": 1, "bar": 2, "quux": true}, "valid": true } ] }, { "description": "additionalProperties does not look in applicators", "schema": { "allOf": [ {"properties": {"foo": {}}} ], "additionalProperties": {"type": "boolean"} }, "tests": [ { "description": "properties defined in allOf are not examined", "data": {"foo": 1, "bar": true}, "valid": false } ] }, { "description": "additionalProperties with null valued instance properties", "schema": { "additionalProperties": { "type": "null" } }, "tests": [ { "description": "allows null values", "data": {"foo": null}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/allOf.json000066400000000000000000000171471477700171100267350ustar00rootroot00000000000000[ { "description": "allOf", "schema": { "allOf": [ { "properties": { "bar": {"type": "integer"} }, "required": ["bar"] }, { "properties": { "foo": {"type": "string"} }, "required": ["foo"] } ] }, "tests": [ { "description": "allOf", "data": {"foo": "baz", "bar": 2}, "valid": true }, { "description": "mismatch second", "data": {"foo": "baz"}, "valid": false }, { "description": "mismatch first", "data": {"bar": 2}, "valid": false }, { "description": "wrong type", "data": {"foo": "baz", "bar": "quux"}, "valid": false } ] }, { "description": "allOf with base schema", "schema": { "properties": {"bar": {"type": "integer"}}, "required": ["bar"], "allOf" : [ { "properties": { "foo": {"type": "string"} }, "required": ["foo"] }, { "properties": { "baz": {"type": "null"} }, "required": ["baz"] } ] }, "tests": [ { "description": "valid", "data": {"foo": "quux", "bar": 2, "baz": null}, "valid": true }, { "description": "mismatch base schema", "data": {"foo": "quux", "baz": null}, "valid": false }, { "description": "mismatch first allOf", "data": {"bar": 2, "baz": null}, "valid": false }, { "description": "mismatch second allOf", "data": {"foo": "quux", "bar": 2}, "valid": false }, { "description": "mismatch both", "data": {"bar": 2}, "valid": false } ] }, { "description": "allOf simple types", "schema": { "allOf": [ {"maximum": 30}, {"minimum": 20} ] }, "tests": [ { "description": "valid", "data": 25, "valid": true }, { "description": "mismatch one", "data": 35, "valid": false } ] }, { "description": "allOf with boolean schemas, all true", "schema": {"allOf": [true, true]}, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "allOf with boolean schemas, some false", "schema": {"allOf": [true, false]}, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "allOf with boolean schemas, all false", "schema": {"allOf": [false, false]}, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "allOf with one empty schema", "schema": { "allOf": [ {} ] }, "tests": [ { "description": "any data is valid", "data": 1, "valid": true } ] }, { "description": "allOf with two empty schemas", "schema": { "allOf": [ {}, {} ] }, "tests": [ { "description": "any data is valid", "data": 1, "valid": true } ] }, { "description": "allOf with the first empty schema", "schema": { "allOf": [ {}, { "type": "number" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "string is invalid", "data": "foo", "valid": false } ] }, { "description": "allOf with the last empty schema", "schema": { "allOf": [ { "type": "number" }, {} ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "string is invalid", "data": "foo", "valid": false } ] }, { "description": "nested allOf, to check validation semantics", "schema": { "allOf": [ { "allOf": [ { "type": "null" } ] } ] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "anything non-null is invalid", "data": 123, "valid": false } ] }, { "description": "allOf combined with anyOf, oneOf", "schema": { "allOf": [ { "multipleOf": 2 } ], "anyOf": [ { "multipleOf": 3 } ], "oneOf": [ { "multipleOf": 5 } ] }, "tests": [ { "description": "allOf: false, anyOf: false, oneOf: false", "data": 1, "valid": false }, { "description": "allOf: false, anyOf: false, oneOf: true", "data": 5, "valid": false }, { "description": "allOf: false, anyOf: true, oneOf: false", "data": 3, "valid": false }, { "description": "allOf: false, anyOf: true, oneOf: true", "data": 15, "valid": false }, { "description": "allOf: true, anyOf: false, oneOf: false", "data": 2, "valid": false }, { "description": "allOf: true, anyOf: false, oneOf: true", "data": 10, "valid": false }, { "description": "allOf: true, anyOf: true, oneOf: false", "data": 6, "valid": false }, { "description": "allOf: true, anyOf: true, oneOf: true", "data": 30, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/anyOf.json000066400000000000000000000113331477700171100267430ustar00rootroot00000000000000[ { "description": "anyOf", "schema": { "anyOf": [ { "type": "integer" }, { "minimum": 2 } ] }, "tests": [ { "description": "first anyOf valid", "data": 1, "valid": true }, { "description": "second anyOf valid", "data": 2.5, "valid": true }, { "description": "both anyOf valid", "data": 3, "valid": true }, { "description": "neither anyOf valid", "data": 1.5, "valid": false } ] }, { "description": "anyOf with base schema", "schema": { "type": "string", "anyOf" : [ { "maxLength": 2 }, { "minLength": 4 } ] }, "tests": [ { "description": "mismatch base schema", "data": 3, "valid": false }, { "description": "one anyOf valid", "data": "foobar", "valid": true }, { "description": "both anyOf invalid", "data": "foo", "valid": false } ] }, { "description": "anyOf with boolean schemas, all true", "schema": {"anyOf": [true, true]}, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "anyOf with boolean schemas, some true", "schema": {"anyOf": [true, false]}, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "anyOf with boolean schemas, all false", "schema": {"anyOf": [false, false]}, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "anyOf complex types", "schema": { "anyOf": [ { "properties": { "bar": {"type": "integer"} }, "required": ["bar"] }, { "properties": { "foo": {"type": "string"} }, "required": ["foo"] } ] }, "tests": [ { "description": "first anyOf valid (complex)", "data": {"bar": 2}, "valid": true }, { "description": "second anyOf valid (complex)", "data": {"foo": "baz"}, "valid": true }, { "description": "both anyOf valid (complex)", "data": {"foo": "baz", "bar": 2}, "valid": true }, { "description": "neither anyOf valid (complex)", "data": {"foo": 2, "bar": "quux"}, "valid": false } ] }, { "description": "anyOf with one empty schema", "schema": { "anyOf": [ { "type": "number" }, {} ] }, "tests": [ { "description": "string is valid", "data": "foo", "valid": true }, { "description": "number is valid", "data": 123, "valid": true } ] }, { "description": "nested anyOf, to check validation semantics", "schema": { "anyOf": [ { "anyOf": [ { "type": "null" } ] } ] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "anything non-null is invalid", "data": 123, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/boolean_schema.json000066400000000000000000000054021477700171100306260ustar00rootroot00000000000000[ { "description": "boolean schema 'true'", "schema": true, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "string is valid", "data": "foo", "valid": true }, { "description": "boolean true is valid", "data": true, "valid": true }, { "description": "boolean false is valid", "data": false, "valid": true }, { "description": "null is valid", "data": null, "valid": true }, { "description": "object is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "empty object is valid", "data": {}, "valid": true }, { "description": "array is valid", "data": ["foo"], "valid": true }, { "description": "empty array is valid", "data": [], "valid": true } ] }, { "description": "boolean schema 'false'", "schema": false, "tests": [ { "description": "number is invalid", "data": 1, "valid": false }, { "description": "string is invalid", "data": "foo", "valid": false }, { "description": "boolean true is invalid", "data": true, "valid": false }, { "description": "boolean false is invalid", "data": false, "valid": false }, { "description": "null is invalid", "data": null, "valid": false }, { "description": "object is invalid", "data": {"foo": "bar"}, "valid": false }, { "description": "empty object is invalid", "data": {}, "valid": false }, { "description": "array is invalid", "data": ["foo"], "valid": false }, { "description": "empty array is invalid", "data": [], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/const.json000066400000000000000000000225641477700171100270250ustar00rootroot00000000000000[ { "description": "const validation", "schema": {"const": 2}, "tests": [ { "description": "same value is valid", "data": 2, "valid": true }, { "description": "another value is invalid", "data": 5, "valid": false }, { "description": "another type is invalid", "data": "a", "valid": false } ] }, { "description": "const with object", "schema": {"const": {"foo": "bar", "baz": "bax"}}, "tests": [ { "description": "same object is valid", "data": {"foo": "bar", "baz": "bax"}, "valid": true }, { "description": "same object with different property order is valid", "data": {"baz": "bax", "foo": "bar"}, "valid": true }, { "description": "another object is invalid", "data": {"foo": "bar"}, "valid": false }, { "description": "another type is invalid", "data": [1, 2], "valid": false } ] }, { "description": "const with array", "schema": {"const": [{ "foo": "bar" }]}, "tests": [ { "description": "same array is valid", "data": [{"foo": "bar"}], "valid": true }, { "description": "another array item is invalid", "data": [2], "valid": false }, { "description": "array with additional items is invalid", "data": [1, 2, 3], "valid": false } ] }, { "description": "const with null", "schema": {"const": null}, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "not null is invalid", "data": 0, "valid": false } ] }, { "description": "const with false does not match 0", "schema": {"const": false}, "tests": [ { "description": "false is valid", "data": false, "valid": true }, { "description": "integer zero is invalid", "data": 0, "valid": false }, { "description": "float zero is invalid", "data": 0.0, "valid": false } ] }, { "description": "const with true does not match 1", "schema": {"const": true}, "tests": [ { "description": "true is valid", "data": true, "valid": true }, { "description": "integer one is invalid", "data": 1, "valid": false }, { "description": "float one is invalid", "data": 1.0, "valid": false } ] }, { "description": "const with [false] does not match [0]", "schema": {"const": [false]}, "tests": [ { "description": "[false] is valid", "data": [false], "valid": true }, { "description": "[0] is invalid", "data": [0], "valid": false }, { "description": "[0.0] is invalid", "data": [0.0], "valid": false } ] }, { "description": "const with [true] does not match [1]", "schema": {"const": [true]}, "tests": [ { "description": "[true] is valid", "data": [true], "valid": true }, { "description": "[1] is invalid", "data": [1], "valid": false }, { "description": "[1.0] is invalid", "data": [1.0], "valid": false } ] }, { "description": "const with {\"a\": false} does not match {\"a\": 0}", "schema": {"const": {"a": false}}, "tests": [ { "description": "{\"a\": false} is valid", "data": {"a": false}, "valid": true }, { "description": "{\"a\": 0} is invalid", "data": {"a": 0}, "valid": false }, { "description": "{\"a\": 0.0} is invalid", "data": {"a": 0.0}, "valid": false } ] }, { "description": "const with {\"a\": true} does not match {\"a\": 1}", "schema": {"const": {"a": true}}, "tests": [ { "description": "{\"a\": true} is valid", "data": {"a": true}, "valid": true }, { "description": "{\"a\": 1} is invalid", "data": {"a": 1}, "valid": false }, { "description": "{\"a\": 1.0} is invalid", "data": {"a": 1.0}, "valid": false } ] }, { "description": "const with 0 does not match other zero-like types", "schema": {"const": 0}, "tests": [ { "description": "false is invalid", "data": false, "valid": false }, { "description": "integer zero is valid", "data": 0, "valid": true }, { "description": "float zero is valid", "data": 0.0, "valid": true }, { "description": "empty object is invalid", "data": {}, "valid": false }, { "description": "empty array is invalid", "data": [], "valid": false }, { "description": "empty string is invalid", "data": "", "valid": false } ] }, { "description": "const with 1 does not match true", "schema": {"const": 1}, "tests": [ { "description": "true is invalid", "data": true, "valid": false }, { "description": "integer one is valid", "data": 1, "valid": true }, { "description": "float one is valid", "data": 1.0, "valid": true } ] }, { "description": "const with -2.0 matches integer and float types", "schema": {"const": -2.0}, "tests": [ { "description": "integer -2 is valid", "data": -2, "valid": true }, { "description": "integer 2 is invalid", "data": 2, "valid": false }, { "description": "float -2.0 is valid", "data": -2.0, "valid": true }, { "description": "float 2.0 is invalid", "data": 2.0, "valid": false }, { "description": "float -2.00001 is invalid", "data": -2.00001, "valid": false } ] }, { "description": "float and integers are equal up to 64-bit representation limits", "schema": {"const": 9007199254740992}, "tests": [ { "description": "integer is valid", "data": 9007199254740992, "valid": true }, { "description": "integer minus one is invalid", "data": 9007199254740991, "valid": false }, { "description": "float is valid", "data": 9007199254740992.0, "valid": true }, { "description": "float minus one is invalid", "data": 9007199254740991.0, "valid": false } ] }, { "description": "nul characters in strings", "schema": { "const": "hello\u0000there" }, "tests": [ { "description": "match string with nul", "data": "hello\u0000there", "valid": true }, { "description": "do not match string lacking nul", "data": "hellothere", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/contains.json000066400000000000000000000110311477700171100275000ustar00rootroot00000000000000[ { "description": "contains keyword validation", "schema": { "contains": {"minimum": 5} }, "tests": [ { "description": "array with item matching schema (5) is valid", "data": [3, 4, 5], "valid": true }, { "description": "array with item matching schema (6) is valid", "data": [3, 4, 6], "valid": true }, { "description": "array with two items matching schema (5, 6) is valid", "data": [3, 4, 5, 6], "valid": true }, { "description": "array without items matching schema is invalid", "data": [2, 3, 4], "valid": false }, { "description": "empty array is invalid", "data": [], "valid": false }, { "description": "not array is valid", "data": {}, "valid": true } ] }, { "description": "contains keyword with const keyword", "schema": { "contains": { "const": 5 } }, "tests": [ { "description": "array with item 5 is valid", "data": [3, 4, 5], "valid": true }, { "description": "array with two items 5 is valid", "data": [3, 4, 5, 5], "valid": true }, { "description": "array without item 5 is invalid", "data": [1, 2, 3, 4], "valid": false } ] }, { "description": "contains keyword with boolean schema true", "schema": {"contains": true}, "tests": [ { "description": "any non-empty array is valid", "data": ["foo"], "valid": true }, { "description": "empty array is invalid", "data": [], "valid": false } ] }, { "description": "contains keyword with boolean schema false", "schema": {"contains": false}, "tests": [ { "description": "any non-empty array is invalid", "data": ["foo"], "valid": false }, { "description": "empty array is invalid", "data": [], "valid": false }, { "description": "non-arrays are valid", "data": "contains does not apply to strings", "valid": true } ] }, { "description": "items + contains", "schema": { "items": { "multipleOf": 2 }, "contains": { "multipleOf": 3 } }, "tests": [ { "description": "matches items, does not match contains", "data": [ 2, 4, 8 ], "valid": false }, { "description": "does not match items, matches contains", "data": [ 3, 6, 9 ], "valid": false }, { "description": "matches both items and contains", "data": [ 6, 12 ], "valid": true }, { "description": "matches neither items nor contains", "data": [ 1, 5 ], "valid": false } ] }, { "description": "contains with false if subschema", "schema": { "contains": { "if": false, "else": true } }, "tests": [ { "description": "any non-empty array is valid", "data": ["foo"], "valid": true }, { "description": "empty array is invalid", "data": [], "valid": false } ] }, { "description": "contains with null instance elements", "schema": { "contains": { "type": "null" } }, "tests": [ { "description": "allows null items", "data": [ null ], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/default.json000066400000000000000000000042671477700171100273230ustar00rootroot00000000000000[ { "description": "invalid type for default", "schema": { "properties": { "foo": { "type": "integer", "default": [] } } }, "tests": [ { "description": "valid when property is specified", "data": {"foo": 13}, "valid": true }, { "description": "still valid when the invalid default is used", "data": {}, "valid": true } ] }, { "description": "invalid string value for default", "schema": { "properties": { "bar": { "type": "string", "minLength": 4, "default": "bad" } } }, "tests": [ { "description": "valid when property is specified", "data": {"bar": "good"}, "valid": true }, { "description": "still valid when the invalid default is used", "data": {}, "valid": true } ] }, { "description": "the default keyword does not do anything if the property is missing", "schema": { "type": "object", "properties": { "alpha": { "type": "number", "maximum": 3, "default": 5 } } }, "tests": [ { "description": "an explicit property value is checked against maximum (passing)", "data": { "alpha": 1 }, "valid": true }, { "description": "an explicit property value is checked against maximum (failing)", "data": { "alpha": 5 }, "valid": false }, { "description": "missing properties are not filled in with the default", "data": {}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/definitions.json000066400000000000000000000013171477700171100302030ustar00rootroot00000000000000[ { "description": "validate definition against metaschema", "schema": {"$ref": "http://json-schema.org/draft-07/schema#"}, "tests": [ { "description": "valid definition schema", "data": { "definitions": { "foo": {"type": "integer"} } }, "valid": true }, { "description": "invalid definition schema", "data": { "definitions": { "foo": {"type": 1} } }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/dependencies.json000066400000000000000000000173371477700171100303270ustar00rootroot00000000000000[ { "description": "dependencies", "schema": { "dependencies": {"bar": ["foo"]} }, "tests": [ { "description": "neither", "data": {}, "valid": true }, { "description": "nondependant", "data": {"foo": 1}, "valid": true }, { "description": "with dependency", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "missing dependency", "data": {"bar": 2}, "valid": false }, { "description": "ignores arrays", "data": ["bar"], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "dependencies with empty array", "schema": { "dependencies": {"bar": []} }, "tests": [ { "description": "empty object", "data": {}, "valid": true }, { "description": "object with one property", "data": {"bar": 2}, "valid": true }, { "description": "non-object is valid", "data": 1, "valid": true } ] }, { "description": "multiple dependencies", "schema": { "dependencies": {"quux": ["foo", "bar"]} }, "tests": [ { "description": "neither", "data": {}, "valid": true }, { "description": "nondependants", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "with dependencies", "data": {"foo": 1, "bar": 2, "quux": 3}, "valid": true }, { "description": "missing dependency", "data": {"foo": 1, "quux": 2}, "valid": false }, { "description": "missing other dependency", "data": {"bar": 1, "quux": 2}, "valid": false }, { "description": "missing both dependencies", "data": {"quux": 1}, "valid": false } ] }, { "description": "multiple dependencies subschema", "schema": { "dependencies": { "bar": { "properties": { "foo": {"type": "integer"}, "bar": {"type": "integer"} } } } }, "tests": [ { "description": "valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "no dependency", "data": {"foo": "quux"}, "valid": true }, { "description": "wrong type", "data": {"foo": "quux", "bar": 2}, "valid": false }, { "description": "wrong type other", "data": {"foo": 2, "bar": "quux"}, "valid": false }, { "description": "wrong type both", "data": {"foo": "quux", "bar": "quux"}, "valid": false } ] }, { "description": "dependencies with boolean subschemas", "schema": { "dependencies": { "foo": true, "bar": false } }, "tests": [ { "description": "object with property having schema true is valid", "data": {"foo": 1}, "valid": true }, { "description": "object with property having schema false is invalid", "data": {"bar": 2}, "valid": false }, { "description": "object with both properties is invalid", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "empty object is valid", "data": {}, "valid": true } ] }, { "description": "dependencies with escaped characters", "schema": { "dependencies": { "foo\nbar": ["foo\rbar"], "foo\tbar": { "minProperties": 4 }, "foo'bar": {"required": ["foo\"bar"]}, "foo\"bar": ["foo'bar"] } }, "tests": [ { "description": "valid object 1", "data": { "foo\nbar": 1, "foo\rbar": 2 }, "valid": true }, { "description": "valid object 2", "data": { "foo\tbar": 1, "a": 2, "b": 3, "c": 4 }, "valid": true }, { "description": "valid object 3", "data": { "foo'bar": 1, "foo\"bar": 2 }, "valid": true }, { "description": "invalid object 1", "data": { "foo\nbar": 1, "foo": 2 }, "valid": false }, { "description": "invalid object 2", "data": { "foo\tbar": 1, "a": 2 }, "valid": false }, { "description": "invalid object 3", "data": { "foo'bar": 1 }, "valid": false }, { "description": "invalid object 4", "data": { "foo\"bar": 2 }, "valid": false } ] }, { "description": "dependent subschema incompatible with root", "schema": { "properties": { "foo": {} }, "dependencies": { "foo": { "properties": { "bar": {} }, "additionalProperties": false } } }, "tests": [ { "description": "matches root", "data": {"foo": 1}, "valid": false }, { "description": "matches dependency", "data": {"bar": 1}, "valid": true }, { "description": "matches both", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "no dependency", "data": {"baz": 1}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/enum.json000066400000000000000000000146431477700171100266420ustar00rootroot00000000000000[ { "description": "simple enum validation", "schema": {"enum": [1, 2, 3]}, "tests": [ { "description": "one of the enum is valid", "data": 1, "valid": true }, { "description": "something else is invalid", "data": 4, "valid": false } ] }, { "description": "heterogeneous enum validation", "schema": {"enum": [6, "foo", [], true, {"foo": 12}]}, "tests": [ { "description": "one of the enum is valid", "data": [], "valid": true }, { "description": "something else is invalid", "data": null, "valid": false }, { "description": "objects are deep compared", "data": {"foo": false}, "valid": false }, { "description": "valid object matches", "data": {"foo": 12}, "valid": true }, { "description": "extra properties in object is invalid", "data": {"foo": 12, "boo": 42}, "valid": false } ] }, { "description": "heterogeneous enum-with-null validation", "schema": { "enum": [6, null] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "number is valid", "data": 6, "valid": true }, { "description": "something else is invalid", "data": "test", "valid": false } ] }, { "description": "enums in properties", "schema": { "type":"object", "properties": { "foo": {"enum":["foo"]}, "bar": {"enum":["bar"]} }, "required": ["bar"] }, "tests": [ { "description": "both properties are valid", "data": {"foo":"foo", "bar":"bar"}, "valid": true }, { "description": "wrong foo value", "data": {"foo":"foot", "bar":"bar"}, "valid": false }, { "description": "wrong bar value", "data": {"foo":"foo", "bar":"bart"}, "valid": false }, { "description": "missing optional property is valid", "data": {"bar":"bar"}, "valid": true }, { "description": "missing required property is invalid", "data": {"foo":"foo"}, "valid": false }, { "description": "missing all properties is invalid", "data": {}, "valid": false } ] }, { "description": "enum with escaped characters", "schema": { "enum": ["foo\nbar", "foo\rbar"] }, "tests": [ { "description": "member 1 is valid", "data": "foo\nbar", "valid": true }, { "description": "member 2 is valid", "data": "foo\rbar", "valid": true }, { "description": "another string is invalid", "data": "abc", "valid": false } ] }, { "description": "enum with false does not match 0", "schema": {"enum": [false]}, "tests": [ { "description": "false is valid", "data": false, "valid": true }, { "description": "integer zero is invalid", "data": 0, "valid": false }, { "description": "float zero is invalid", "data": 0.0, "valid": false } ] }, { "description": "enum with true does not match 1", "schema": {"enum": [true]}, "tests": [ { "description": "true is valid", "data": true, "valid": true }, { "description": "integer one is invalid", "data": 1, "valid": false }, { "description": "float one is invalid", "data": 1.0, "valid": false } ] }, { "description": "enum with 0 does not match false", "schema": {"enum": [0]}, "tests": [ { "description": "false is invalid", "data": false, "valid": false }, { "description": "integer zero is valid", "data": 0, "valid": true }, { "description": "float zero is valid", "data": 0.0, "valid": true } ] }, { "description": "enum with 1 does not match true", "schema": {"enum": [1]}, "tests": [ { "description": "true is invalid", "data": true, "valid": false }, { "description": "integer one is valid", "data": 1, "valid": true }, { "description": "float one is valid", "data": 1.0, "valid": true } ] }, { "description": "nul characters in strings", "schema": { "enum": [ "hello\u0000there" ] }, "tests": [ { "description": "match string with nul", "data": "hello\u0000there", "valid": true }, { "description": "do not match string lacking nul", "data": "hellothere", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/exclusiveMaximum.json000066400000000000000000000014071477700171100312350ustar00rootroot00000000000000[ { "description": "exclusiveMaximum validation", "schema": { "exclusiveMaximum": 3.0 }, "tests": [ { "description": "below the exclusiveMaximum is valid", "data": 2.2, "valid": true }, { "description": "boundary point is invalid", "data": 3.0, "valid": false }, { "description": "above the exclusiveMaximum is invalid", "data": 3.5, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/exclusiveMinimum.json000066400000000000000000000014071477700171100312330ustar00rootroot00000000000000[ { "description": "exclusiveMinimum validation", "schema": { "exclusiveMinimum": 1.1 }, "tests": [ { "description": "above the exclusiveMinimum is valid", "data": 1.2, "valid": true }, { "description": "boundary point is invalid", "data": 1.1, "valid": false }, { "description": "below the exclusiveMinimum is invalid", "data": 0.6, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/format.json000066400000000000000000000432231477700171100271620ustar00rootroot00000000000000[ { "description": "email format", "schema": { "format": "email" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "idn-email format", "schema": { "format": "idn-email" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "regex format", "schema": { "format": "regex" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "ipv4 format", "schema": { "format": "ipv4" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "ipv6 format", "schema": { "format": "ipv6" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "idn-hostname format", "schema": { "format": "idn-hostname" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "hostname format", "schema": { "format": "hostname" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "date format", "schema": { "format": "date" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "date-time format", "schema": { "format": "date-time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "time format", "schema": { "format": "time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "json-pointer format", "schema": { "format": "json-pointer" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "relative-json-pointer format", "schema": { "format": "relative-json-pointer" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "iri format", "schema": { "format": "iri" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "iri-reference format", "schema": { "format": "iri-reference" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "uri format", "schema": { "format": "uri" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "uri-reference format", "schema": { "format": "uri-reference" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { "description": "uri-template format", "schema": { "format": "uri-template" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/id.json000066400000000000000000000067121477700171100262700ustar00rootroot00000000000000[ { "description": "id inside an enum is not a real identifier", "comment": "the implementation must not be confused by an id buried in the enum", "schema": { "definitions": { "id_in_enum": { "enum": [ { "$id": "https://localhost:1234/id/my_identifier.json", "type": "null" } ] }, "real_id_in_schema": { "$id": "https://localhost:1234/id/my_identifier.json", "type": "string" }, "zzz_id_in_const": { "const": { "$id": "https://localhost:1234/id/my_identifier.json", "type": "null" } } }, "anyOf": [ { "$ref": "#/definitions/id_in_enum" }, { "$ref": "https://localhost:1234/id/my_identifier.json" } ] }, "tests": [ { "description": "exact match to enum, and type matches", "data": { "$id": "https://localhost:1234/id/my_identifier.json", "type": "null" }, "valid": true }, { "description": "match $ref to id", "data": "a string to match #/definitions/id_in_enum", "valid": true }, { "description": "no match on enum or $ref to id", "data": 1, "valid": false } ] }, { "description": "non-schema object containing a plain-name $id property", "schema": { "definitions": { "const_not_anchor": { "const": { "$id": "#not_a_real_anchor" } } }, "if": { "const": "skip not_a_real_anchor" }, "then": true, "else" : { "$ref": "#/definitions/const_not_anchor" } }, "tests": [ { "description": "skip traversing definition for a valid result", "data": "skip not_a_real_anchor", "valid": true }, { "description": "const at const_not_anchor does not match", "data": 1, "valid": false } ] }, { "description": "non-schema object containing an $id property", "schema": { "definitions": { "const_not_id": { "const": { "$id": "not_a_real_id" } } }, "if": { "const": "skip not_a_real_id" }, "then": true, "else" : { "$ref": "#/definitions/const_not_id" } }, "tests": [ { "description": "skip traversing definition for a valid result", "data": "skip not_a_real_id", "valid": true }, { "description": "const at const_not_id does not match", "data": 1, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/if-then-else.json000066400000000000000000000153221477700171100301510ustar00rootroot00000000000000[ { "description": "ignore if without then or else", "schema": { "if": { "const": 0 } }, "tests": [ { "description": "valid when valid against lone if", "data": 0, "valid": true }, { "description": "valid when invalid against lone if", "data": "hello", "valid": true } ] }, { "description": "ignore then without if", "schema": { "then": { "const": 0 } }, "tests": [ { "description": "valid when valid against lone then", "data": 0, "valid": true }, { "description": "valid when invalid against lone then", "data": "hello", "valid": true } ] }, { "description": "ignore else without if", "schema": { "else": { "const": 0 } }, "tests": [ { "description": "valid when valid against lone else", "data": 0, "valid": true }, { "description": "valid when invalid against lone else", "data": "hello", "valid": true } ] }, { "description": "if and then without else", "schema": { "if": { "exclusiveMaximum": 0 }, "then": { "minimum": -10 } }, "tests": [ { "description": "valid through then", "data": -1, "valid": true }, { "description": "invalid through then", "data": -100, "valid": false }, { "description": "valid when if test fails", "data": 3, "valid": true } ] }, { "description": "if and else without then", "schema": { "if": { "exclusiveMaximum": 0 }, "else": { "multipleOf": 2 } }, "tests": [ { "description": "valid when if test passes", "data": -1, "valid": true }, { "description": "valid through else", "data": 4, "valid": true }, { "description": "invalid through else", "data": 3, "valid": false } ] }, { "description": "validate against correct branch, then vs else", "schema": { "if": { "exclusiveMaximum": 0 }, "then": { "minimum": -10 }, "else": { "multipleOf": 2 } }, "tests": [ { "description": "valid through then", "data": -1, "valid": true }, { "description": "invalid through then", "data": -100, "valid": false }, { "description": "valid through else", "data": 4, "valid": true }, { "description": "invalid through else", "data": 3, "valid": false } ] }, { "description": "non-interference across combined schemas", "schema": { "allOf": [ { "if": { "exclusiveMaximum": 0 } }, { "then": { "minimum": -10 } }, { "else": { "multipleOf": 2 } } ] }, "tests": [ { "description": "valid, but would have been invalid through then", "data": -100, "valid": true }, { "description": "valid, but would have been invalid through else", "data": 3, "valid": true } ] }, { "description": "if with boolean schema true", "schema": { "if": true, "then": { "const": "then" }, "else": { "const": "else" } }, "tests": [ { "description": "boolean schema true in if always chooses the then path (valid)", "data": "then", "valid": true }, { "description": "boolean schema true in if always chooses the then path (invalid)", "data": "else", "valid": false } ] }, { "description": "if with boolean schema false", "schema": { "if": false, "then": { "const": "then" }, "else": { "const": "else" } }, "tests": [ { "description": "boolean schema false in if always chooses the else path (invalid)", "data": "then", "valid": false }, { "description": "boolean schema false in if always chooses the else path (valid)", "data": "else", "valid": true } ] }, { "description": "if appears at the end when serialized (keyword processing sequence)", "schema": { "then": { "const": "yes" }, "else": { "const": "other" }, "if": { "maxLength": 4 } }, "tests": [ { "description": "yes redirects to then and passes", "data": "yes", "valid": true }, { "description": "other redirects to else and passes", "data": "other", "valid": true }, { "description": "no redirects to then and fails", "data": "no", "valid": false }, { "description": "invalid redirects to else and fails", "data": "invalid", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/infinite-loop-detection.json000066400000000000000000000017461477700171100324260ustar00rootroot00000000000000[ { "description": "evaluating the same schema location against the same data location twice is not a sign of an infinite loop", "schema": { "definitions": { "int": { "type": "integer" } }, "allOf": [ { "properties": { "foo": { "$ref": "#/definitions/int" } } }, { "additionalProperties": { "$ref": "#/definitions/int" } } ] }, "tests": [ { "description": "passing case", "data": { "foo": 1 }, "valid": true }, { "description": "failing case", "data": { "foo": "a string" }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/items.json000066400000000000000000000176141477700171100270200ustar00rootroot00000000000000[ { "description": "a schema given for items", "schema": { "items": {"type": "integer"} }, "tests": [ { "description": "valid items", "data": [ 1, 2, 3 ], "valid": true }, { "description": "wrong type of items", "data": [1, "x"], "valid": false }, { "description": "ignores non-arrays", "data": {"foo" : "bar"}, "valid": true }, { "description": "JavaScript pseudo-array is valid", "data": { "0": "invalid", "length": 1 }, "valid": true } ] }, { "description": "an array of schemas for items", "schema": { "items": [ {"type": "integer"}, {"type": "string"} ] }, "tests": [ { "description": "correct types", "data": [ 1, "foo" ], "valid": true }, { "description": "wrong types", "data": [ "foo", 1 ], "valid": false }, { "description": "incomplete array of items", "data": [ 1 ], "valid": true }, { "description": "array with additional items", "data": [ 1, "foo", true ], "valid": true }, { "description": "empty array", "data": [ ], "valid": true }, { "description": "JavaScript pseudo-array is valid", "data": { "0": "invalid", "1": "valid", "length": 2 }, "valid": true } ] }, { "description": "items with boolean schema (true)", "schema": {"items": true}, "tests": [ { "description": "any array is valid", "data": [ 1, "foo", true ], "valid": true }, { "description": "empty array is valid", "data": [], "valid": true } ] }, { "description": "items with boolean schema (false)", "schema": {"items": false}, "tests": [ { "description": "any non-empty array is invalid", "data": [ 1, "foo", true ], "valid": false }, { "description": "empty array is valid", "data": [], "valid": true } ] }, { "description": "items with boolean schemas", "schema": { "items": [true, false] }, "tests": [ { "description": "array with one item is valid", "data": [ 1 ], "valid": true }, { "description": "array with two items is invalid", "data": [ 1, "foo" ], "valid": false }, { "description": "empty array is valid", "data": [], "valid": true } ] }, { "description": "items and subitems", "schema": { "definitions": { "item": { "type": "array", "additionalItems": false, "items": [ { "$ref": "#/definitions/sub-item" }, { "$ref": "#/definitions/sub-item" } ] }, "sub-item": { "type": "object", "required": ["foo"] } }, "type": "array", "additionalItems": false, "items": [ { "$ref": "#/definitions/item" }, { "$ref": "#/definitions/item" }, { "$ref": "#/definitions/item" } ] }, "tests": [ { "description": "valid items", "data": [ [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": true }, { "description": "too many items", "data": [ [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "too many sub-items", "data": [ [ {"foo": null}, {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "wrong item", "data": [ {"foo": null}, [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "wrong sub-item", "data": [ [ {}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "fewer items is valid", "data": [ [ {"foo": null} ], [ {"foo": null} ] ], "valid": true } ] }, { "description": "nested items", "schema": { "type": "array", "items": { "type": "array", "items": { "type": "array", "items": { "type": "array", "items": { "type": "number" } } } } }, "tests": [ { "description": "valid nested array", "data": [[[[1]], [[2],[3]]], [[[4], [5], [6]]]], "valid": true }, { "description": "nested array with invalid type", "data": [[[["1"]], [[2],[3]]], [[[4], [5], [6]]]], "valid": false }, { "description": "not deep enough", "data": [[[1], [2],[3]], [[4], [5], [6]]], "valid": false } ] }, { "description": "single-form items with null instance elements", "schema": { "items": { "type": "null" } }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] }, { "description": "array-form items with null instance elements", "schema": { "items": [ { "type": "null" } ] }, "tests": [ { "description": "allows null elements", "data": [ null ], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/maxItems.json000066400000000000000000000021551477700171100274600ustar00rootroot00000000000000[ { "description": "maxItems validation", "schema": {"maxItems": 2}, "tests": [ { "description": "shorter is valid", "data": [1], "valid": true }, { "description": "exact length is valid", "data": [1, 2], "valid": true }, { "description": "too long is invalid", "data": [1, 2, 3], "valid": false }, { "description": "ignores non-arrays", "data": "foobar", "valid": true } ] }, { "description": "maxItems validation with a decimal", "schema": {"maxItems": 2.0}, "tests": [ { "description": "shorter is valid", "data": [1], "valid": true }, { "description": "too long is invalid", "data": [1, 2, 3], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/maxLength.json000066400000000000000000000024511477700171100276170ustar00rootroot00000000000000[ { "description": "maxLength validation", "schema": {"maxLength": 2}, "tests": [ { "description": "shorter is valid", "data": "f", "valid": true }, { "description": "exact length is valid", "data": "fo", "valid": true }, { "description": "too long is invalid", "data": "foo", "valid": false }, { "description": "ignores non-strings", "data": 100, "valid": true }, { "description": "two supplementary Unicode code points is long enough", "data": "\uD83D\uDCA9\uD83D\uDCA9", "valid": true } ] }, { "description": "maxLength validation with a decimal", "schema": {"maxLength": 2.0}, "tests": [ { "description": "shorter is valid", "data": "f", "valid": true }, { "description": "too long is invalid", "data": "foo", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/maxProperties.json000066400000000000000000000036531477700171100305370ustar00rootroot00000000000000[ { "description": "maxProperties validation", "schema": {"maxProperties": 2}, "tests": [ { "description": "shorter is valid", "data": {"foo": 1}, "valid": true }, { "description": "exact length is valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "too long is invalid", "data": {"foo": 1, "bar": 2, "baz": 3}, "valid": false }, { "description": "ignores arrays", "data": [1, 2, 3], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "maxProperties validation with a decimal", "schema": {"maxProperties": 2.0}, "tests": [ { "description": "shorter is valid", "data": {"foo": 1}, "valid": true }, { "description": "too long is invalid", "data": {"foo": 1, "bar": 2, "baz": 3}, "valid": false } ] }, { "description": "maxProperties = 0 means the object is empty", "schema": { "maxProperties": 0 }, "tests": [ { "description": "no properties is valid", "data": {}, "valid": true }, { "description": "one property is invalid", "data": { "foo": 1 }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/maximum.json000066400000000000000000000027041477700171100273460ustar00rootroot00000000000000[ { "description": "maximum validation", "schema": {"maximum": 3.0}, "tests": [ { "description": "below the maximum is valid", "data": 2.6, "valid": true }, { "description": "boundary point is valid", "data": 3.0, "valid": true }, { "description": "above the maximum is invalid", "data": 3.5, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] }, { "description": "maximum validation with unsigned integer", "schema": {"maximum": 300}, "tests": [ { "description": "below the maximum is invalid", "data": 299.97, "valid": true }, { "description": "boundary point integer is valid", "data": 300, "valid": true }, { "description": "boundary point float is valid", "data": 300.00, "valid": true }, { "description": "above the maximum is invalid", "data": 300.5, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/minItems.json000066400000000000000000000021341477700171100274530ustar00rootroot00000000000000[ { "description": "minItems validation", "schema": {"minItems": 1}, "tests": [ { "description": "longer is valid", "data": [1, 2], "valid": true }, { "description": "exact length is valid", "data": [1], "valid": true }, { "description": "too short is invalid", "data": [], "valid": false }, { "description": "ignores non-arrays", "data": "", "valid": true } ] }, { "description": "minItems validation with a decimal", "schema": {"minItems": 1.0}, "tests": [ { "description": "longer is valid", "data": [1, 2], "valid": true }, { "description": "too short is invalid", "data": [], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/minLength.json000066400000000000000000000024371477700171100276210ustar00rootroot00000000000000[ { "description": "minLength validation", "schema": {"minLength": 2}, "tests": [ { "description": "longer is valid", "data": "foo", "valid": true }, { "description": "exact length is valid", "data": "fo", "valid": true }, { "description": "too short is invalid", "data": "f", "valid": false }, { "description": "ignores non-strings", "data": 1, "valid": true }, { "description": "one supplementary Unicode code point is not long enough", "data": "\uD83D\uDCA9", "valid": false } ] }, { "description": "minLength validation with a decimal", "schema": {"minLength": 2.0}, "tests": [ { "description": "longer is valid", "data": "foo", "valid": true }, { "description": "too short is invalid", "data": "f", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/minProperties.json000066400000000000000000000026531477700171100305340ustar00rootroot00000000000000[ { "description": "minProperties validation", "schema": {"minProperties": 1}, "tests": [ { "description": "longer is valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "exact length is valid", "data": {"foo": 1}, "valid": true }, { "description": "too short is invalid", "data": {}, "valid": false }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores strings", "data": "", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "minProperties validation with a decimal", "schema": {"minProperties": 1.0}, "tests": [ { "description": "longer is valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "too short is invalid", "data": {}, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/minimum.json000066400000000000000000000036121477700171100273430ustar00rootroot00000000000000[ { "description": "minimum validation", "schema": {"minimum": 1.1}, "tests": [ { "description": "above the minimum is valid", "data": 2.6, "valid": true }, { "description": "boundary point is valid", "data": 1.1, "valid": true }, { "description": "below the minimum is invalid", "data": 0.6, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] }, { "description": "minimum validation with signed integer", "schema": {"minimum": -2}, "tests": [ { "description": "negative above the minimum is valid", "data": -1, "valid": true }, { "description": "positive above the minimum is valid", "data": 0, "valid": true }, { "description": "boundary point is valid", "data": -2, "valid": true }, { "description": "boundary point with float is valid", "data": -2.0, "valid": true }, { "description": "float below the minimum is invalid", "data": -2.0001, "valid": false }, { "description": "int below the minimum is invalid", "data": -3, "valid": false }, { "description": "ignores non-numbers", "data": "x", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/multipleOf.json000066400000000000000000000042241477700171100300100ustar00rootroot00000000000000[ { "description": "by int", "schema": {"multipleOf": 2}, "tests": [ { "description": "int by int", "data": 10, "valid": true }, { "description": "int by int fail", "data": 7, "valid": false }, { "description": "ignores non-numbers", "data": "foo", "valid": true } ] }, { "description": "by number", "schema": {"multipleOf": 1.5}, "tests": [ { "description": "zero is multiple of anything", "data": 0, "valid": true }, { "description": "4.5 is multiple of 1.5", "data": 4.5, "valid": true }, { "description": "35 is not multiple of 1.5", "data": 35, "valid": false } ] }, { "description": "by small number", "schema": {"multipleOf": 0.0001}, "tests": [ { "description": "0.0075 is multiple of 0.0001", "data": 0.0075, "valid": true }, { "description": "0.00751 is not multiple of 0.0001", "data": 0.00751, "valid": false } ] }, { "description": "float division = inf", "schema": {"type": "integer", "multipleOf": 0.123456789}, "tests": [ { "description": "always invalid, but naive implementations may raise an overflow error", "data": 1e308, "valid": false } ] }, { "description": "small multiple of large integer", "schema": {"type": "integer", "multipleOf": 1e-8}, "tests": [ { "description": "any integer is a multiple of 1e-8", "data": 12391239123, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/not.json000066400000000000000000000053761477700171100265010ustar00rootroot00000000000000[ { "description": "not", "schema": { "not": {"type": "integer"} }, "tests": [ { "description": "allowed", "data": "foo", "valid": true }, { "description": "disallowed", "data": 1, "valid": false } ] }, { "description": "not multiple types", "schema": { "not": {"type": ["integer", "boolean"]} }, "tests": [ { "description": "valid", "data": "foo", "valid": true }, { "description": "mismatch", "data": 1, "valid": false }, { "description": "other mismatch", "data": true, "valid": false } ] }, { "description": "not more complex schema", "schema": { "not": { "type": "object", "properties": { "foo": { "type": "string" } } } }, "tests": [ { "description": "match", "data": 1, "valid": true }, { "description": "other match", "data": {"foo": 1}, "valid": true }, { "description": "mismatch", "data": {"foo": "bar"}, "valid": false } ] }, { "description": "forbidden property", "schema": { "properties": { "foo": { "not": {} } } }, "tests": [ { "description": "property present", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "property absent", "data": {"bar": 1, "baz": 2}, "valid": true } ] }, { "description": "not with boolean schema true", "schema": {"not": true}, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "not with boolean schema false", "schema": {"not": false}, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/oneOf.json000066400000000000000000000161231477700171100267370ustar00rootroot00000000000000[ { "description": "oneOf", "schema": { "oneOf": [ { "type": "integer" }, { "minimum": 2 } ] }, "tests": [ { "description": "first oneOf valid", "data": 1, "valid": true }, { "description": "second oneOf valid", "data": 2.5, "valid": true }, { "description": "both oneOf valid", "data": 3, "valid": false }, { "description": "neither oneOf valid", "data": 1.5, "valid": false } ] }, { "description": "oneOf with base schema", "schema": { "type": "string", "oneOf" : [ { "minLength": 2 }, { "maxLength": 4 } ] }, "tests": [ { "description": "mismatch base schema", "data": 3, "valid": false }, { "description": "one oneOf valid", "data": "foobar", "valid": true }, { "description": "both oneOf valid", "data": "foo", "valid": false } ] }, { "description": "oneOf with boolean schemas, all true", "schema": {"oneOf": [true, true, true]}, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "oneOf with boolean schemas, one true", "schema": {"oneOf": [true, false, false]}, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "oneOf with boolean schemas, more than one true", "schema": {"oneOf": [true, true, false]}, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "oneOf with boolean schemas, all false", "schema": {"oneOf": [false, false, false]}, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "oneOf complex types", "schema": { "oneOf": [ { "properties": { "bar": {"type": "integer"} }, "required": ["bar"] }, { "properties": { "foo": {"type": "string"} }, "required": ["foo"] } ] }, "tests": [ { "description": "first oneOf valid (complex)", "data": {"bar": 2}, "valid": true }, { "description": "second oneOf valid (complex)", "data": {"foo": "baz"}, "valid": true }, { "description": "both oneOf valid (complex)", "data": {"foo": "baz", "bar": 2}, "valid": false }, { "description": "neither oneOf valid (complex)", "data": {"foo": 2, "bar": "quux"}, "valid": false } ] }, { "description": "oneOf with empty schema", "schema": { "oneOf": [ { "type": "number" }, {} ] }, "tests": [ { "description": "one valid - valid", "data": "foo", "valid": true }, { "description": "both valid - invalid", "data": 123, "valid": false } ] }, { "description": "oneOf with required", "schema": { "type": "object", "oneOf": [ { "required": ["foo", "bar"] }, { "required": ["foo", "baz"] } ] }, "tests": [ { "description": "both invalid - invalid", "data": {"bar": 2}, "valid": false }, { "description": "first valid - valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "second valid - valid", "data": {"foo": 1, "baz": 3}, "valid": true }, { "description": "both valid - invalid", "data": {"foo": 1, "bar": 2, "baz" : 3}, "valid": false } ] }, { "description": "oneOf with missing optional property", "schema": { "oneOf": [ { "properties": { "bar": true, "baz": true }, "required": ["bar"] }, { "properties": { "foo": true }, "required": ["foo"] } ] }, "tests": [ { "description": "first oneOf valid", "data": {"bar": 8}, "valid": true }, { "description": "second oneOf valid", "data": {"foo": "foo"}, "valid": true }, { "description": "both oneOf valid", "data": {"foo": "foo", "bar": 8}, "valid": false }, { "description": "neither oneOf valid", "data": {"baz": "quux"}, "valid": false } ] }, { "description": "nested oneOf, to check validation semantics", "schema": { "oneOf": [ { "oneOf": [ { "type": "null" } ] } ] }, "tests": [ { "description": "null is valid", "data": null, "valid": true }, { "description": "anything non-null is invalid", "data": 123, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/000077500000000000000000000000001477700171100266205ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/bignum.json000066400000000000000000000054011477700171100307740ustar00rootroot00000000000000[ { "description": "integer", "schema": { "type": "integer" }, "tests": [ { "description": "a bignum is an integer", "data": 12345678910111213141516171819202122232425262728293031, "valid": true }, { "description": "a negative bignum is an integer", "data": -12345678910111213141516171819202122232425262728293031, "valid": true } ] }, { "description": "number", "schema": { "type": "number" }, "tests": [ { "description": "a bignum is a number", "data": 98249283749234923498293171823948729348710298301928331, "valid": true }, { "description": "a negative bignum is a number", "data": -98249283749234923498293171823948729348710298301928331, "valid": true } ] }, { "description": "string", "schema": { "type": "string" }, "tests": [ { "description": "a bignum is not a string", "data": 98249283749234923498293171823948729348710298301928331, "valid": false } ] }, { "description": "maximum integer comparison", "schema": { "maximum": 18446744073709551615 }, "tests": [ { "description": "comparison works for high numbers", "data": 18446744073709551600, "valid": true } ] }, { "description": "float comparison with high precision", "schema": { "exclusiveMaximum": 972783798187987123879878123.18878137 }, "tests": [ { "description": "comparison works for high numbers", "data": 972783798187987123879878123.188781371, "valid": false } ] }, { "description": "minimum integer comparison", "schema": { "minimum": -18446744073709551615 }, "tests": [ { "description": "comparison works for very negative numbers", "data": -18446744073709551600, "valid": true } ] }, { "description": "float comparison with high precision on negative numbers", "schema": { "exclusiveMinimum": -972783798187987123879878123.18878137 }, "tests": [ { "description": "comparison works for very negative numbers", "data": -972783798187987123879878123.188781371, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/content.json000066400000000000000000000042741477700171100311740ustar00rootroot00000000000000[ { "description": "validation of string-encoded content based on media type", "schema": { "contentMediaType": "application/json" }, "tests": [ { "description": "a valid JSON document", "data": "{\"foo\": \"bar\"}", "valid": true }, { "description": "an invalid JSON document", "data": "{:}", "valid": false }, { "description": "ignores non-strings", "data": 100, "valid": true } ] }, { "description": "validation of binary string-encoding", "schema": { "contentEncoding": "base64" }, "tests": [ { "description": "a valid base64 string", "data": "eyJmb28iOiAiYmFyIn0K", "valid": true }, { "description": "an invalid base64 string (% is not a valid character)", "data": "eyJmb28iOi%iYmFyIn0K", "valid": false }, { "description": "ignores non-strings", "data": 100, "valid": true } ] }, { "description": "validation of binary-encoded media type documents", "schema": { "contentMediaType": "application/json", "contentEncoding": "base64" }, "tests": [ { "description": "a valid base64-encoded JSON document", "data": "eyJmb28iOiAiYmFyIn0K", "valid": true }, { "description": "a validly-encoded invalid JSON document", "data": "ezp9Cg==", "valid": false }, { "description": "an invalid base64 string that is valid JSON", "data": "{}", "valid": false }, { "description": "ignores non-strings", "data": 100, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/cross-draft.json000066400000000000000000000014741477700171100317500ustar00rootroot00000000000000[ { "description": "refs to future drafts are processed as future drafts", "schema": { "type": "object", "allOf": [ { "properties": { "foo": true } }, { "$ref": "http://localhost:1234/draft2019-09/dependentRequired.json" } ] }, "tests": [ { "description": "missing bar is invalid", "comment": "if the implementation is not processing the $ref as a 2019-09 schema, this test will fail", "data": {"foo": "any value"}, "valid": false }, { "description": "present bar is valid", "data": {"foo": "any value", "bar": "also any value"}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/ecmascript-regex.json000066400000000000000000000441011477700171100327550ustar00rootroot00000000000000[ { "description": "ECMA 262 regex $ does not match trailing newline", "schema": { "type": "string", "pattern": "^abc$" }, "tests": [ { "description": "matches in Python, but not in ECMA 262", "data": "abc\\n", "valid": false }, { "description": "matches", "data": "abc", "valid": true } ] }, { "description": "ECMA 262 regex converts \\t to horizontal tab", "schema": { "type": "string", "pattern": "^\\t$" }, "tests": [ { "description": "does not match", "data": "\\t", "valid": false }, { "description": "matches", "data": "\u0009", "valid": true } ] }, { "description": "ECMA 262 regex escapes control codes with \\c and upper letter", "schema": { "type": "string", "pattern": "^\\cC$" }, "tests": [ { "description": "does not match", "data": "\\cC", "valid": false }, { "description": "matches", "data": "\u0003", "valid": true } ] }, { "description": "ECMA 262 regex escapes control codes with \\c and lower letter", "schema": { "type": "string", "pattern": "^\\cc$" }, "tests": [ { "description": "does not match", "data": "\\cc", "valid": false }, { "description": "matches", "data": "\u0003", "valid": true } ] }, { "description": "ECMA 262 \\d matches ascii digits only", "schema": { "type": "string", "pattern": "^\\d$" }, "tests": [ { "description": "ASCII zero matches", "data": "0", "valid": true }, { "description": "NKO DIGIT ZERO does not match (unlike e.g. Python)", "data": "߀", "valid": false }, { "description": "NKO DIGIT ZERO (as \\u escape) does not match", "data": "\u07c0", "valid": false } ] }, { "description": "ECMA 262 \\D matches everything but ascii digits", "schema": { "type": "string", "pattern": "^\\D$" }, "tests": [ { "description": "ASCII zero does not match", "data": "0", "valid": false }, { "description": "NKO DIGIT ZERO matches (unlike e.g. Python)", "data": "߀", "valid": true }, { "description": "NKO DIGIT ZERO (as \\u escape) matches", "data": "\u07c0", "valid": true } ] }, { "description": "ECMA 262 \\w matches ascii letters only", "schema": { "type": "string", "pattern": "^\\w$" }, "tests": [ { "description": "ASCII 'a' matches", "data": "a", "valid": true }, { "description": "latin-1 e-acute does not match (unlike e.g. Python)", "data": "é", "valid": false } ] }, { "description": "ECMA 262 \\W matches everything but ascii letters", "schema": { "type": "string", "pattern": "^\\W$" }, "tests": [ { "description": "ASCII 'a' does not match", "data": "a", "valid": false }, { "description": "latin-1 e-acute matches (unlike e.g. Python)", "data": "é", "valid": true } ] }, { "description": "ECMA 262 \\s matches whitespace", "schema": { "type": "string", "pattern": "^\\s$" }, "tests": [ { "description": "ASCII space matches", "data": " ", "valid": true }, { "description": "Character tabulation matches", "data": "\t", "valid": true }, { "description": "Line tabulation matches", "data": "\u000b", "valid": true }, { "description": "Form feed matches", "data": "\u000c", "valid": true }, { "description": "latin-1 non-breaking-space matches", "data": "\u00a0", "valid": true }, { "description": "zero-width whitespace matches", "data": "\ufeff", "valid": true }, { "description": "line feed matches (line terminator)", "data": "\u000a", "valid": true }, { "description": "paragraph separator matches (line terminator)", "data": "\u2029", "valid": true }, { "description": "EM SPACE matches (Space_Separator)", "data": "\u2003", "valid": true }, { "description": "Non-whitespace control does not match", "data": "\u0001", "valid": false }, { "description": "Non-whitespace does not match", "data": "\u2013", "valid": false } ] }, { "description": "ECMA 262 \\S matches everything but whitespace", "schema": { "type": "string", "pattern": "^\\S$" }, "tests": [ { "description": "ASCII space does not match", "data": " ", "valid": false }, { "description": "Character tabulation does not match", "data": "\t", "valid": false }, { "description": "Line tabulation does not match", "data": "\u000b", "valid": false }, { "description": "Form feed does not match", "data": "\u000c", "valid": false }, { "description": "latin-1 non-breaking-space does not match", "data": "\u00a0", "valid": false }, { "description": "zero-width whitespace does not match", "data": "\ufeff", "valid": false }, { "description": "line feed does not match (line terminator)", "data": "\u000a", "valid": false }, { "description": "paragraph separator does not match (line terminator)", "data": "\u2029", "valid": false }, { "description": "EM SPACE does not match (Space_Separator)", "data": "\u2003", "valid": false }, { "description": "Non-whitespace control matches", "data": "\u0001", "valid": true }, { "description": "Non-whitespace matches", "data": "\u2013", "valid": true } ] }, { "description": "patterns always use unicode semantics with pattern", "schema": { "pattern": "\\p{Letter}cole" }, "tests": [ { "description": "ascii character in json string", "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", "valid": true }, { "description": "literal unicode character in json string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": true }, { "description": "unicode character in hex format in string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": true }, { "description": "unicode matching is case-sensitive", "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", "valid": false } ] }, { "description": "\\w in patterns matches [A-Za-z0-9_], not unicode letters", "schema": { "pattern": "\\wcole" }, "tests": [ { "description": "ascii character in json string", "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", "valid": true }, { "description": "literal unicode character in json string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "unicode character in hex format in string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "unicode matching is case-sensitive", "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", "valid": false } ] }, { "description": "pattern with ASCII ranges", "schema": { "pattern": "[a-z]cole" }, "tests": [ { "description": "literal unicode character in json string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "unicode character in hex format in string", "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", "valid": false }, { "description": "ascii characters match", "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", "valid": true } ] }, { "description": "\\d in pattern matches [0-9], not unicode digits", "schema": { "pattern": "^\\d+$" }, "tests": [ { "description": "ascii digits", "data": "42", "valid": true }, { "description": "ascii non-digits", "data": "-%#", "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": "৪২", "valid": false } ] }, { "description": "pattern with non-ASCII digits", "schema": { "pattern": "^\\p{digit}+$" }, "tests": [ { "description": "ascii digits", "data": "42", "valid": true }, { "description": "ascii non-digits", "data": "-%#", "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": "৪২", "valid": true } ] }, { "description": "patterns always use unicode semantics with patternProperties", "schema": { "type": "object", "patternProperties": { "\\p{Letter}cole": true }, "additionalProperties": false }, "tests": [ { "description": "ascii character in json string", "data": { "l'ecole": "pas de vraie vie" }, "valid": true }, { "description": "literal unicode character in json string", "data": { "l'école": "pas de vraie vie" }, "valid": true }, { "description": "unicode character in hex format in string", "data": { "l'\u00e9cole": "pas de vraie vie" }, "valid": true }, { "description": "unicode matching is case-sensitive", "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, "valid": false } ] }, { "description": "\\w in patternProperties matches [A-Za-z0-9_], not unicode letters", "schema": { "type": "object", "patternProperties": { "\\wcole": true }, "additionalProperties": false }, "tests": [ { "description": "ascii character in json string", "data": { "l'ecole": "pas de vraie vie" }, "valid": true }, { "description": "literal unicode character in json string", "data": { "l'école": "pas de vraie vie" }, "valid": false }, { "description": "unicode character in hex format in string", "data": { "l'\u00e9cole": "pas de vraie vie" }, "valid": false }, { "description": "unicode matching is case-sensitive", "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, "valid": false } ] }, { "description": "patternProperties with ASCII ranges", "schema": { "type": "object", "patternProperties": { "[a-z]cole": true }, "additionalProperties": false }, "tests": [ { "description": "literal unicode character in json string", "data": { "l'école": "pas de vraie vie" }, "valid": false }, { "description": "unicode character in hex format in string", "data": { "l'\u00e9cole": "pas de vraie vie" }, "valid": false }, { "description": "ascii characters match", "data": { "l'ecole": "pas de vraie vie" }, "valid": true } ] }, { "description": "\\d in patternProperties matches [0-9], not unicode digits", "schema": { "type": "object", "patternProperties": { "^\\d+$": true }, "additionalProperties": false }, "tests": [ { "description": "ascii digits", "data": { "42": "life, the universe, and everything" }, "valid": true }, { "description": "ascii non-digits", "data": { "-%#": "spending the year dead for tax reasons" }, "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": { "৪২": "khajit has wares if you have coin" }, "valid": false } ] }, { "description": "patternProperties with non-ASCII digits", "schema": { "type": "object", "patternProperties": { "^\\p{digit}+$": true }, "additionalProperties": false }, "tests": [ { "description": "ascii digits", "data": { "42": "life, the universe, and everything" }, "valid": true }, { "description": "ascii non-digits", "data": { "-%#": "spending the year dead for tax reasons" }, "valid": false }, { "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", "data": { "৪২": "khajit has wares if you have coin" }, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/float-overflow.json000066400000000000000000000005511477700171100324620ustar00rootroot00000000000000[ { "description": "all integers are multiples of 0.5, if overflow is handled", "schema": {"type": "integer", "multipleOf": 0.5}, "tests": [ { "description": "valid if optional overflow handling is implemented", "data": 1e308, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/000077500000000000000000000000001477700171100301105ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/date-time.json000066400000000000000000000110601477700171100326520ustar00rootroot00000000000000[ { "description": "validation of date-time strings", "schema": { "format": "date-time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid date-time string", "data": "1963-06-19T08:30:06.283185Z", "valid": true }, { "description": "a valid date-time string without second fraction", "data": "1963-06-19T08:30:06Z", "valid": true }, { "description": "a valid date-time string with plus offset", "data": "1937-01-01T12:00:27.87+00:20", "valid": true }, { "description": "a valid date-time string with minus offset", "data": "1990-12-31T15:59:50.123-08:00", "valid": true }, { "description": "a valid date-time with a leap second, UTC", "data": "1998-12-31T23:59:60Z", "valid": true }, { "description": "a valid date-time with a leap second, with minus offset", "data": "1998-12-31T15:59:60.123-08:00", "valid": true }, { "description": "an invalid date-time past leap second, UTC", "data": "1998-12-31T23:59:61Z", "valid": false }, { "description": "an invalid date-time with leap second on a wrong minute, UTC", "data": "1998-12-31T23:58:60Z", "valid": false }, { "description": "an invalid date-time with leap second on a wrong hour, UTC", "data": "1998-12-31T22:59:60Z", "valid": false }, { "description": "an invalid day in date-time string", "data": "1990-02-31T15:59:59.123-08:00", "valid": false }, { "description": "an invalid offset in date-time string", "data": "1990-12-31T15:59:59-24:00", "valid": false }, { "description": "an invalid closing Z after time-zone offset", "data": "1963-06-19T08:30:06.28123+01:00Z", "valid": false }, { "description": "an invalid date-time string", "data": "06/19/1963 08:30:06 PST", "valid": false }, { "description": "case-insensitive T and Z", "data": "1963-06-19t08:30:06.283185z", "valid": true }, { "description": "only RFC3339 not all of ISO 8601 are valid", "data": "2013-350T01:01:01", "valid": false }, { "description": "invalid non-padded month dates", "data": "1963-6-19T08:30:06.283185Z", "valid": false }, { "description": "invalid non-padded day dates", "data": "1963-06-1T08:30:06.283185Z", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4) in date portion", "data": "1963-06-1৪T00:00:00Z", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4) in time portion", "data": "1963-06-11T0৪:00:00Z", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/date.json000066400000000000000000000200521477700171100317170ustar00rootroot00000000000000[ { "description": "validation of date strings", "schema": { "format": "date" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid date string", "data": "1963-06-19", "valid": true }, { "description": "a valid date string with 31 days in January", "data": "2020-01-31", "valid": true }, { "description": "a invalid date string with 32 days in January", "data": "2020-01-32", "valid": false }, { "description": "a valid date string with 28 days in February (normal)", "data": "2021-02-28", "valid": true }, { "description": "a invalid date string with 29 days in February (normal)", "data": "2021-02-29", "valid": false }, { "description": "a valid date string with 29 days in February (leap)", "data": "2020-02-29", "valid": true }, { "description": "a invalid date string with 30 days in February (leap)", "data": "2020-02-30", "valid": false }, { "description": "a valid date string with 31 days in March", "data": "2020-03-31", "valid": true }, { "description": "a invalid date string with 32 days in March", "data": "2020-03-32", "valid": false }, { "description": "a valid date string with 30 days in April", "data": "2020-04-30", "valid": true }, { "description": "a invalid date string with 31 days in April", "data": "2020-04-31", "valid": false }, { "description": "a valid date string with 31 days in May", "data": "2020-05-31", "valid": true }, { "description": "a invalid date string with 32 days in May", "data": "2020-05-32", "valid": false }, { "description": "a valid date string with 30 days in June", "data": "2020-06-30", "valid": true }, { "description": "a invalid date string with 31 days in June", "data": "2020-06-31", "valid": false }, { "description": "a valid date string with 31 days in July", "data": "2020-07-31", "valid": true }, { "description": "a invalid date string with 32 days in July", "data": "2020-07-32", "valid": false }, { "description": "a valid date string with 31 days in August", "data": "2020-08-31", "valid": true }, { "description": "a invalid date string with 32 days in August", "data": "2020-08-32", "valid": false }, { "description": "a valid date string with 30 days in September", "data": "2020-09-30", "valid": true }, { "description": "a invalid date string with 31 days in September", "data": "2020-09-31", "valid": false }, { "description": "a valid date string with 31 days in October", "data": "2020-10-31", "valid": true }, { "description": "a invalid date string with 32 days in October", "data": "2020-10-32", "valid": false }, { "description": "a valid date string with 30 days in November", "data": "2020-11-30", "valid": true }, { "description": "a invalid date string with 31 days in November", "data": "2020-11-31", "valid": false }, { "description": "a valid date string with 31 days in December", "data": "2020-12-31", "valid": true }, { "description": "a invalid date string with 32 days in December", "data": "2020-12-32", "valid": false }, { "description": "a invalid date string with invalid month", "data": "2020-13-01", "valid": false }, { "description": "an invalid date string", "data": "06/19/1963", "valid": false }, { "description": "only RFC3339 not all of ISO 8601 are valid", "data": "2013-350", "valid": false }, { "description": "non-padded month dates are not valid", "data": "1998-1-20", "valid": false }, { "description": "non-padded day dates are not valid", "data": "1998-01-1", "valid": false }, { "description": "invalid month", "data": "1998-13-01", "valid": false }, { "description": "invalid month-day combination", "data": "1998-04-31", "valid": false }, { "description": "2021 is not a leap year", "data": "2021-02-29", "valid": false }, { "description": "2020 is a leap year", "data": "2020-02-29", "valid": true }, { "description": "invalid non-ASCII '৪' (a Bengali 4)", "data": "1963-06-1৪", "valid": false }, { "description": "ISO8601 / non-RFC3339: YYYYMMDD without dashes (2023-03-28)", "data": "20230328", "valid": false }, { "description": "ISO8601 / non-RFC3339: week number implicit day of week (2023-01-02)", "data": "2023-W01", "valid": false }, { "description": "ISO8601 / non-RFC3339: week number with day of week (2023-03-28)", "data": "2023-W13-2", "valid": false }, { "description": "ISO8601 / non-RFC3339: week number rollover to next year (2023-01-01)", "data": "2022W527", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/email.json000066400000000000000000000051041477700171100320720ustar00rootroot00000000000000[ { "description": "validation of e-mail addresses", "schema": { "format": "email" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid e-mail address", "data": "joe.bloggs@example.com", "valid": true }, { "description": "an invalid e-mail address", "data": "2962", "valid": false }, { "description": "tilde in local part is valid", "data": "te~st@example.com", "valid": true }, { "description": "tilde before local part is valid", "data": "~test@example.com", "valid": true }, { "description": "tilde after local part is valid", "data": "test~@example.com", "valid": true }, { "description": "dot before local part is not valid", "data": ".test@example.com", "valid": false }, { "description": "dot after local part is not valid", "data": "test.@example.com", "valid": false }, { "description": "two separated dots inside local part are valid", "data": "te.s.t@example.com", "valid": true }, { "description": "two subsequent dots inside local part are not valid", "data": "te..st@example.com", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/hostname.json000066400000000000000000000073671477700171100326360ustar00rootroot00000000000000[ { "description": "validation of host names", "schema": { "format": "hostname" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid host name", "data": "www.example.com", "valid": true }, { "description": "a valid punycoded IDN hostname", "data": "xn--4gbwdl.xn--wgbh1c", "valid": true }, { "description": "a host name starting with an illegal character", "data": "-a-host-name-that-starts-with--", "valid": false }, { "description": "a host name containing illegal characters", "data": "not_a_valid_host_name", "valid": false }, { "description": "a host name with a component too long", "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", "valid": false }, { "description": "starts with hyphen", "data": "-hostname", "valid": false }, { "description": "ends with hyphen", "data": "hostname-", "valid": false }, { "description": "starts with underscore", "data": "_hostname", "valid": false }, { "description": "ends with underscore", "data": "hostname_", "valid": false }, { "description": "contains underscore", "data": "host_name", "valid": false }, { "description": "maximum label length", "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.com", "valid": true }, { "description": "exceeds maximum label length", "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl.com", "valid": false }, { "description": "single label", "data": "hostname", "valid": true }, { "description": "single label with hyphen", "data": "host-name", "valid": true }, { "description": "single label with digits", "data": "h0stn4me", "valid": true }, { "description": "single label ending with digit", "data": "hostnam3", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/idn-email.json000066400000000000000000000033541477700171100326470ustar00rootroot00000000000000[ { "description": "validation of an internationalized e-mail addresses", "schema": { "format": "idn-email" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid idn e-mail (example@example.test in Hangul)", "data": "실례@실례.테스트", "valid": true }, { "description": "an invalid idn e-mail address", "data": "2962", "valid": false }, { "description": "a valid e-mail address", "data": "joe.bloggs@example.com", "valid": true }, { "description": "an invalid e-mail address", "data": "2962", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/idn-hostname.json000066400000000000000000000360041477700171100333740ustar00rootroot00000000000000[ { "description": "validation of internationalized host names", "schema": { "format": "idn-hostname" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid host name (example.test in Hangul)", "data": "실례.테스트", "valid": true }, { "description": "illegal first char U+302E Hangul single dot tone mark", "data": "〮실례.테스트", "valid": false }, { "description": "contains illegal char U+302E Hangul single dot tone mark", "data": "실〮례.테스트", "valid": false }, { "description": "a host name with a component too long", "data": "실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실례례테스트례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례테스트례례실례.테스트", "valid": false }, { "description": "invalid label, correct Punycode", "comment": "https://tools.ietf.org/html/rfc5890#section-2.3.2.1 https://tools.ietf.org/html/rfc5891#section-4.4 https://tools.ietf.org/html/rfc3492#section-7.1", "data": "-> $1.00 <--", "valid": false }, { "description": "valid Chinese Punycode", "comment": "https://tools.ietf.org/html/rfc5890#section-2.3.2.1 https://tools.ietf.org/html/rfc5891#section-4.4", "data": "xn--ihqwcrb4cv8a8dqg056pqjye", "valid": true }, { "description": "invalid Punycode", "comment": "https://tools.ietf.org/html/rfc5891#section-4.4 https://tools.ietf.org/html/rfc5890#section-2.3.2.1", "data": "xn--X", "valid": false }, { "description": "U-label contains \"--\" in the 3rd and 4th position", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1 https://tools.ietf.org/html/rfc5890#section-2.3.2.1", "data": "XN--aa---o47jg78q", "valid": false }, { "description": "U-label starts with a dash", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", "data": "-hello", "valid": false }, { "description": "U-label ends with a dash", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", "data": "hello-", "valid": false }, { "description": "U-label starts and ends with a dash", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", "data": "-hello-", "valid": false }, { "description": "Begins with a Spacing Combining Mark", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", "data": "\u0903hello", "valid": false }, { "description": "Begins with a Nonspacing Mark", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", "data": "\u0300hello", "valid": false }, { "description": "Begins with an Enclosing Mark", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", "data": "\u0488hello", "valid": false }, { "description": "Exceptions that are PVALID, left-to-right chars", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", "data": "\u00df\u03c2\u0f0b\u3007", "valid": true }, { "description": "Exceptions that are PVALID, right-to-left chars", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", "data": "\u06fd\u06fe", "valid": true }, { "description": "Exceptions that are DISALLOWED, right-to-left chars", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", "data": "\u0640\u07fa", "valid": false }, { "description": "Exceptions that are DISALLOWED, left-to-right chars", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6 Note: The two combining marks (U+302E and U+302F) are in the middle and not at the start", "data": "\u3031\u3032\u3033\u3034\u3035\u302e\u302f\u303b", "valid": false }, { "description": "MIDDLE DOT with no preceding 'l'", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", "data": "a\u00b7l", "valid": false }, { "description": "MIDDLE DOT with nothing preceding", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", "data": "\u00b7l", "valid": false }, { "description": "MIDDLE DOT with no following 'l'", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", "data": "l\u00b7a", "valid": false }, { "description": "MIDDLE DOT with nothing following", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", "data": "l\u00b7", "valid": false }, { "description": "MIDDLE DOT with surrounding 'l's", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", "data": "l\u00b7l", "valid": true }, { "description": "Greek KERAIA not followed by Greek", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", "data": "\u03b1\u0375S", "valid": false }, { "description": "Greek KERAIA not followed by anything", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", "data": "\u03b1\u0375", "valid": false }, { "description": "Greek KERAIA followed by Greek", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", "data": "\u03b1\u0375\u03b2", "valid": true }, { "description": "Hebrew GERESH not preceded by Hebrew", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", "data": "A\u05f3\u05d1", "valid": false }, { "description": "Hebrew GERESH not preceded by anything", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", "data": "\u05f3\u05d1", "valid": false }, { "description": "Hebrew GERESH preceded by Hebrew", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", "data": "\u05d0\u05f3\u05d1", "valid": true }, { "description": "Hebrew GERSHAYIM not preceded by Hebrew", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", "data": "A\u05f4\u05d1", "valid": false }, { "description": "Hebrew GERSHAYIM not preceded by anything", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", "data": "\u05f4\u05d1", "valid": false }, { "description": "Hebrew GERSHAYIM preceded by Hebrew", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", "data": "\u05d0\u05f4\u05d1", "valid": true }, { "description": "KATAKANA MIDDLE DOT with no Hiragana, Katakana, or Han", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", "data": "def\u30fbabc", "valid": false }, { "description": "KATAKANA MIDDLE DOT with no other characters", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", "data": "\u30fb", "valid": false }, { "description": "KATAKANA MIDDLE DOT with Hiragana", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", "data": "\u30fb\u3041", "valid": true }, { "description": "KATAKANA MIDDLE DOT with Katakana", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", "data": "\u30fb\u30a1", "valid": true }, { "description": "KATAKANA MIDDLE DOT with Han", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", "data": "\u30fb\u4e08", "valid": true }, { "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", "data": "\u0660\u06f0", "valid": false }, { "description": "Arabic-Indic digits not mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", "data": "\u0628\u0660\u0628", "valid": true }, { "description": "Extended Arabic-Indic digits not mixed with Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.9", "data": "\u06f00", "valid": true }, { "description": "ZERO WIDTH JOINER not preceded by Virama", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", "data": "\u0915\u200d\u0937", "valid": false }, { "description": "ZERO WIDTH JOINER not preceded by anything", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", "data": "\u200d\u0937", "valid": false }, { "description": "ZERO WIDTH JOINER preceded by Virama", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", "data": "\u0915\u094d\u200d\u0937", "valid": true }, { "description": "ZERO WIDTH NON-JOINER preceded by Virama", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1", "data": "\u0915\u094d\u200c\u0937", "valid": true }, { "description": "ZERO WIDTH NON-JOINER not preceded by Virama but matches regexp", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1 https://www.w3.org/TR/alreq/#h_disjoining_enforcement", "data": "\u0628\u064a\u200c\u0628\u064a", "valid": true }, { "description": "single label", "data": "hostname", "valid": true }, { "description": "single label with hyphen", "data": "host-name", "valid": true }, { "description": "single label with digits", "data": "h0stn4me", "valid": true }, { "description": "single label ending with digit", "data": "hostnam3", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/ipv4.json000066400000000000000000000056621477700171100316760ustar00rootroot00000000000000[ { "description": "validation of IP addresses", "schema": { "format": "ipv4" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid IP address", "data": "192.168.0.1", "valid": true }, { "description": "an IP address with too many components", "data": "127.0.0.0.1", "valid": false }, { "description": "an IP address with out-of-range values", "data": "256.256.256.256", "valid": false }, { "description": "an IP address without 4 components", "data": "127.0", "valid": false }, { "description": "an IP address as an integer", "data": "0x7f000001", "valid": false }, { "description": "an IP address as an integer (decimal)", "data": "2130706433", "valid": false }, { "description": "invalid leading zeroes, as they are treated as octals", "comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/", "data": "087.10.0.1", "valid": false }, { "description": "value without leading zero is valid", "data": "87.10.0.1", "valid": true }, { "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২7.0.0.1", "valid": false }, { "description": "netmask is not a part of ipv4 address", "data": "192.168.1.0/24", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/ipv6.json000066400000000000000000000154371477700171100317010ustar00rootroot00000000000000[ { "description": "validation of IPv6 addresses", "schema": { "format": "ipv6" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid IPv6 address", "data": "::1", "valid": true }, { "description": "an IPv6 address with out-of-range values", "data": "12345::", "valid": false }, { "description": "trailing 4 hex symbols is valid", "data": "::abef", "valid": true }, { "description": "trailing 5 hex symbols is invalid", "data": "::abcef", "valid": false }, { "description": "an IPv6 address with too many components", "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", "valid": false }, { "description": "an IPv6 address containing illegal characters", "data": "::laptop", "valid": false }, { "description": "no digits is valid", "data": "::", "valid": true }, { "description": "leading colons is valid", "data": "::42:ff:1", "valid": true }, { "description": "trailing colons is valid", "data": "d6::", "valid": true }, { "description": "missing leading octet is invalid", "data": ":2:3:4:5:6:7:8", "valid": false }, { "description": "missing trailing octet is invalid", "data": "1:2:3:4:5:6:7:", "valid": false }, { "description": "missing leading octet with omitted octets later", "data": ":2:3:4::8", "valid": false }, { "description": "single set of double colons in the middle is valid", "data": "1:d6::42", "valid": true }, { "description": "two sets of double colons is invalid", "data": "1::d6::42", "valid": false }, { "description": "mixed format with the ipv4 section as decimal octets", "data": "1::d6:192.168.0.1", "valid": true }, { "description": "mixed format with double colons between the sections", "data": "1:2::192.168.0.1", "valid": true }, { "description": "mixed format with ipv4 section with octet out of range", "data": "1::2:192.168.256.1", "valid": false }, { "description": "mixed format with ipv4 section with a hex octet", "data": "1::2:192.168.ff.1", "valid": false }, { "description": "mixed format with leading double colons (ipv4-mapped ipv6 address)", "data": "::ffff:192.168.0.1", "valid": true }, { "description": "triple colons is invalid", "data": "1:2:3:4:5:::8", "valid": false }, { "description": "8 octets", "data": "1:2:3:4:5:6:7:8", "valid": true }, { "description": "insufficient octets without double colons", "data": "1:2:3:4:5:6:7", "valid": false }, { "description": "no colons is invalid", "data": "1", "valid": false }, { "description": "ipv4 is not ipv6", "data": "127.0.0.1", "valid": false }, { "description": "ipv4 segment must have 4 octets", "data": "1:2:3:4:1.2.3", "valid": false }, { "description": "leading whitespace is invalid", "data": " ::1", "valid": false }, { "description": "trailing whitespace is invalid", "data": "::1 ", "valid": false }, { "description": "netmask is not a part of ipv6 address", "data": "fe80::/64", "valid": false }, { "description": "zone id is not a part of ipv6 address", "data": "fe80::a%eth1", "valid": false }, { "description": "a long valid ipv6", "data": "1000:1000:1000:1000:1000:1000:255.255.255.255", "valid": true }, { "description": "a long invalid ipv6, below length limit, first", "data": "100:100:100:100:100:100:255.255.255.255.255", "valid": false }, { "description": "a long invalid ipv6, below length limit, second", "data": "100:100:100:100:100:100:100:255.255.255.255", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4)", "data": "1:2:3:4:5:6:7:৪", "valid": false }, { "description": "invalid non-ASCII '৪' (a Bengali 4) in the IPv4 portion", "data": "1:2::192.16৪.0.1", "valid": false } ] } ] iri-reference.json000066400000000000000000000043121477700171100334430ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format[ { "description": "validation of IRI References", "schema": { "format": "iri-reference" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid IRI", "data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx", "valid": true }, { "description": "a valid protocol-relative IRI Reference", "data": "//ƒøø.ßår/?∂éœ=πîx#πîüx", "valid": true }, { "description": "a valid relative IRI Reference", "data": "/âππ", "valid": true }, { "description": "an invalid IRI Reference", "data": "\\\\WINDOWS\\filëßåré", "valid": false }, { "description": "a valid IRI Reference", "data": "âππ", "valid": true }, { "description": "a valid IRI fragment", "data": "#ƒrägmênt", "valid": true }, { "description": "an invalid IRI fragment", "data": "#ƒräg\\mênt", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/iri.json000066400000000000000000000053241477700171100315720ustar00rootroot00000000000000[ { "description": "validation of IRIs", "schema": { "format": "iri" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid IRI with anchor tag", "data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx", "valid": true }, { "description": "a valid IRI with anchor tag and parentheses", "data": "http://ƒøø.com/blah_(wîkïpédiå)_blah#ßité-1", "valid": true }, { "description": "a valid IRI with URL-encoded stuff", "data": "http://ƒøø.ßår/?q=Test%20URL-encoded%20stuff", "valid": true }, { "description": "a valid IRI with many special characters", "data": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", "valid": true }, { "description": "a valid IRI based on IPv6", "data": "http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]", "valid": true }, { "description": "an invalid IRI based on IPv6", "data": "http://2001:0db8:85a3:0000:0000:8a2e:0370:7334", "valid": false }, { "description": "an invalid relative IRI Reference", "data": "/abc", "valid": false }, { "description": "an invalid IRI", "data": "\\\\WINDOWS\\filëßåré", "valid": false }, { "description": "an invalid IRI though valid IRI reference", "data": "âππ", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/json-pointer.json000066400000000000000000000150631477700171100334370ustar00rootroot00000000000000[ { "description": "validation of JSON-pointers (JSON String Representation)", "schema": { "format": "json-pointer" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid JSON-pointer", "data": "/foo/bar~0/baz~1/%a", "valid": true }, { "description": "not a valid JSON-pointer (~ not escaped)", "data": "/foo/bar~", "valid": false }, { "description": "valid JSON-pointer with empty segment", "data": "/foo//bar", "valid": true }, { "description": "valid JSON-pointer with the last empty segment", "data": "/foo/bar/", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #1", "data": "", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #2", "data": "/foo", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #3", "data": "/foo/0", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #4", "data": "/", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #5", "data": "/a~1b", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #6", "data": "/c%d", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #7", "data": "/e^f", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #8", "data": "/g|h", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #9", "data": "/i\\j", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #10", "data": "/k\"l", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #11", "data": "/ ", "valid": true }, { "description": "valid JSON-pointer as stated in RFC 6901 #12", "data": "/m~0n", "valid": true }, { "description": "valid JSON-pointer used adding to the last array position", "data": "/foo/-", "valid": true }, { "description": "valid JSON-pointer (- used as object member name)", "data": "/foo/-/bar", "valid": true }, { "description": "valid JSON-pointer (multiple escaped characters)", "data": "/~1~0~0~1~1", "valid": true }, { "description": "valid JSON-pointer (escaped with fraction part) #1", "data": "/~1.1", "valid": true }, { "description": "valid JSON-pointer (escaped with fraction part) #2", "data": "/~0.1", "valid": true }, { "description": "not a valid JSON-pointer (URI Fragment Identifier) #1", "data": "#", "valid": false }, { "description": "not a valid JSON-pointer (URI Fragment Identifier) #2", "data": "#/", "valid": false }, { "description": "not a valid JSON-pointer (URI Fragment Identifier) #3", "data": "#a", "valid": false }, { "description": "not a valid JSON-pointer (some escaped, but not all) #1", "data": "/~0~", "valid": false }, { "description": "not a valid JSON-pointer (some escaped, but not all) #2", "data": "/~0/~", "valid": false }, { "description": "not a valid JSON-pointer (wrong escape character) #1", "data": "/~2", "valid": false }, { "description": "not a valid JSON-pointer (wrong escape character) #2", "data": "/~-1", "valid": false }, { "description": "not a valid JSON-pointer (multiple characters not escaped)", "data": "/~~", "valid": false }, { "description": "not a valid JSON-pointer (isn't empty nor starts with /) #1", "data": "a", "valid": false }, { "description": "not a valid JSON-pointer (isn't empty nor starts with /) #2", "data": "0", "valid": false }, { "description": "not a valid JSON-pointer (isn't empty nor starts with /) #3", "data": "a/a", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/regex.json000066400000000000000000000026161477700171100321220ustar00rootroot00000000000000[ { "description": "validation of regular expressions", "schema": { "format": "regex" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid regular expression", "data": "([abc])+\\s+$", "valid": true }, { "description": "a regular expression with unclosed parens is invalid", "data": "^(abc]", "valid": false } ] } ] relative-json-pointer.json000066400000000000000000000057431477700171100351750ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format[ { "description": "validation of Relative JSON Pointers (RJP)", "schema": { "format": "relative-json-pointer" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid upwards RJP", "data": "1", "valid": true }, { "description": "a valid downwards RJP", "data": "0/foo/bar", "valid": true }, { "description": "a valid up and then down RJP, with array index", "data": "2/0/baz/1/zip", "valid": true }, { "description": "a valid RJP taking the member or index name", "data": "0#", "valid": true }, { "description": "an invalid RJP that is a valid JSON Pointer", "data": "/foo/bar", "valid": false }, { "description": "negative prefix", "data": "-1/foo/bar", "valid": false }, { "description": "explicit positive prefix", "data": "+1/foo/bar", "valid": false }, { "description": "## is not a valid json-pointer", "data": "0##", "valid": false }, { "description": "zero cannot be followed by other digits, plus json-pointer", "data": "01/a", "valid": false }, { "description": "zero cannot be followed by other digits, plus octothorpe", "data": "01#", "valid": false }, { "description": "empty string", "data": "", "valid": false }, { "description": "multi-digit integer prefix", "data": "120/foo/bar", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/time.json000066400000000000000000000175051477700171100317510ustar00rootroot00000000000000[ { "description": "validation of time strings", "schema": { "format": "time" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid time string", "data": "08:30:06Z", "valid": true }, { "description": "invalid time string with extra leading zeros", "data": "008:030:006Z", "valid": false }, { "description": "invalid time string with no leading zero for single digit", "data": "8:3:6Z", "valid": false }, { "description": "hour, minute, second must be two digits", "data": "8:0030:6Z", "valid": false }, { "description": "a valid time string with leap second, Zulu", "data": "23:59:60Z", "valid": true }, { "description": "invalid leap second, Zulu (wrong hour)", "data": "22:59:60Z", "valid": false }, { "description": "invalid leap second, Zulu (wrong minute)", "data": "23:58:60Z", "valid": false }, { "description": "valid leap second, zero time-offset", "data": "23:59:60+00:00", "valid": true }, { "description": "invalid leap second, zero time-offset (wrong hour)", "data": "22:59:60+00:00", "valid": false }, { "description": "invalid leap second, zero time-offset (wrong minute)", "data": "23:58:60+00:00", "valid": false }, { "description": "valid leap second, positive time-offset", "data": "01:29:60+01:30", "valid": true }, { "description": "valid leap second, large positive time-offset", "data": "23:29:60+23:30", "valid": true }, { "description": "invalid leap second, positive time-offset (wrong hour)", "data": "23:59:60+01:00", "valid": false }, { "description": "invalid leap second, positive time-offset (wrong minute)", "data": "23:59:60+00:30", "valid": false }, { "description": "valid leap second, negative time-offset", "data": "15:59:60-08:00", "valid": true }, { "description": "valid leap second, large negative time-offset", "data": "00:29:60-23:30", "valid": true }, { "description": "invalid leap second, negative time-offset (wrong hour)", "data": "23:59:60-01:00", "valid": false }, { "description": "invalid leap second, negative time-offset (wrong minute)", "data": "23:59:60-00:30", "valid": false }, { "description": "a valid time string with second fraction", "data": "23:20:50.52Z", "valid": true }, { "description": "a valid time string with precise second fraction", "data": "08:30:06.283185Z", "valid": true }, { "description": "a valid time string with plus offset", "data": "08:30:06+00:20", "valid": true }, { "description": "a valid time string with minus offset", "data": "08:30:06-08:00", "valid": true }, { "description": "hour, minute in time-offset must be two digits", "data": "08:30:06-8:000", "valid": false }, { "description": "a valid time string with case-insensitive Z", "data": "08:30:06z", "valid": true }, { "description": "an invalid time string with invalid hour", "data": "24:00:00Z", "valid": false }, { "description": "an invalid time string with invalid minute", "data": "00:60:00Z", "valid": false }, { "description": "an invalid time string with invalid second", "data": "00:00:61Z", "valid": false }, { "description": "an invalid time string with invalid leap second (wrong hour)", "data": "22:59:60Z", "valid": false }, { "description": "an invalid time string with invalid leap second (wrong minute)", "data": "23:58:60Z", "valid": false }, { "description": "an invalid time string with invalid time numoffset hour", "data": "01:02:03+24:00", "valid": false }, { "description": "an invalid time string with invalid time numoffset minute", "data": "01:02:03+00:60", "valid": false }, { "description": "an invalid time string with invalid time with both Z and numoffset", "data": "01:02:03Z+00:30", "valid": false }, { "description": "an invalid offset indicator", "data": "08:30:06 PST", "valid": false }, { "description": "only RFC3339 not all of ISO 8601 are valid", "data": "01:01:01,1111", "valid": false }, { "description": "no time offset", "data": "12:00:00", "valid": false }, { "description": "no time offset with second fraction", "data": "12:00:00.52", "valid": false }, { "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২:00:00Z", "valid": false }, { "description": "offset not starting with plus or minus", "data": "08:30:06#00:20", "valid": false }, { "description": "contains letters", "data": "ab:cd:ef", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/unknown.json000066400000000000000000000022631477700171100325050ustar00rootroot00000000000000[ { "description": "unknown format", "schema": { "format": "unknown" }, "tests": [ { "description": "unknown formats ignore integers", "data": 12, "valid": true }, { "description": "unknown formats ignore floats", "data": 13.7, "valid": true }, { "description": "unknown formats ignore objects", "data": {}, "valid": true }, { "description": "unknown formats ignore arrays", "data": [], "valid": true }, { "description": "unknown formats ignore booleans", "data": false, "valid": true }, { "description": "unknown formats ignore nulls", "data": null, "valid": true }, { "description": "unknown formats ignore strings", "data": "string", "valid": true } ] } ] uri-reference.json000066400000000000000000000042371477700171100334650ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format[ { "description": "validation of URI References", "schema": { "format": "uri-reference" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid URI", "data": "http://foo.bar/?baz=qux#quux", "valid": true }, { "description": "a valid protocol-relative URI Reference", "data": "//foo.bar/?baz=qux#quux", "valid": true }, { "description": "a valid relative URI Reference", "data": "/abc", "valid": true }, { "description": "an invalid URI Reference", "data": "\\\\WINDOWS\\fileshare", "valid": false }, { "description": "a valid URI Reference", "data": "abc", "valid": true }, { "description": "a valid URI fragment", "data": "#fragment", "valid": true }, { "description": "an invalid URI fragment", "data": "#frag\\ment", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/uri-template.json000066400000000000000000000034311477700171100334140ustar00rootroot00000000000000[ { "description": "format: uri-template", "schema": { "format": "uri-template" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid uri-template", "data": "http://example.com/dictionary/{term:1}/{term}", "valid": true }, { "description": "an invalid uri-template", "data": "http://example.com/dictionary/{term:1}/{term", "valid": false }, { "description": "a valid uri-template without variables", "data": "http://example.com/dictionary", "valid": true }, { "description": "a valid relative uri-template", "data": "dictionary/{term:1}/{term}", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/uri.json000066400000000000000000000110341477700171100316010ustar00rootroot00000000000000[ { "description": "validation of URIs", "schema": { "format": "uri" }, "tests": [ { "description": "all string formats ignore integers", "data": 12, "valid": true }, { "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { "description": "all string formats ignore objects", "data": {}, "valid": true }, { "description": "all string formats ignore arrays", "data": [], "valid": true }, { "description": "all string formats ignore booleans", "data": false, "valid": true }, { "description": "all string formats ignore nulls", "data": null, "valid": true }, { "description": "a valid URL with anchor tag", "data": "http://foo.bar/?baz=qux#quux", "valid": true }, { "description": "a valid URL with anchor tag and parentheses", "data": "http://foo.com/blah_(wikipedia)_blah#cite-1", "valid": true }, { "description": "a valid URL with URL-encoded stuff", "data": "http://foo.bar/?q=Test%20URL-encoded%20stuff", "valid": true }, { "description": "a valid puny-coded URL ", "data": "http://xn--nw2a.xn--j6w193g/", "valid": true }, { "description": "a valid URL with many special characters", "data": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", "valid": true }, { "description": "a valid URL based on IPv4", "data": "http://223.255.255.254", "valid": true }, { "description": "a valid URL with ftp scheme", "data": "ftp://ftp.is.co.za/rfc/rfc1808.txt", "valid": true }, { "description": "a valid URL for a simple text file", "data": "http://www.ietf.org/rfc/rfc2396.txt", "valid": true }, { "description": "a valid URL ", "data": "ldap://[2001:db8::7]/c=GB?objectClass?one", "valid": true }, { "description": "a valid mailto URI", "data": "mailto:John.Doe@example.com", "valid": true }, { "description": "a valid newsgroup URI", "data": "news:comp.infosystems.www.servers.unix", "valid": true }, { "description": "a valid tel URI", "data": "tel:+1-816-555-1212", "valid": true }, { "description": "a valid URN", "data": "urn:oasis:names:specification:docbook:dtd:xml:4.1.2", "valid": true }, { "description": "an invalid protocol-relative URI Reference", "data": "//foo.bar/?baz=qux#quux", "valid": false }, { "description": "an invalid relative URI Reference", "data": "/abc", "valid": false }, { "description": "an invalid URI", "data": "\\\\WINDOWS\\fileshare", "valid": false }, { "description": "an invalid URI though valid URI reference", "data": "abc", "valid": false }, { "description": "an invalid URI with spaces", "data": "http:// shouldfail.com", "valid": false }, { "description": "an invalid URI with spaces and missing scheme", "data": ":// should fail", "valid": false }, { "description": "an invalid URI with comma in scheme", "data": "bar,baz:foo", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/non-bmp-regex.json000066400000000000000000000045361477700171100322010ustar00rootroot00000000000000[ { "description": "Proper UTF-16 surrogate pair handling: pattern", "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", "schema": { "pattern": "^🐲*$" }, "tests": [ { "description": "matches empty", "data": "", "valid": true }, { "description": "matches single", "data": "🐲", "valid": true }, { "description": "matches two", "data": "🐲🐲", "valid": true }, { "description": "doesn't match one", "data": "🐉", "valid": false }, { "description": "doesn't match two", "data": "🐉🐉", "valid": false }, { "description": "doesn't match one ASCII", "data": "D", "valid": false }, { "description": "doesn't match two ASCII", "data": "DD", "valid": false } ] }, { "description": "Proper UTF-16 surrogate pair handling: patternProperties", "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", "schema": { "patternProperties": { "^🐲*$": { "type": "integer" } } }, "tests": [ { "description": "matches empty", "data": { "": 1 }, "valid": true }, { "description": "matches single", "data": { "🐲": 1 }, "valid": true }, { "description": "matches two", "data": { "🐲🐲": 1 }, "valid": true }, { "description": "doesn't match one", "data": { "🐲": "hello" }, "valid": false }, { "description": "doesn't match two", "data": { "🐲🐲": "hello" }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/pattern.json000066400000000000000000000030031477700171100273370ustar00rootroot00000000000000[ { "description": "pattern validation", "schema": {"pattern": "^a*$"}, "tests": [ { "description": "a matching pattern is valid", "data": "aaa", "valid": true }, { "description": "a non-matching pattern is invalid", "data": "abc", "valid": false }, { "description": "ignores booleans", "data": true, "valid": true }, { "description": "ignores integers", "data": 123, "valid": true }, { "description": "ignores floats", "data": 1.0, "valid": true }, { "description": "ignores objects", "data": {}, "valid": true }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores null", "data": null, "valid": true } ] }, { "description": "pattern is not anchored", "schema": {"pattern": "a+"}, "tests": [ { "description": "matches a substring", "data": "xxaayy", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/patternProperties.json000066400000000000000000000120711477700171100314210ustar00rootroot00000000000000[ { "description": "patternProperties validates properties matching a regex", "schema": { "patternProperties": { "f.*o": {"type": "integer"} } }, "tests": [ { "description": "a single valid match is valid", "data": {"foo": 1}, "valid": true }, { "description": "multiple valid matches is valid", "data": {"foo": 1, "foooooo" : 2}, "valid": true }, { "description": "a single invalid match is invalid", "data": {"foo": "bar", "fooooo": 2}, "valid": false }, { "description": "multiple invalid matches is invalid", "data": {"foo": "bar", "foooooo" : "baz"}, "valid": false }, { "description": "ignores arrays", "data": ["foo"], "valid": true }, { "description": "ignores strings", "data": "foo", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "multiple simultaneous patternProperties are validated", "schema": { "patternProperties": { "a*": {"type": "integer"}, "aaa*": {"maximum": 20} } }, "tests": [ { "description": "a single valid match is valid", "data": {"a": 21}, "valid": true }, { "description": "a simultaneous match is valid", "data": {"aaaa": 18}, "valid": true }, { "description": "multiple matches is valid", "data": {"a": 21, "aaaa": 18}, "valid": true }, { "description": "an invalid due to one is invalid", "data": {"a": "bar"}, "valid": false }, { "description": "an invalid due to the other is invalid", "data": {"aaaa": 31}, "valid": false }, { "description": "an invalid due to both is invalid", "data": {"aaa": "foo", "aaaa": 31}, "valid": false } ] }, { "description": "regexes are not anchored by default and are case sensitive", "schema": { "patternProperties": { "[0-9]{2,}": { "type": "boolean" }, "X_": { "type": "string" } } }, "tests": [ { "description": "non recognized members are ignored", "data": { "answer 1": "42" }, "valid": true }, { "description": "recognized members are accounted for", "data": { "a31b": null }, "valid": false }, { "description": "regexes are case sensitive", "data": { "a_x_3": 3 }, "valid": true }, { "description": "regexes are case sensitive, 2", "data": { "a_X_3": 3 }, "valid": false } ] }, { "description": "patternProperties with boolean schemas", "schema": { "patternProperties": { "f.*": true, "b.*": false } }, "tests": [ { "description": "object with property matching schema true is valid", "data": {"foo": 1}, "valid": true }, { "description": "object with property matching schema false is invalid", "data": {"bar": 2}, "valid": false }, { "description": "object with both properties is invalid", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "object with a property matching both true and false is invalid", "data": {"foobar":1}, "valid": false }, { "description": "empty object is valid", "data": {}, "valid": true } ] }, { "description": "patternProperties with null valued instance properties", "schema": { "patternProperties": { "^.*bar$": {"type": "null"} } }, "tests": [ { "description": "allows null values", "data": {"foobar": null}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/properties.json000066400000000000000000000162111477700171100300630ustar00rootroot00000000000000[ { "description": "object properties validation", "schema": { "properties": { "foo": {"type": "integer"}, "bar": {"type": "string"} } }, "tests": [ { "description": "both properties present and valid is valid", "data": {"foo": 1, "bar": "baz"}, "valid": true }, { "description": "one property invalid is invalid", "data": {"foo": 1, "bar": {}}, "valid": false }, { "description": "both properties invalid is invalid", "data": {"foo": [], "bar": {}}, "valid": false }, { "description": "doesn't invalidate other properties", "data": {"quux": []}, "valid": true }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "properties, patternProperties, additionalProperties interaction", "schema": { "properties": { "foo": {"type": "array", "maxItems": 3}, "bar": {"type": "array"} }, "patternProperties": {"f.o": {"minItems": 2}}, "additionalProperties": {"type": "integer"} }, "tests": [ { "description": "property validates property", "data": {"foo": [1, 2]}, "valid": true }, { "description": "property invalidates property", "data": {"foo": [1, 2, 3, 4]}, "valid": false }, { "description": "patternProperty invalidates property", "data": {"foo": []}, "valid": false }, { "description": "patternProperty validates nonproperty", "data": {"fxo": [1, 2]}, "valid": true }, { "description": "patternProperty invalidates nonproperty", "data": {"fxo": []}, "valid": false }, { "description": "additionalProperty ignores property", "data": {"bar": []}, "valid": true }, { "description": "additionalProperty validates others", "data": {"quux": 3}, "valid": true }, { "description": "additionalProperty invalidates others", "data": {"quux": "foo"}, "valid": false } ] }, { "description": "properties with boolean schema", "schema": { "properties": { "foo": true, "bar": false } }, "tests": [ { "description": "no property present is valid", "data": {}, "valid": true }, { "description": "only 'true' property present is valid", "data": {"foo": 1}, "valid": true }, { "description": "only 'false' property present is invalid", "data": {"bar": 2}, "valid": false }, { "description": "both properties present is invalid", "data": {"foo": 1, "bar": 2}, "valid": false } ] }, { "description": "properties with escaped characters", "schema": { "properties": { "foo\nbar": {"type": "number"}, "foo\"bar": {"type": "number"}, "foo\\bar": {"type": "number"}, "foo\rbar": {"type": "number"}, "foo\tbar": {"type": "number"}, "foo\fbar": {"type": "number"} } }, "tests": [ { "description": "object with all numbers is valid", "data": { "foo\nbar": 1, "foo\"bar": 1, "foo\\bar": 1, "foo\rbar": 1, "foo\tbar": 1, "foo\fbar": 1 }, "valid": true }, { "description": "object with strings is invalid", "data": { "foo\nbar": "1", "foo\"bar": "1", "foo\\bar": "1", "foo\rbar": "1", "foo\tbar": "1", "foo\fbar": "1" }, "valid": false } ] }, { "description": "properties with null valued instance properties", "schema": { "properties": { "foo": {"type": "null"} } }, "tests": [ { "description": "allows null values", "data": {"foo": null}, "valid": true } ] }, { "description": "properties whose names are Javascript object property names", "comment": "Ensure JS implementations don't universally consider e.g. __proto__ to always be present in an object.", "schema": { "properties": { "__proto__": {"type": "number"}, "toString": { "properties": { "length": { "type": "string" } } }, "constructor": {"type": "number"} } }, "tests": [ { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true }, { "description": "none of the properties mentioned", "data": {}, "valid": true }, { "description": "__proto__ not valid", "data": { "__proto__": "foo" }, "valid": false }, { "description": "toString not valid", "data": { "toString": { "length": 37 } }, "valid": false }, { "description": "constructor not valid", "data": { "constructor": { "length": 37 } }, "valid": false }, { "description": "all present and valid", "data": { "__proto__": 12, "toString": { "length": "foo" }, "constructor": 37 }, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/propertyNames.json000066400000000000000000000055771477700171100305540ustar00rootroot00000000000000[ { "description": "propertyNames validation", "schema": { "propertyNames": {"maxLength": 3} }, "tests": [ { "description": "all property names valid", "data": { "f": {}, "foo": {} }, "valid": true }, { "description": "some property names invalid", "data": { "foo": {}, "foobar": {} }, "valid": false }, { "description": "object without properties is valid", "data": {}, "valid": true }, { "description": "ignores arrays", "data": [1, 2, 3, 4], "valid": true }, { "description": "ignores strings", "data": "foobar", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "propertyNames validation with pattern", "schema": { "propertyNames": { "pattern": "^a+$" } }, "tests": [ { "description": "matching property names valid", "data": { "a": {}, "aa": {}, "aaa": {} }, "valid": true }, { "description": "non-matching property name is invalid", "data": { "aaA": {} }, "valid": false }, { "description": "object without properties is valid", "data": {}, "valid": true } ] }, { "description": "propertyNames with boolean schema true", "schema": {"propertyNames": true}, "tests": [ { "description": "object with any properties is valid", "data": {"foo": 1}, "valid": true }, { "description": "empty object is valid", "data": {}, "valid": true } ] }, { "description": "propertyNames with boolean schema false", "schema": {"propertyNames": false}, "tests": [ { "description": "object with any properties is invalid", "data": {"foo": 1}, "valid": false }, { "description": "empty object is valid", "data": {}, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/ref.json000066400000000000000000000731561477700171100264560ustar00rootroot00000000000000[ { "description": "root pointer ref", "schema": { "properties": { "foo": {"$ref": "#"} }, "additionalProperties": false }, "tests": [ { "description": "match", "data": {"foo": false}, "valid": true }, { "description": "recursive match", "data": {"foo": {"foo": false}}, "valid": true }, { "description": "mismatch", "data": {"bar": false}, "valid": false }, { "description": "recursive mismatch", "data": {"foo": {"bar": false}}, "valid": false } ] }, { "description": "relative pointer ref to object", "schema": { "properties": { "foo": {"type": "integer"}, "bar": {"$ref": "#/properties/foo"} } }, "tests": [ /*{ "description": "match", "data": {"bar": 3}, "valid": true }, { "description": "mismatch", "data": {"bar": true}, "valid": false }*/ ] }, { "description": "relative pointer ref to array", "schema": { "items": [ {"type": "integer"}, {"$ref": "#/items/0"} ] }, "tests": [ { "description": "match array", "data": [1, 2], "valid": true }, { "description": "mismatch array", "data": [1, "foo"], "valid": false } ] }, { "description": "escaped pointer ref", "schema": { "definitions": { "tilde~field": {"type": "integer"}, "slash/field": {"type": "integer"}, "percent%field": {"type": "integer"} }, "properties": { "tilde": {"$ref": "#/definitions/tilde~0field"}, "slash": {"$ref": "#/definitions/slash~1field"}, "percent": {"$ref": "#/definitions/percent%25field"} } }, "tests": [ { "description": "slash invalid", "data": {"slash": "aoeu"}, "valid": false }, { "description": "tilde invalid", "data": {"tilde": "aoeu"}, "valid": false }, { "description": "percent invalid", "data": {"percent": "aoeu"}, "valid": false }, { "description": "slash valid", "data": {"slash": 123}, "valid": true }, { "description": "tilde valid", "data": {"tilde": 123}, "valid": true }, { "description": "percent valid", "data": {"percent": 123}, "valid": true } ] }, { "description": "nested refs", "schema": { "definitions": { "a": {"type": "integer"}, "b": {"$ref": "#/definitions/a"}, "c": {"$ref": "#/definitions/b"} }, "allOf": [{ "$ref": "#/definitions/c" }] }, "tests": [ { "description": "nested ref valid", "data": 5, "valid": true }, { "description": "nested ref invalid", "data": "a", "valid": false } ] }, { "description": "ref overrides any sibling keywords", "schema": { "definitions": { "reffed": { "type": "array" } }, "properties": { "foo": { "$ref": "#/definitions/reffed", "maxItems": 2 } } }, "tests": [ { "description": "ref valid", "data": { "foo": [] }, "valid": true }, { "description": "ref valid, maxItems ignored", "data": { "foo": [ 1, 2, 3] }, "valid": true }, { "description": "ref invalid", "data": { "foo": "string" }, "valid": false } ] }, { "description": "$ref prevents a sibling $id from changing the base uri", "schema": { "$id": "http://localhost:1234/sibling_id/base/", "definitions": { "foo": { "$id": "http://localhost:1234/sibling_id/foo.json", "type": "string" }, "base_foo": { "$comment": "this canonical uri is http://localhost:1234/sibling_id/base/foo.json", "$id": "foo.json", "type": "number" } }, "allOf": [ { "$comment": "$ref resolves to http://localhost:1234/sibling_id/base/foo.json, not http://localhost:1234/sibling_id/foo.json", "$id": "http://localhost:1234/sibling_id/", "$ref": "foo.json" } ] }, "tests": [ { "description": "$ref resolves to /definitions/base_foo, data does not validate", "data": "a", "valid": false }, { "description": "$ref resolves to /definitions/base_foo, data validates", "data": 1, "valid": true } ] }, { "description": "remote ref, containing refs itself", "schema": {"$ref": "http://json-schema.org/draft-07/schema#"}, "tests": [ { "description": "remote ref valid", "data": {"minLength": 1}, "valid": true }, { "description": "remote ref invalid", "data": {"minLength": -1}, "valid": false } ] }, { "description": "property named $ref that is not a reference", "schema": { "properties": { "$ref": {"type": "string"} } }, "tests": [ { "description": "property named $ref valid", "data": {"$ref": "a"}, "valid": true }, { "description": "property named $ref invalid", "data": {"$ref": 2}, "valid": false } ] }, { "description": "property named $ref, containing an actual $ref", "schema": { "properties": { "$ref": {"$ref": "#/definitions/is-string"} }, "definitions": { "is-string": { "type": "string" } } }, "tests": [ { "description": "property named $ref valid", "data": {"$ref": "a"}, "valid": true }, { "description": "property named $ref invalid", "data": {"$ref": 2}, "valid": false } ] }, { "description": "$ref to boolean schema true", "schema": { "allOf": [{ "$ref": "#/definitions/bool" }], "definitions": { "bool": true } }, "tests": [ { "description": "any value is valid", "data": "foo", "valid": true } ] }, { "description": "$ref to boolean schema false", "schema": { "allOf": [{ "$ref": "#/definitions/bool" }], "definitions": { "bool": false } }, "tests": [ { "description": "any value is invalid", "data": "foo", "valid": false } ] }, { "description": "Recursive references between schemas", "schema": { "$id": "http://localhost:1234/tree", "description": "tree of nodes", "type": "object", "properties": { "meta": {"type": "string"}, "nodes": { "type": "array", "items": {"$ref": "node"} } }, "required": ["meta", "nodes"], "definitions": { "node": { "$id": "http://localhost:1234/node", "description": "node", "type": "object", "properties": { "value": {"type": "number"}, "subtree": {"$ref": "tree"} }, "required": ["value"] } } }, "tests": [ { "description": "valid tree", "data": { "meta": "root", "nodes": [ { "value": 1, "subtree": { "meta": "child", "nodes": [ {"value": 1.1}, {"value": 1.2} ] } }, { "value": 2, "subtree": { "meta": "child", "nodes": [ {"value": 2.1}, {"value": 2.2} ] } } ] }, "valid": true }, { "description": "invalid tree", "data": { "meta": "root", "nodes": [ { "value": 1, "subtree": { "meta": "child", "nodes": [ {"value": "string is invalid"}, {"value": 1.2} ] } }, { "value": 2, "subtree": { "meta": "child", "nodes": [ {"value": 2.1}, {"value": 2.2} ] } } ] }, "valid": false } ] }, { "description": "refs with quote", "schema": { "properties": { "foo\"bar": {"$ref": "#/definitions/foo%22bar"} }, "definitions": { "foo\"bar": {"type": "number"} } }, "tests": [ { "description": "object with numbers is valid", "data": { "foo\"bar": 1 }, "valid": true }, { "description": "object with strings is invalid", "data": { "foo\"bar": "1" }, "valid": false } ] }, { "description": "Location-independent identifier", "schema": { "allOf": [{ "$ref": "#foo" }], "definitions": { "A": { "$id": "#foo", "type": "integer" } } }, "tests": [ { "data": 1, "description": "match", "valid": true }, { "data": "a", "description": "mismatch", "valid": false } ] }, { "description": "Reference an anchor with a non-relative URI", "schema": { "$id": "https://example.com/schema-with-anchor", "allOf": [{ "$ref": "https://example.com/schema-with-anchor#foo" }], "definitions": { "A": { "$id": "#foo", "type": "integer" } } }, "tests": [ { "data": 1, "description": "match", "valid": true }, { "data": "a", "description": "mismatch", "valid": false } ] }, { "description": "Location-independent identifier with base URI change in subschema", "schema": { "$id": "http://localhost:1234/root", "allOf": [{ "$ref": "http://localhost:1234/nested.json#foo" }], "definitions": { "A": { "$id": "nested.json", "definitions": { "B": { "$id": "#foo", "type": "integer" } } } } }, "tests": [ { "data": 1, "description": "match", "valid": true }, { "data": "a", "description": "mismatch", "valid": false } ] }, { "description": "naive replacement of $ref with its destination is not correct", "schema": { "definitions": { "a_string": { "type": "string" } }, "enum": [ { "$ref": "#/definitions/a_string" } ] }, "tests": [ { "description": "do not evaluate the $ref inside the enum, matching any string", "data": "this is a string", "valid": false }, { "description": "do not evaluate the $ref inside the enum, definition exact match", "data": { "type": "string" }, "valid": false }, { "description": "match the enum exactly", "data": { "$ref": "#/definitions/a_string" }, "valid": true } ] }, { "description": "refs with relative uris and defs", "schema": { "$id": "http://example.com/schema-relative-uri-defs1.json", "properties": { "foo": { "$id": "schema-relative-uri-defs2.json", "definitions": { "inner": { "properties": { "bar": { "type": "string" } } } }, "allOf": [ { "$ref": "#/definitions/inner" } ] } }, "allOf": [ { "$ref": "schema-relative-uri-defs2.json" } ] }, "tests": [ { "description": "invalid on inner field", "data": { "foo": { "bar": 1 }, "bar": "a" }, "valid": false }, { "description": "invalid on outer field", "data": { "foo": { "bar": "a" }, "bar": 1 }, "valid": false }, { "description": "valid on both fields", "data": { "foo": { "bar": "a" }, "bar": "a" }, "valid": true } ] }, { "description": "relative refs with absolute uris and defs", "schema": { "$id": "http://example.com/schema-refs-absolute-uris-defs1.json", "properties": { "foo": { "$id": "http://example.com/schema-refs-absolute-uris-defs2.json", "definitions": { "inner": { "properties": { "bar": { "type": "string" } } } }, "allOf": [ { "$ref": "#/definitions/inner" } ] } }, "allOf": [ { "$ref": "schema-refs-absolute-uris-defs2.json" } ] }, "tests": [ { "description": "invalid on inner field", "data": { "foo": { "bar": 1 }, "bar": "a" }, "valid": false }, { "description": "invalid on outer field", "data": { "foo": { "bar": "a" }, "bar": 1 }, "valid": false }, { "description": "valid on both fields", "data": { "foo": { "bar": "a" }, "bar": "a" }, "valid": true } ] }, { "description": "$id must be resolved against nearest parent, not just immediate parent", "schema": { "$id": "http://example.com/a.json", "definitions": { "x": { "$id": "http://example.com/b/c.json", "not": { "definitions": { "y": { "$id": "d.json", "type": "number" } } } } }, "allOf": [ { "$ref": "http://example.com/b/d.json" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] }, { "description": "simple URN base URI with $ref via the URN", "schema": { "$comment": "URIs do not have to have HTTP(s) schemes", "$id": "urn:uuid:deadbeef-1234-ffff-ffff-4321feebdaed", "minimum": 30, "properties": { "foo": {"$ref": "urn:uuid:deadbeef-1234-ffff-ffff-4321feebdaed"} } }, "tests": [ { "description": "valid under the URN IDed schema", "data": {"foo": 37}, "valid": true }, { "description": "invalid under the URN IDed schema", "data": {"foo": 12}, "valid": false } ] }, { "description": "simple URN base URI with JSON pointer", "schema": { "$comment": "URIs do not have to have HTTP(s) schemes", "$id": "urn:uuid:deadbeef-1234-00ff-ff00-4321feebdaed", "properties": { "foo": {"$ref": "#/definitions/bar"} }, "definitions": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with NSS", "schema": { "$comment": "RFC 8141 §2.2", "$id": "urn:example:1/406/47452/2", "properties": { "foo": {"$ref": "#/definitions/bar"} }, "definitions": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with r-component", "schema": { "$comment": "RFC 8141 §2.3.1", "$id": "urn:example:foo-bar-baz-qux?+CCResolve:cc=uk", "properties": { "foo": {"$ref": "#/definitions/bar"} }, "definitions": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with q-component", "schema": { "$comment": "RFC 8141 §2.3.2", "$id": "urn:example:weather?=op=map&lat=39.56&lon=-104.85&datetime=1969-07-21T02:56:15Z", "properties": { "foo": {"$ref": "#/definitions/bar"} }, "definitions": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with URN and JSON pointer ref", "schema": { "$id": "urn:uuid:deadbeef-1234-0000-0000-4321feebdaed", "properties": { "foo": {"$ref": "urn:uuid:deadbeef-1234-0000-0000-4321feebdaed#/definitions/bar"} }, "definitions": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "URN base URI with URN and anchor ref", "schema": { "$id": "urn:uuid:deadbeef-1234-ff00-00ff-4321feebdaed", "properties": { "foo": {"$ref": "urn:uuid:deadbeef-1234-ff00-00ff-4321feebdaed#something"} }, "definitions": { "bar": { "$id": "#something", "type": "string" } } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false } ] }, { "description": "ref to if", "schema": { "allOf": [ {"$ref": "http://example.com/ref/if"}, { "if": { "$id": "http://example.com/ref/if", "type": "integer" } } ] }, "tests": [ { "description": "a non-integer is invalid due to the $ref", "data": "foo", "valid": false }, { "description": "an integer is valid", "data": 12, "valid": true } ] }, { "description": "ref to then", "schema": { "allOf": [ {"$ref": "http://example.com/ref/then"}, { "then": { "$id": "http://example.com/ref/then", "type": "integer" } } ] }, "tests": [ { "description": "a non-integer is invalid due to the $ref", "data": "foo", "valid": false }, { "description": "an integer is valid", "data": 12, "valid": true } ] }, { "description": "ref to else", "schema": { "allOf": [ {"$ref": "http://example.com/ref/else"}, { "else": { "$id": "http://example.com/ref/else", "type": "integer" } } ] }, "tests": [ { "description": "a non-integer is invalid due to the $ref", "data": "foo", "valid": false }, { "description": "an integer is valid", "data": 12, "valid": true } ] }, { "description": "ref with absolute-path-reference", "schema": { "$id": "http://example.com/ref/absref.json", "definitions": { "a": { "$id": "http://example.com/ref/absref/foobar.json", "type": "number" }, "b": { "$id": "http://example.com/absref/foobar.json", "type": "string" } }, "allOf": [ { "$ref": "/absref/foobar.json" } ] }, "tests": [ { "description": "a string is valid", "data": "foo", "valid": true }, { "description": "an integer is invalid", "data": 12, "valid": false } ] }, { "description": "$id with file URI still resolves pointers - *nix", "schema": { "$id": "file:///folder/file.json", "definitions": { "foo": { "type": "number" } }, "allOf": [ { "$ref": "#/definitions/foo" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] }, { "description": "$id with file URI still resolves pointers - windows", "schema": { "$id": "file:///c:/folder/file.json", "definitions": { "foo": { "type": "number" } }, "allOf": [ { "$ref": "#/definitions/foo" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] }, { "description": "empty tokens in $ref json-pointer", "schema": { "definitions": { "": { "definitions": { "": { "type": "number" } } } }, "allOf": [ { "$ref": "#/definitions//definitions/" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/refRemote.json000066400000000000000000000160651477700171100276260ustar00rootroot00000000000000[ { "description": "remote ref", "schema": {"$ref": "http://localhost:1234/integer.json"}, "tests": [ { "description": "remote ref valid", "data": 1, "valid": true }, { "description": "remote ref invalid", "data": "a", "valid": false } ] }, { "description": "fragment within remote ref", "schema": {"$ref": "http://localhost:1234/subSchemas.json#/definitions/integer"}, "tests": [ { "description": "remote fragment valid", "data": 1, "valid": true }, { "description": "remote fragment invalid", "data": "a", "valid": false } ] }, { "description": "ref within remote ref", "schema": { "$ref": "http://localhost:1234/subSchemas.json#/definitions/refToInteger" }, "tests": [ { "description": "ref within ref valid", "data": 1, "valid": true }, { "description": "ref within ref invalid", "data": "a", "valid": false } ] }, { "description": "base URI change", "schema": { "$id": "http://localhost:1234/", "items": { "$id": "baseUriChange/", "items": {"$ref": "folderInteger.json"} } }, "tests": [ { "description": "base URI change ref valid", "data": [[1]], "valid": true }, { "description": "base URI change ref invalid", "data": [["a"]], "valid": false } ] }, { "description": "base URI change - change folder", "schema": { "$id": "http://localhost:1234/scope_change_defs1.json", "type" : "object", "properties": { "list": {"$ref": "#/definitions/baz"} }, "definitions": { "baz": { "$id": "baseUriChangeFolder/", "type": "array", "items": {"$ref": "folderInteger.json"} } } }, "tests": [ { "description": "number is valid", "data": {"list": [1]}, "valid": true }, { "description": "string is invalid", "data": {"list": ["a"]}, "valid": false } ] }, { "description": "base URI change - change folder in subschema", "schema": { "$id": "http://localhost:1234/scope_change_defs2.json", "type" : "object", "properties": { "list": {"$ref": "#/definitions/baz/definitions/bar"} }, "definitions": { "baz": { "$id": "baseUriChangeFolderInSubschema/", "definitions": { "bar": { "type": "array", "items": {"$ref": "folderInteger.json"} } } } } }, "tests": [ { "description": "number is valid", "data": {"list": [1]}, "valid": true }, { "description": "string is invalid", "data": {"list": ["a"]}, "valid": false } ] }, { "description": "root ref in remote ref", "schema": { "$id": "http://localhost:1234/object", "type": "object", "properties": { "name": {"$ref": "name.json#/definitions/orNull"} } }, "tests": [ { "description": "string is valid", "data": { "name": "foo" }, "valid": true }, { "description": "null is valid", "data": { "name": null }, "valid": true }, { "description": "object is invalid", "data": { "name": { "name": null } }, "valid": false } ] }, { "description": "remote ref with ref to definitions", "schema": { "$id": "http://localhost:1234/schema-remote-ref-ref-defs1.json", "allOf": [ { "$ref": "ref-and-definitions.json" } ] }, "tests": [ { "description": "invalid", "data": { "bar": 1 }, "valid": false }, { "description": "valid", "data": { "bar": "a" }, "valid": true } ] }, { "description": "Location-independent identifier in remote ref", "schema": { "$ref": "http://localhost:1234/locationIndependentIdentifierPre2019.json#/definitions/refToInteger" }, "tests": [ { "description": "integer is valid", "data": 1, "valid": true }, { "description": "string is invalid", "data": "foo", "valid": false } ] }, { "description": "retrieved nested refs resolve relative to their URI not $id", "schema": { "$id": "http://localhost:1234/some-id", "properties": { "name": {"$ref": "nested/foo-ref-string.json"} } }, "tests": [ { "description": "number is invalid", "data": { "name": {"foo": 1} }, "valid": false }, { "description": "string is valid", "data": { "name": {"foo": "a"} }, "valid": true } ] }, { "description": "$ref to $ref finds location-independent $id", "schema": { "$ref": "http://localhost:1234/draft7/detached-ref.json#/definitions/foo" }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }, { "description": "non-number is invalid", "data": "a", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/required.json000066400000000000000000000102341477700171100275060ustar00rootroot00000000000000[ { "description": "required validation", "schema": { "properties": { "foo": {}, "bar": {} }, "required": ["foo"] }, "tests": [ { "description": "present required property is valid", "data": {"foo": 1}, "valid": true }, { "description": "non-present required property is invalid", "data": {"bar": 1}, "valid": false }, { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores strings", "data": "", "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true } ] }, { "description": "required default validation", "schema": { "properties": { "foo": {} } }, "tests": [ { "description": "not required by default", "data": {}, "valid": true } ] }, { "description": "required with empty array", "schema": { "properties": { "foo": {} }, "required": [] }, "tests": [ { "description": "property not required", "data": {}, "valid": true } ] }, { "description": "required with escaped characters", "schema": { "required": [ "foo\nbar", "foo\"bar", "foo\\bar", "foo\rbar", "foo\tbar", "foo\fbar" ] }, "tests": [ { "description": "object with all properties present is valid", "data": { "foo\nbar": 1, "foo\"bar": 1, "foo\\bar": 1, "foo\rbar": 1, "foo\tbar": 1, "foo\fbar": 1 }, "valid": true }, { "description": "object with some properties missing is invalid", "data": { "foo\nbar": "1", "foo\"bar": "1" }, "valid": false } ] }, { "description": "required properties whose names are Javascript object property names", "comment": "Ensure JS implementations don't universally consider e.g. __proto__ to always be present in an object.", "schema": { "required": ["__proto__", "toString", "constructor"] }, "tests": [ { "description": "ignores arrays", "data": [], "valid": true }, { "description": "ignores other non-objects", "data": 12, "valid": true }, { "description": "none of the properties mentioned", "data": {}, "valid": false }, { "description": "__proto__ present", "data": { "__proto__": "foo" }, "valid": false }, { "description": "toString present", "data": { "toString": { "length": 37 } }, "valid": false }, { "description": "constructor present", "data": { "constructor": { "length": 37 } }, "valid": false }, { "description": "all present", "data": { "__proto__": 12, "toString": { "length": "foo" }, "constructor": 37 }, "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/type.json000066400000000000000000000321401477700171100266470ustar00rootroot00000000000000[ { "description": "integer type matches integers", "schema": {"type": "integer"}, "tests": [ { "description": "an integer is an integer", "data": 1, "valid": true }, { "description": "a float with zero fractional part is an integer", "data": 1.0, "valid": true }, { "description": "a float is not an integer", "data": 1.1, "valid": false }, { "description": "a string is not an integer", "data": "foo", "valid": false }, { "description": "a string is still not an integer, even if it looks like one", "data": "1", "valid": false }, { "description": "an object is not an integer", "data": {}, "valid": false }, { "description": "an array is not an integer", "data": [], "valid": false }, { "description": "a boolean is not an integer", "data": true, "valid": false }, { "description": "null is not an integer", "data": null, "valid": false } ] }, { "description": "number type matches numbers", "schema": {"type": "number"}, "tests": [ { "description": "an integer is a number", "data": 1, "valid": true }, { "description": "a float with zero fractional part is a number (and an integer)", "data": 1.0, "valid": true }, { "description": "a float is a number", "data": 1.1, "valid": true }, { "description": "a string is not a number", "data": "foo", "valid": false }, { "description": "a string is still not a number, even if it looks like one", "data": "1", "valid": false }, { "description": "an object is not a number", "data": {}, "valid": false }, { "description": "an array is not a number", "data": [], "valid": false }, { "description": "a boolean is not a number", "data": true, "valid": false }, { "description": "null is not a number", "data": null, "valid": false } ] }, { "description": "string type matches strings", "schema": {"type": "string"}, "tests": [ { "description": "1 is not a string", "data": 1, "valid": false }, { "description": "a float is not a string", "data": 1.1, "valid": false }, { "description": "a string is a string", "data": "foo", "valid": true }, { "description": "a string is still a string, even if it looks like a number", "data": "1", "valid": true }, { "description": "an empty string is still a string", "data": "", "valid": true }, { "description": "an object is not a string", "data": {}, "valid": false }, { "description": "an array is not a string", "data": [], "valid": false }, { "description": "a boolean is not a string", "data": true, "valid": false }, { "description": "null is not a string", "data": null, "valid": false } ] }, { "description": "object type matches objects", "schema": {"type": "object"}, "tests": [ { "description": "an integer is not an object", "data": 1, "valid": false }, { "description": "a float is not an object", "data": 1.1, "valid": false }, { "description": "a string is not an object", "data": "foo", "valid": false }, { "description": "an object is an object", "data": {}, "valid": true }, { "description": "an array is not an object", "data": [], "valid": false }, { "description": "a boolean is not an object", "data": true, "valid": false }, { "description": "null is not an object", "data": null, "valid": false } ] }, { "description": "array type matches arrays", "schema": {"type": "array"}, "tests": [ { "description": "an integer is not an array", "data": 1, "valid": false }, { "description": "a float is not an array", "data": 1.1, "valid": false }, { "description": "a string is not an array", "data": "foo", "valid": false }, { "description": "an object is not an array", "data": {}, "valid": false }, { "description": "an array is an array", "data": [], "valid": true }, { "description": "a boolean is not an array", "data": true, "valid": false }, { "description": "null is not an array", "data": null, "valid": false } ] }, { "description": "boolean type matches booleans", "schema": {"type": "boolean"}, "tests": [ { "description": "an integer is not a boolean", "data": 1, "valid": false }, { "description": "zero is not a boolean", "data": 0, "valid": false }, { "description": "a float is not a boolean", "data": 1.1, "valid": false }, { "description": "a string is not a boolean", "data": "foo", "valid": false }, { "description": "an empty string is not a boolean", "data": "", "valid": false }, { "description": "an object is not a boolean", "data": {}, "valid": false }, { "description": "an array is not a boolean", "data": [], "valid": false }, { "description": "true is a boolean", "data": true, "valid": true }, { "description": "false is a boolean", "data": false, "valid": true }, { "description": "null is not a boolean", "data": null, "valid": false } ] }, { "description": "null type matches only the null object", "schema": {"type": "null"}, "tests": [ { "description": "an integer is not null", "data": 1, "valid": false }, { "description": "a float is not null", "data": 1.1, "valid": false }, { "description": "zero is not null", "data": 0, "valid": false }, { "description": "a string is not null", "data": "foo", "valid": false }, { "description": "an empty string is not null", "data": "", "valid": false }, { "description": "an object is not null", "data": {}, "valid": false }, { "description": "an array is not null", "data": [], "valid": false }, { "description": "true is not null", "data": true, "valid": false }, { "description": "false is not null", "data": false, "valid": false }, { "description": "null is null", "data": null, "valid": true } ] }, { "description": "multiple types can be specified in an array", "schema": {"type": ["integer", "string"]}, "tests": [ { "description": "an integer is valid", "data": 1, "valid": true }, { "description": "a string is valid", "data": "foo", "valid": true }, { "description": "a float is invalid", "data": 1.1, "valid": false }, { "description": "an object is invalid", "data": {}, "valid": false }, { "description": "an array is invalid", "data": [], "valid": false }, { "description": "a boolean is invalid", "data": true, "valid": false }, { "description": "null is invalid", "data": null, "valid": false } ] }, { "description": "type as array with one item", "schema": { "type": ["string"] }, "tests": [ { "description": "string is valid", "data": "foo", "valid": true }, { "description": "number is invalid", "data": 123, "valid": false } ] }, { "description": "type: array or object", "schema": { "type": ["array", "object"] }, "tests": [ { "description": "array is valid", "data": [1,2,3], "valid": true }, { "description": "object is valid", "data": {"foo": 123}, "valid": true }, { "description": "number is invalid", "data": 123, "valid": false }, { "description": "string is invalid", "data": "foo", "valid": false }, { "description": "null is invalid", "data": null, "valid": false } ] }, { "description": "type: array, object or null", "schema": { "type": ["array", "object", "null"] }, "tests": [ { "description": "array is valid", "data": [1,2,3], "valid": true }, { "description": "object is valid", "data": {"foo": 123}, "valid": true }, { "description": "null is valid", "data": null, "valid": true }, { "description": "number is invalid", "data": 123, "valid": false }, { "description": "string is invalid", "data": "foo", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/uniqueItems.json000066400000000000000000000333021477700171100301770ustar00rootroot00000000000000[ { "description": "uniqueItems validation", "schema": {"uniqueItems": true}, "tests": [ { "description": "unique array of integers is valid", "data": [1, 2], "valid": true }, { "description": "non-unique array of integers is invalid", "data": [1, 1], "valid": false }, { "description": "non-unique array of more than two integers is invalid", "data": [1, 2, 1], "valid": false }, { "description": "numbers are unique if mathematically unequal", "data": [1.0, 1.00, 1], "valid": false }, { "description": "false is not equal to zero", "data": [0, false], "valid": true }, { "description": "true is not equal to one", "data": [1, true], "valid": true }, { "description": "unique array of strings is valid", "data": ["foo", "bar", "baz"], "valid": true }, { "description": "non-unique array of strings is invalid", "data": ["foo", "bar", "foo"], "valid": false }, { "description": "unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "baz"}], "valid": true }, { "description": "non-unique array of objects is invalid", "data": [{"foo": "bar"}, {"foo": "bar"}], "valid": false }, { "description": "property order of array of objects is ignored", "data": [{"foo": "bar", "bar": "foo"}, {"bar": "foo", "foo": "bar"}], "valid": false }, { "description": "unique array of nested objects is valid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : false}}} ], "valid": true }, { "description": "non-unique array of nested objects is invalid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : true}}} ], "valid": false }, { "description": "unique array of arrays is valid", "data": [["foo"], ["bar"]], "valid": true }, { "description": "non-unique array of arrays is invalid", "data": [["foo"], ["foo"]], "valid": false }, { "description": "non-unique array of more than two arrays is invalid", "data": [["foo"], ["bar"], ["foo"]], "valid": false }, { "description": "1 and true are unique", "data": [1, true], "valid": true }, { "description": "0 and false are unique", "data": [0, false], "valid": true }, { "description": "[1] and [true] are unique", "data": [[1], [true]], "valid": true }, { "description": "[0] and [false] are unique", "data": [[0], [false]], "valid": true }, { "description": "nested [1] and [true] are unique", "data": [[[1], "foo"], [[true], "foo"]], "valid": true }, { "description": "nested [0] and [false] are unique", "data": [[[0], "foo"], [[false], "foo"]], "valid": true }, { "description": "unique heterogeneous types are valid", "data": [{}, [1], true, null, 1, "{}"], "valid": true }, { "description": "non-unique heterogeneous types are invalid", "data": [{}, [1], true, null, {}, 1], "valid": false }, { "description": "different objects are unique", "data": [{"a": 1, "b": 2}, {"a": 2, "b": 1}], "valid": true }, { "description": "objects are non-unique despite key order", "data": [{"a": 1, "b": 2}, {"b": 2, "a": 1}], "valid": false }, { "description": "{\"a\": false} and {\"a\": 0} are unique", "data": [{"a": false}, {"a": 0}], "valid": true }, { "description": "{\"a\": true} and {\"a\": 1} are unique", "data": [{"a": true}, {"a": 1}], "valid": true } ] }, { "description": "uniqueItems with an array of items", "schema": { "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": true }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is not valid", "data": [false, false], "valid": false }, { "description": "[true, true] from items array is not valid", "data": [true, true], "valid": false }, { "description": "unique array extended from [false, true] is valid", "data": [false, true, "foo", "bar"], "valid": true }, { "description": "unique array extended from [true, false] is valid", "data": [true, false, "foo", "bar"], "valid": true }, { "description": "non-unique array extended from [false, true] is not valid", "data": [false, true, "foo", "foo"], "valid": false }, { "description": "non-unique array extended from [true, false] is not valid", "data": [true, false, "foo", "foo"], "valid": false } ] }, { "description": "uniqueItems with an array of items and additionalItems=false", "schema": { "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": true, "additionalItems": false }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is not valid", "data": [false, false], "valid": false }, { "description": "[true, true] from items array is not valid", "data": [true, true], "valid": false }, { "description": "extra items are invalid even if unique", "data": [false, true, null], "valid": false } ] }, { "description": "uniqueItems=false validation", "schema": { "uniqueItems": false }, "tests": [ { "description": "unique array of integers is valid", "data": [1, 2], "valid": true }, { "description": "non-unique array of integers is valid", "data": [1, 1], "valid": true }, { "description": "numbers are unique if mathematically unequal", "data": [1.0, 1.00, 1], "valid": true }, { "description": "false is not equal to zero", "data": [0, false], "valid": true }, { "description": "true is not equal to one", "data": [1, true], "valid": true }, { "description": "unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "baz"}], "valid": true }, { "description": "non-unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "bar"}], "valid": true }, { "description": "unique array of nested objects is valid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : false}}} ], "valid": true }, { "description": "non-unique array of nested objects is valid", "data": [ {"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : true}}} ], "valid": true }, { "description": "unique array of arrays is valid", "data": [["foo"], ["bar"]], "valid": true }, { "description": "non-unique array of arrays is valid", "data": [["foo"], ["foo"]], "valid": true }, { "description": "1 and true are unique", "data": [1, true], "valid": true }, { "description": "0 and false are unique", "data": [0, false], "valid": true }, { "description": "unique heterogeneous types are valid", "data": [{}, [1], true, null, 1], "valid": true }, { "description": "non-unique heterogeneous types are valid", "data": [{}, [1], true, null, {}, 1], "valid": true } ] }, { "description": "uniqueItems=false with an array of items", "schema": { "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": false }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is valid", "data": [false, false], "valid": true }, { "description": "[true, true] from items array is valid", "data": [true, true], "valid": true }, { "description": "unique array extended from [false, true] is valid", "data": [false, true, "foo", "bar"], "valid": true }, { "description": "unique array extended from [true, false] is valid", "data": [true, false, "foo", "bar"], "valid": true }, { "description": "non-unique array extended from [false, true] is valid", "data": [false, true, "foo", "foo"], "valid": true }, { "description": "non-unique array extended from [true, false] is valid", "data": [true, false, "foo", "foo"], "valid": true } ] }, { "description": "uniqueItems=false with an array of items and additionalItems=false", "schema": { "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": false, "additionalItems": false }, "tests": [ { "description": "[false, true] from items array is valid", "data": [false, true], "valid": true }, { "description": "[true, false] from items array is valid", "data": [true, false], "valid": true }, { "description": "[false, false] from items array is valid", "data": [false, false], "valid": true }, { "description": "[true, true] from items array is valid", "data": [true, true], "valid": true }, { "description": "extra items are invalid even if unique", "data": [false, true, null], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/draft7/unknownKeyword.json000066400000000000000000000037421477700171100307400ustar00rootroot00000000000000[ { "description": "$id inside an unknown keyword is not a real identifier", "comment": "the implementation must not be confused by an $id in locations we do not know how to parse", "schema": { "definitions": { "id_in_unknown0": { "not": { "array_of_schemas": [ { "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", "type": "null" } ] } }, "real_id_in_schema": { "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", "type": "string" }, "id_in_unknown1": { "not": { "object_of_schemas": { "foo": { "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", "type": "integer" } } } } }, "anyOf": [ { "$ref": "#/definitions/id_in_unknown0" }, { "$ref": "#/definitions/id_in_unknown1" }, { "$ref": "https://localhost:1234/unknownKeyword/my_identifier.json" } ] }, "tests": [ { "description": "type matches second anyOf, which has a real schema in it", "data": "a string", "valid": true }, { "description": "type matches non-schema in first anyOf", "data": null, "valid": false }, { "description": "type matches non-schema in third anyOf", "data": 1, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/JSON-Schema-Test-Suite/tests/latest000066400000000000000000000000141477700171100250160ustar00rootroot00000000000000draft2020-12jsoncons-1.3.2/test/jsonschema/baseUriChange/000077500000000000000000000000001477700171100211675ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/baseUriChange/folderInteger.json000066400000000000000000000000321477700171100246460ustar00rootroot00000000000000{ "type": "integer" } jsoncons-1.3.2/test/jsonschema/baseUriChangeFolder/000077500000000000000000000000001477700171100223235ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/baseUriChangeFolder/folderInteger.json000066400000000000000000000000321477700171100260020ustar00rootroot00000000000000{ "type": "integer" } jsoncons-1.3.2/test/jsonschema/baseUriChangeFolderInSubschema/000077500000000000000000000000001477700171100244455ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/baseUriChangeFolderInSubschema/folderInteger.json000066400000000000000000000000321477700171100301240ustar00rootroot00000000000000{ "type": "integer" } jsoncons-1.3.2/test/jsonschema/issues/000077500000000000000000000000001477700171100200025ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/issues/draft2019-09/000077500000000000000000000000001477700171100216445ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/issues/draft2019-09/anyof.txt000066400000000000000000000152571477700171100235330ustar00rootroot00000000000000validator_type make_schema_validator(const Json& schema, const compilation_context& context, jsoncons::span keys) { auto new_context = context.update_uris(schema, keys); validator_pointer validator_ptr = nullptr; switch (schema.type()) { case json_type::object_value: { auto it = schema.find("$defs"); if (it != schema.object_range().end()) { for (const auto& def : it->value().object_range()) { std::string sub_keys[] = { "$defs", def.key() }; make_schema_validator(def.value(), new_context, sub_keys); } } it = schema.find("definitions"); if (it != schema.object_range().end()) { for (const auto& def : it->value().object_range()) { std::string sub_keys[] = { "definitions", def.key() }; make_schema_validator(def.value(), new_context, sub_keys); } } auto ref = make_type_validator(schema, new_context); validator_ptr = ref.get(); subschemas_.emplace_back(std::move(ref)); it = schema.find("$anchor"); // If $anchor is found, this schema can be referenced by the id if (it != schema.object_range().end()) { std::string anchor = it->value().template as(); if (!validate_anchor(anchor)) { std::string message("Invalid anchor "); message.append(anchor.data(), anchor.size()); JSONCONS_THROW(schema_error(message)); } schema_location relative("#"+anchor); insert_schema(relative, validator_ptr); if (new_context.get_base_uri().is_absolute()) { schema_location new_uri = relative.resolve(new_context.get_base_uri()); insert_schema(new_uri, validator_ptr); } } for (const auto& uri : new_context.uris()) { insert_schema(uri, validator_ptr); for (const auto& item : schema.object_range()) { insert_unknown_keyword(uri, item.key(), item.value()); // save unknown keywords for later reference } } break; } default: JSONCONS_THROW(schema_error("invalid JSON-type for a schema for " + new_context.get_absolute_uri().string() + ", expected: boolean or object")); break; } return jsoncons::make_unique(validator_ptr); } std::unique_ptr> make_type_validator(const Json& schema, const compilation_context& context) { std::string schema_path = context.get_absolute_uri().string(); Json default_value{jsoncons::null_type()}; std::unique_ptr> enumvalidator{}; std::unique_ptr> const_validator; std::vector combined_validators; std::unique_ptr> conditionalvalidator; std::vector expected_types; std::unique_ptr> unevaluated_properties_validator_ptr; validator_type ref_validator; validator_type recursive_ref_validator; auto it = schema.find("$ref"); if (it != schema.object_range().end()) // this schema is a reference { std::string ref_string = it->value().template as(); schema_location relative(ref_string); auto id = relative.resolve(context.get_base_uri()); auto ref = get_or_create_reference(id); auto ptr = ref.get(); subschemas_.emplace_back(std::move(ref)); ref_validator = jsoncons::make_unique(ptr); } it = schema.find("$recursiveRef"); if (it != schema.object_range().end()) // this schema is a reference { std::string ref_string = it->value().template as(); schema_location relative(ref_string); auto base_uri = context.get_base_uri(uri_anchor_flags::recursive_anchor); auto id = relative.resolve(base_uri); auto ref = get_or_create_reference(id); auto ptr = ref.get(); subschemas_.emplace_back(std::move(ref)); recursive_ref_validator = jsoncons::make_unique(ptr); } std::vector type_mapping{(uint8_t)(json_type::object_value)+1}; std::set known_keywords; it = schema.find("type"); if (it == schema.object_range().end()) { init_type_mapping(type_mapping, "", schema, context, known_keywords); } else { switch (it->value().type()) { case json_type::string_value: { auto type = it->value().template as(); init_type_mapping(type_mapping, type, schema, context, known_keywords); expected_types.emplace_back(std::move(type)); break; } case json_type::array_value: // "type": ["type1", "type2"] { for (const auto& item : it->value().array_range()) { auto type = item.template as(); init_type_mapping(type_mapping, type, schema, context, known_keywords); expected_types.emplace_back(std::move(type)); } break; } } } it = schema.find("anyOf"); if (it != schema.object_range().end()) { combined_validators.emplace_back(make_any_of_validator(it->value(), context)); } return jsoncons::make_unique>(std::move(schema_path), std::move(type_mapping), std::move(combined_validators), std::move(ref_validator), std::move(recursive_ref_validator) ); } std::unique_ptr>> make_any_of_validator(const Json& schema, const compilation_context& context) { std::string schema_path = context.make_schema_path_with("anyOf"); std::vector subschemas; size_t c = 0; for (const auto& subsch : schema.array_range()) { std::string sub_keys[] = { any_of_criterion::key(), std::to_string(c++) }; subschemas.emplace_back(make_schema_validator(subsch, context, sub_keys)); } return jsoncons::make_unique>>(std::move(schema_path), std::move(subschemas)); } jsoncons-1.3.2/test/jsonschema/issues/draft2019-09/issue-anchor.json000066400000000000000000000014021477700171100251340ustar00rootroot00000000000000 [ { "description": "Location-independent identifier with absolute URI", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://localhost:1234/draft2019-09/bar#foo", "$defs": { "A": { "$id": "http://localhost:1234/draft2019-09/bar", "$anchor": "foo", "type": "integer" } } }, "tests": [ { "data": 1, "description": "match", "valid": true }, { "data": "a", "description": "mismatch", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/issues/draft2019-09/issue-not.json000066400000000000000000000016331477700171100244700ustar00rootroot00000000000000[ { "description": "collect annotations inside a 'not', even if collection is disabled", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "not": { "$comment": "this subschema must still produce annotations internally, even though the 'not' will ultimately discard them", "anyOf": [ true, { "properties": { "foo": true } } ], "unevaluatedProperties": false } }, "tests": [ { "description": "unevaluated property", "data": { "bar": 1 }, "valid": true }/*, { "description": "annotations are still collected inside a 'not'", "data": { "foo": 1 }, "valid": false }*/ ] } ] jsoncons-1.3.2/test/jsonschema/issues/draft2019-09/issue-recursiveRef.json000066400000000000000000000030571477700171100263360ustar00rootroot00000000000000[ { "description": "$recursiveRef with no $recursiveAnchor in the initial target schema resource", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:4242/draft2019-09/recursiveRef6/base.json", "$recursiveAnchor": true, "anyOf": [ { "type": "boolean" }, { "type": "object", "additionalProperties": { "$id": "http://localhost:4242/draft2019-09/recursiveRef6/inner.json", "$comment": "there is no $recursiveAnchor: true here, so we do NOT recurse to the base", "anyOf": [ { "type": "integer" }, { "type": "object", "additionalProperties": { "$recursiveRef": "#" } } ] } } ] }, "tests": [ /*{ "description": "leaf node does not match; no recursion", "data": { "foo": true }, "valid": false },*/ { "description": "leaf node matches: recursion uses the inner schema", "data": { "foo": { "bar": 1 } }, "valid": true }/*, { "description": "leaf node does not match: recursion uses the inner schema", "data": { "foo": { "bar": true } }, "valid": false }*/ ] } ] jsoncons-1.3.2/test/jsonschema/issues/draft2019-09/issue-recursiveRef.txt000066400000000000000000000117471477700171100262110ustar00rootroot00000000000000{ "description": "$recursiveRef with $recursiveAnchor: false works like $ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://localhost:4242/draft2019-09/recursiveRef4/schema.json", "$recursiveAnchor": false, "$defs": { "myobject": { "$id": "myobject.json", "$recursiveAnchor": false, "anyOf": [ { "type": "string" }, { "type": "object", "additionalProperties": { "$recursiveRef": "#" } } ] } }, "anyOf": [ { "type": "integer" }, { "$ref": "#/$defs/myobject" } ] }, "tests": [ { "description": "two levels, properties match with inner definition", "data": { "foo": { "bar": "hi" } }, "valid": true } ] } recursive_ref_validator.clone base_uri: << http://localhost:4242/draft2019-09/recursiveRef4/schema.json, schema_path: http://localhost:4242/draft2019-09/recursiveRef4/myobject.json object_schema_validator location::do_resolve_recursive_refs: http://localhost:4242/draft2019-09/recursiveRef4/schema.json#/anyOf/0, 0 base: http://localhost:4242/draft2019-09/recursiveRef4/schema.json, has_recursive_anchor: 0 ref_validator location::do_resolve_recursive_refs: http://localhost:4242/draft2019-09/recursiveRef4/myobject.json base: http://localhost:4242/draft2019-09/recursiveRef4/schema.json#/anyOf/1, has_recursive_anchor: 0 object_schema_validator location::do_resolve_recursive_refs: http://localhost:4242/draft2019-09/recursiveRef4/myobject.json#/anyOf/0, 0 base: http://localhost:4242/draft2019-09/recursiveRef4/myobject.json, has_recursive_anchor: 0 recursive_ref_validator::do_resolve_recursive_refs location: http://localhost:4242/draft2019-09/recursiveRef4/myobject.json base: http://localhost:4242/draft2019-09/recursiveRef4/myobject.json#/anyOf/1/additionalProperties, has_recursive_anchor: 0 location: http://localhost:4242/draft2019-09/recursiveRef4/myobject.json object_schema_validator location::do_resolve_recursive_refs: http://localhost:4242/draft2019-09/recursiveRef4/myobject.json#/anyOf/1/additionalProperties, 0 base: http://localhost:4242/draft2019-09/recursiveRef4/myobject.json#/anyOf/1, has_recursive_anchor: 0 object_schema_validator location::do_resolve_recursive_refs: http://localhost:4242/draft2019-09/recursiveRef4/myobject.json#/anyOf/1, 0 base: http://localhost:4242/draft2019-09/recursiveRef4/myobject.json, has_recursive_anchor: 0 object_schema_validator location::do_resolve_recursive_refs: http://localhost:4242/draft2019-09/recursiveRef4/myobject.json, 0 base: http://localhost:4242/draft2019-09/recursiveRef4/myobject.json, has_recursive_anchor: 0 object_schema_validator location::do_resolve_recursive_refs: http://localhost:4242/draft2019-09/recursiveRef4/schema.json#/anyOf/1, 0 base: http://localhost:4242/draft2019-09/recursiveRef4/schema.json, has_recursive_anchor: 0 object_schema_validator location::do_resolve_recursive_refs: http://localhost:4242/draft2019-09/recursiveRef4/schema.json, 0 base: http://localhost:4242/draft2019-09/recursiveRef4/schema.json, has_recursive_anchor: 0 combining_validator.do_validate keywordLocation: << http://localhost:4242/draft2019-09/recursiveRef4/schema.json#/anyOf, instanceLocation: combining_validator.do_validate keywordLocation: << http://localhost:4242/draft2019-09/recursiveRef4/myobject.json#/anyOf, instanceLocation: recursive_ref_validator.do_validate keywordLocation: << http://localhost:4242/draft2019-09/recursiveRef4/myobject.json, instanceLocation:/foo combining_validator.do_validate keywordLocation: << http://localhost:4242/draft2019-09/recursiveRef4/myobject.json#/anyOf, instanceLocation:/foo recursive_ref_validator.do_validate keywordLocation: << http://localhost:4242/draft2019-09/recursiveRef4/myobject.json, instanceLocation:/foo/bar ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test.exe is a Catch v2.13.10 host application. Run with -? for options ------------------------------------------------------------------------------- jsonschema draft2019-09 tests issues ------------------------------------------------------------------------------- C:\Users\danie\source\repos\jsoncons\test\jsonschema\src\jsonschema_draft201909_tests.cpp(97) ............................................................................... C:\Users\danie\source\repos\jsoncons\test\jsonschema\src\jsonschema_draft201909_tests.cpp(66): FAILED: CHECK_FALSE( test_case["valid"].as() ) with expansion: !true File: ./jsonschema/issues/draft2019-09/issue-recursiveRef.json Test case 1.1: "two levels, properties match with inner definition" Failed: #: No schema matched, but one of them is required to match Nested error: #: Expected 1 integer, found object Nested error: #: No schema matched, but one of them is required to match jsoncons-1.3.2/test/jsonschema/issues/draft2019-09/issue-ref.json000066400000000000000000000013511477700171100244410ustar00rootroot00000000000000[ { "description": "empty tokens in $ref json-pointer", "schema": { "definitions": { "": { "definitions": { "": { "type": "number" } } } }, "allOf": [ { "$ref": "#/definitions//definitions/" } ] }, "tests": [ { "description": "number is valid", "data": 1, "valid": true }/*, { "description": "non-number is invalid", "data": "a", "valid": false }*/ ] } ] jsoncons-1.3.2/test/jsonschema/issues/draft2019-09/issue-ref.txt000066400000000000000000000003051477700171100243050ustar00rootroot00000000000000 File: ./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/ref.json 16 Could not open ./jsonschema/JSON-Schema-Test-Suite/remotes/draft2019-09/schema-relative-uri-defs2.json for schema loading jsoncons-1.3.2/test/jsonschema/issues/draft2019-09/issue-unevaluatedProperties.json000066400000000000000000000034411477700171100302610ustar00rootroot00000000000000[ { "description": "unevaluatedProperties with $recursiveRef", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://example.com/extended-tree", "$recursiveAnchor": true, "$ref": "/tree", "properties": { "name": { "type": "string" } }, "$defs": { "tree": { "$id": "/tree", "$recursiveAnchor": true, "type": "object", "properties": { "node": true, "branches": { "$comment": "unevaluatedProperties comes first so it's more likely to bugs errors with implementations that are sensitive to keyword ordering", "unevaluatedProperties": false, "$recursiveRef": "#" } }, "required": ["node"] } } }, "tests": [ { "description": "with no unevaluated properties", "data": { "name": "a", "node": 1, "branches": { "name": "b", "node": 2 } }, "valid": true }/*, { "description": "with unevaluated properties", "data": { "name": "a", "node": 1, "branches": { "foo": "b", "node": 2 } }, "valid": false }*/ ] } ] jsoncons-1.3.2/test/jsonschema/issues/draft2020-12/000077500000000000000000000000001477700171100216265ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/issues/draft2020-12/DynamicRefKeyword.txt000066400000000000000000000154571477700171100257710ustar00rootroot00000000000000public KeywordConstraint GetConstraint(SchemaConstraint schemaConstraint, IReadOnlyList localConstraints, EvaluationContext context) { var newUri = new Uri(context.Scope.LocalScope, Reference); var newBaseUri = new Uri(newUri.GetLeftPart(UriPartial.Query)); var anchorName = Reference.OriginalString.Split('#').Last(); JsonSchema? targetSchema = null; var targetBase = context.Options.SchemaRegistry.Get(newBaseUri) ?? throw new JsonSchemaException($"Cannot resolve base schema from `{newUri}`"); foreach (var uri in context.Scope.Reverse()) { var scopeRoot = context.Options.SchemaRegistry.Get(uri); if (scopeRoot == null) throw new Exception("This shouldn't happen"); if (scopeRoot is not JsonSchema schemaRoot) throw new Exception("Does OpenAPI use anchors?"); if (!schemaRoot.Anchors.TryGetValue(anchorName, out var anchor) || !anchor.IsDynamic) continue; if (targetBase is JsonSchema targetBaseSchema && context.EvaluatingAs == SpecVersion.Draft202012 && (!targetBaseSchema.Anchors.TryGetValue(anchorName, out var targetAnchor) || !targetAnchor.IsDynamic)) break; targetSchema = anchor.Schema; break; } if (targetSchema == null) { if (JsonPointer.TryParse(newUri.Fragment, out var pointerFragment)) { if (targetBase == null) throw new JsonSchemaException($"Cannot resolve base schema from `{newUri}`"); targetSchema = targetBase.FindSubschema(pointerFragment!, context.Options); } else { var anchorFragment = newUri.Fragment.Substring(1); if (!AnchorKeyword.AnchorPattern.IsMatch(anchorFragment)) throw new JsonSchemaException($"Unrecognized fragment type `{newUri}`"); if (targetBase is JsonSchema targetBaseSchema && targetBaseSchema.Anchors.TryGetValue(anchorFragment, out var anchorDefinition)) targetSchema = anchorDefinition.Schema; } if (targetSchema == null) throw new JsonSchemaException($"Cannot resolve schema `{newUri}`"); } return new KeywordConstraint(Name, (e, c) => Evaluator(e, c, targetSchema)); } Anchors public EvaluationResults Evaluate(JsonNode? root, EvaluationOptions? options = null) { options = EvaluationOptions.From(options ?? EvaluationOptions.Default); // BaseUri may change if $id is present // TODO: remove options.EvaluatingAs var evaluatingAs = DetermineSpecVersion(this, options.SchemaRegistry, options.EvaluateAs); PopulateBaseUris(this, this, BaseUri, options.SchemaRegistry, evaluatingAs, true); var context = new EvaluationContext(options, evaluatingAs, BaseUri); var constraint = BuildConstraint(JsonPointer.Empty, JsonPointer.Empty, JsonPointer.Empty, context.Scope); if (!BoolValue.HasValue) PopulateConstraint(constraint, context); var evaluation = constraint.BuildEvaluation(root, JsonPointer.Empty, JsonPointer.Empty, options); evaluation.Evaluate(context); if (options.AddAnnotationForUnknownKeywords && constraint.UnknownKeywords != null) evaluation.Results.SetAnnotation(_unknownKeywordsAnnotationKey, constraint.UnknownKeywords); var results = evaluation.Results; switch (options.OutputFormat) { case OutputFormat.Flag: results.ToFlag(); break; case OutputFormat.List: results.ToList(); break; case OutputFormat.Hierarchical: break; default: throw new ArgumentOutOfRangeException(); } return results; } private static void PopulateBaseUris(JsonSchema schema, JsonSchema resourceRoot, Uri currentBaseUri, SchemaRegistry registry, SpecVersion evaluatingAs = SpecVersion.Unspecified, bool selfRegister = false) { if (schema.BoolValue.HasValue) return; evaluatingAs = DetermineSpecVersion(schema, registry, evaluatingAs); if (evaluatingAs is SpecVersion.Draft6 or SpecVersion.Draft7 && schema.TryGetKeyword(RefKeyword.Name, out _)) { schema.BaseUri = currentBaseUri; if (selfRegister) registry.RegisterSchema(schema.BaseUri, schema); } else { var idKeyword = (IIdKeyword?)schema.Keywords!.FirstOrDefault(x => x is IIdKeyword); if (idKeyword != null) { if (evaluatingAs <= SpecVersion.Draft7 && idKeyword.Id.OriginalString[0] == '#' && AnchorKeyword.AnchorPattern.IsMatch(idKeyword.Id.OriginalString.Substring(1))) { schema.BaseUri = currentBaseUri; resourceRoot.Anchors[idKeyword.Id.OriginalString.Substring(1)] = (schema, false); } else { schema.IsResourceRoot = true; schema.DeclaredVersion = evaluatingAs; resourceRoot = schema; schema.BaseUri = new Uri(currentBaseUri, idKeyword.Id); registry.RegisterSchema(schema.BaseUri, schema); } } else { schema.BaseUri = currentBaseUri; if (selfRegister) registry.RegisterSchema(schema.BaseUri, schema); } if (schema.TryGetKeyword(AnchorKeyword.Name, out var anchorKeyword)) { resourceRoot.Anchors[anchorKeyword!.Anchor] = (schema, false); } if (schema.TryGetKeyword(DynamicAnchorKeyword.Name, out var dynamicAnchorKeyword)) { resourceRoot.Anchors[dynamicAnchorKeyword!.Value] = (schema, true); } schema.TryGetKeyword(RecursiveAnchorKeyword.Name, out var recursiveAnchorKeyword); if (recursiveAnchorKeyword is { Value: true }) resourceRoot.RecursiveAnchor = schema; } var subschemas = schema.Keywords!.SelectMany(GetSubschemas); foreach (var subschema in subschemas) { PopulateBaseUris(subschema, resourceRoot, schema.BaseUri, registry, evaluatingAs); } } jsoncons-1.3.2/test/jsonschema/issues/draft2020-12/dynamicRef.txt000066400000000000000000000026111477700171100244500ustar00rootroot00000000000000"after leaving a dynamic scope, it is not used by a $dynamicRef" { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://test.json-schema.org/dynamic-ref-leaving-dynamic-scope/main", "if": { "$id": "first_scope", "$defs": { "thingy": { "$comment": "this is first_scope#thingy", "$dynamicAnchor": "thingy", "type": "number" } } }, "then": { "$id": "second_scope", "$ref": "start", "$defs": { "thingy": { "$comment": "this is second_scope#thingy, the final destination of the $dynamicRef", "$dynamicAnchor": "thingy", "type": "null" } } }, "$defs": { "start": { "$comment": "this is the landing spot from $ref", "$id": "start", "$dynamicRef": "inner_scope#thingy" }, "thingy": { "$comment": "this is the first stop for the $dynamicRef", "$id": "inner_scope", "$dynamicAnchor": "thingy", "type": "string" } } } "a string" "string matches /$defs/thingy, but the $dynamicRef does not stop here" false 42 "first_scope is not in dynamic scope for the $dynamicRef" false null "/then/$defs/thingy is the final stop for the $dynamicRef" true jsoncons-1.3.2/test/jsonschema/issues/draft2020-12/issue-521.json000066400000000000000000000017211477700171100241570ustar00rootroot00000000000000[ { "description": "URN base URI with r-component", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "hexaStringOrPositiveInteger": { "description": "A hexadecimal integer in a string (eg: 0xHE770 or HE770) or a positive integer", "anyOf": [ { "type": "string", "pattern": "^(0x)?[0-9a-fA-F]+$" }, { "type": "integer", "minimum": 0 } ] } }, "type": "array", "items": { "$ref": "#/$defs/hexaStringOrPositiveInteger" } } , "tests": [ { "description": "a string is valid", "data": [ "0x7FFFFFFFFFFFFFFF", 9223372036854775807, "0xFFFFFFFFFFFFFFFF", 18446744073709551615, "0x1FFFFFFFFFFFFFFFF", 36893488147419103231, "0xFFFFFFFFFFFFFFFFF", 295147905179352825855 ], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/issues/draft2020-12/issue-dynamicRef.json000066400000000000000000000033651477700171100257370ustar00rootroot00000000000000[ { "description": "A $dynamicRef that initially resolves to a schema with a matching $dynamicAnchor resolves to the first $dynamicAnchor in the dynamic scope", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://test.json-schema.org/relative-dynamic-reference/root", "$dynamicAnchor": "meta", "type": "object", "properties": { "foo": { "const": "pass" } }, "$ref": "extended", "$defs": { "extended": { "$id": "extended", "$dynamicAnchor": "meta", "type": "object", "properties": { "bar": { "$ref": "bar" } } }, "bar": { "$id": "bar", "type": "object", "properties": { "baz": { "$dynamicRef": "extended#meta" } } } } }, "tests": [ /*{ "description": "The recursive part is valid against the root", "data": { "foo": "pass", "bar": { "baz": { "foo": "pass" } } }, "valid": true },*/ { "description": "The recursive part is not valid against the root", "data": { "foo": "pass", "bar": { "baz": { "foo": "fail" } } }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/issues/draft2020-12/issue-dynamicRef.txt000066400000000000000000000027101477700171100255760ustar00rootroot00000000000000A $dynamicRef that initially resolves to a schema with a matching $dynamicAnchor resolves to the first $dynamicAnchor in the dynamic scope { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://test.json-schema.org/relative-dynamic-reference/root", "$dynamicAnchor": "meta", "type": "object", "properties": { "foo": { "const": "pass" } }, "$ref": "extended", "$defs": { "extended": { "$id": "extended", "$dynamicAnchor": "meta", "type": "object", "properties": { "bar": { "$ref": "bar" } } }, "bar": { "$id": "bar", "type": "object", "properties": { "baz": { "$dynamicRef": "extended#meta" } } } } } "The recursive part is not valid against the root" { "foo": "pass", "bar": { "baz": { "foo": "fail" } } } https://test.json-schema.org/relative-dynamic-reference/bar#/properties/baz https://test.json-schema.org/relative-dynamic-reference/bar https://test.json-schema.org/relative-dynamic-reference/extended#/properties/bar https://test.json-schema.org/relative-dynamic-reference/extended#meta https://test.json-schema.org/relative-dynamic-reference/root#/properties/foo https://test.json-schema.org/relative-dynamic-reference/root#meta meta, https://test.json-schema.org/relative-dynamic-reference/extended#meta jsoncons-1.3.2/test/jsonschema/issues/draft2020-12/issue-email.json000066400000000000000000000006331477700171100247400ustar00rootroot00000000000000[ { "description": "validation of e-mail addresses", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "email" }, "tests": [ { "description": "an invalid IPv4-address-literal", "data": "joe.bloggs@[127.0.0.300]", "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/issues/draft2020-12/issue-items.json000066400000000000000000000052411477700171100247720ustar00rootroot00000000000000[ { "description": "items and subitems", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "item": { "type": "array", "items": false, "prefixItems": [ { "$ref": "#/$defs/sub-item" }, { "$ref": "#/$defs/sub-item" } ] }, "sub-item": { "type": "object", "required": ["foo"] } }, "type": "array", "items": false, "prefixItems": [ { "$ref": "#/$defs/item" }, { "$ref": "#/$defs/item" }, { "$ref": "#/$defs/item" } ] }, "tests": [ { "description": "valid items", "data": [ [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": true }, { "description": "too many items", "data": [ [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "too many sub-items", "data": [ [ {"foo": null}, {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "wrong item", "data": [ {"foo": null}, [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "wrong sub-item", "data": [ [ {}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ], "valid": false }, { "description": "fewer items is valid", "data": [ [ {"foo": null} ], [ {"foo": null} ] ], "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/issues/draft2020-12/issue-items.txt000066400000000000000000000020111477700171100246300ustar00rootroot00000000000000{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "item": { "type": "array", "items": false, "prefixItems": [ { "$ref": "#/$defs/sub-item" }, { "$ref": "#/$defs/sub-item" } ] }, "sub-item": { "type": "object", "required": ["foo"] } }, "type": "array", "items": false, "prefixItems": [ { "$ref": "#/$defs/item" }, { "$ref": "#/$defs/item" }, { "$ref": "#/$defs/item" } ] } [ [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ], [ {"foo": null}, {"foo": null} ] ] Failed: /0/0: False schema always fails Failed: /0/1: False schema always fails Failed: /1/0: False schema always fails Failed: /1/1: False schema always fails Failed: /2/0: False schema always fails Failed: /2/1: False schema always fails Failed: /0: False schema always fails Failed: /1: False schema always fails jsoncons-1.3.2/test/jsonschema/issues/draft2020-12/issue-ref.json000066400000000000000000000014311477700171100244220ustar00rootroot00000000000000[ { "description": "URN base URI with r-component", "schema": { "$comment": "RFC 8141 §2.3.1", "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "urn:example:foo-bar-baz-qux?+CCResolve:cc=uk", "properties": { "foo": {"$ref": "#/$defs/bar"} }, "$defs": { "bar": {"type": "string"} } }, "tests": [ { "description": "a string is valid", "data": {"foo": "bar"}, "valid": true }/*, { "description": "a non-string is invalid", "data": {"foo": 12}, "valid": false }*/ ] } ] jsoncons-1.3.2/test/jsonschema/issues/draft2020-12/issue-ref.txt000066400000000000000000000006211477700171100242700ustar00rootroot00000000000000{ "$comment": "RFC 8141 §2.3.1", "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "urn:example:foo-bar-baz-qux?+CCResolve:cc=uk", "properties": { "foo": {"$ref": "#/$defs/bar"} }, "$defs": { "bar": {"type": "string"} } } {"foo": "bar"} Could not open ./jsonschema/JSON-Schema-Test-Suite/remotesexample:foo-bar-baz-qux for schema loading jsoncons-1.3.2/test/jsonschema/issues/draft2020-12/issue-unevaluatedItems.json000066400000000000000000000010271477700171100271660ustar00rootroot00000000000000[ { "description": "unevaluatedItems false", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "unevaluatedItems": false }, "tests": [ /*{ "description": "with no unevaluated items", "data": [], "valid": true },*/ { "description": "with unevaluated items", "data": ["foo"], "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/issues/draft2020-12/issue-unevaluatedProperties.json000066400000000000000000000031171477700171100302430ustar00rootroot00000000000000[ { "description": "schema with if then and else", "schema": { "title": "Person", "type": "object", "if": { "properties": { "firstName": { "type": "string", "description": "The person's first name." }, "age": { "description": "Age in years which must be equal to or greater than zero.", "type": "integer", "minimum": 0 } }, "required": [ "firstName" ] }, "then": { "properties": { "lastName": { "type": "string", "description": "The person's last name." } } }, "else": { "properties": { "surName": { "type": "string", "description": "The person's sur name." } } }, "unevaluatedProperties": false }, "tests": [ { "description": "Data with if then and else", "data": { "age": 18, "surName": "Sur Name" }, "valid": false }/*, { "description": "Data - else schema with one unevaluated property", "data": { "age": 18, "surName": "Sur Name", "unevaluated": true }, "valid": false, "validationMessages": [ "$: property 'age' is not evaluated and the schema does not allow unevaluated properties", "$: property 'unevaluated' is not evaluated and the schema does not allow unevaluated properties" ] }*/ ] } ] jsoncons-1.3.2/test/jsonschema/issues/draft2020-12/issue-unevaluatedProperties.txt000066400000000000000000000031751477700171100301150ustar00rootroot00000000000000{ "title": "Person", "type": "object", "if": { "properties": { "firstName": { "type": "string", "description": "The person's first name." }, "age": { "description": "Age in years which must be equal to or greater than zero.", "type": "integer", "minimum": 0 } }, "required": [ "firstName" ] }, "then": { "properties": { "lastName": { "type": "string", "description": "The person's last name." } } }, "else": { "properties": { "surName": { "type": "string", "description": "The person's sur name." } } }, "unevaluatedProperties": false } {"age": 18,"surName": "Sur Name"} Fail - else schema with one unevaluated property if: age else: age, surName void do_validate(const evaluation_context& context,const Json& instance,const jsonpointer::json_pointer& instance_location,evaluation_results& results,error_reporter& reporter,Json& patch) const final { evaluation_context this_context(context, this->keyword_name()); if (if_val_) { collecting_error_reporter local_reporter; if_val_->validate(this_context, instance, instance_location, results, local_reporter, patch); if (local_reporter.errors.empty()) { if (then_val_) then_val_->validate(this_context, instance, instance_location, results, reporter, patch); } else { if (else_val_) else_val_->validate(this_context, instance, instance_location, results, reporter, patch); } } } jsoncons-1.3.2/test/jsonschema/issues/draft2020-12/issue-uri.json000066400000000000000000000006601477700171100244500ustar00rootroot00000000000000[ { "description": "validation of URIs", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "format": "uri" }, "tests": [ { "description": "a valid URL with many special characters", "data": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", "valid": true } ] } ] jsoncons-1.3.2/test/jsonschema/issues/draft7/000077500000000000000000000000001477700171100211715ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/issues/draft7/issue-520.json000066400000000000000000000150441477700171100235240ustar00rootroot00000000000000[ { "description": "URN base URI with r-component", "schema": { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "logicalapps": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string", "pattern": "^[a-zA-Z]([\\- a-zA-Z0-9])+$", "minLength": 3, "maxLength": 64 }, "listenIP": { "oneOf": [ { "type": "string", "format": "ipv6" }, { "type": "string", "format": "ipv4" } ] }, "forwardPort": { "type": "integer", "minimum": 1, "maximum": 65535 }, "forwardIP": { "type": "array", "items": { "oneOf": [ { "type": "string", "format": "ipv6" }, { "type": "string", "format": "ipv4" } ] }, "uniqueItems": true, "minItems": 1 }, "protocol": { "type": "array", "items": { "enum": [ "TCP", "UDP"] }, "uniqueItems": true, "minItems": 1 }, "serverMode": { "type": "array", "items": { "type": "object", "properties": { "ip": { "type": "array", "items": { "oneOf": [ { "type": "object", "properties": { "net": { "type": "string", "format": "ipv4" }, "mask": { "type": "integer", "minimum": 1, "maximum": 32 } }, "required": [ "net" ] }, { "type": "object", "properties": { "net": { "type": "string", "format": "ipv6" }, "mask": { "type": "integer", "minimum": 1, "maximum": 128 } }, "required": [ "net" ] } ] }, "minItems": 1 }, "port": { "type": "array", "items": { "type": "object", "properties": { "start": { "type": "integer", "minimum": 1, "maximum": 65535 }, "end": { "type": "integer", "minimum": 1, "maximum": 65535 } }, "required": [ "start" ] }, "minItems": 1 }, "interface": { "type": "array", "items": { "type": "string", "pattern": "^[a-zA-Z]([a-zA-Z0-9])+$", "minLength": 3, "maxLength": 32 }, "minItems": 1 } }, "required": [ "port" ] } }, "clientMode": { "type": "array", "items": { "type": "object", "properties": { "ip": { "type": "array", "items": { "oneOf": [ { "type": "object", "properties": { "net": { "type": "string", "format": "ipv4" }, "mask": { "type": "integer", "minimum": 1, "maximum": 32 } }, "required": [ "net" ] }, { "type": "object", "properties": { "net": { "type": "string", "format": "ipv6" }, "mask": { "type": "integer", "minimum": 1, "maximum": 128 } }, "required": [ "net" ] } ] }, "minItems": 1 }, "port": { "type": "array", "items": { "type": "object", "properties": { "start": { "type": "integer", "minimum": 1, "maximum": 65535 }, "end": { "type": "integer", "minimum": 1, "maximum": 65535 } }, "required": [ "start" ] }, "minItems": 1 }, "interface": { "type": "array", "items": { "type": "string", "pattern": "^[a-zA-Z]([a-zA-Z0-9])+$", "minLength": 3, "maxLength": 32 }, "minItems": 1 } }, "required": [ "port" ] } } }, "required": [ "name", "protocol" ] } } }, "required": [ "logicalapps" ] }, "tests": [ { "description": "a string is valid", "data": { "logicalapps": [ { "name": "Email Server", "listenIP": "192.168.1.4", "forwardPort": 7443, "forwardIP": [ "203.34.5.6", "203.45.6.7" ], "protocol": [ "TCP", "UDP" ], "serverMode": [ { "ip": [ { "net": "192.168.1.4" }, { "net": "203.199.224.0", "mask": 24 }, { "net": "172.16.4.5", "mask": 32 }, { "net": "10.34.56.1", "mask": 8 } ], "port": [ { "start": 25 }, { "start": 16328, "end": 32766 } ] }, { "port": [ { "start": 587 } ] } ], "clientMode": [ { "ip": [ { "net": "8.8.8.8" }, { "net": "8.8.4.4" } ], "port": [ { "start": "53" } ] }, { "port": [ { "start": 68 }, { "start": 67 } ], "interface": [ "eth0" ] } ] } ] }, "valid": false } ] } ] jsoncons-1.3.2/test/jsonschema/more_tests/000077500000000000000000000000001477700171100206535ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/more_tests/draft2020-12/000077500000000000000000000000001477700171100224775ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/more_tests/draft2020-12/README000066400000000000000000000002351477700171100233570ustar00rootroot00000000000000unevaluated-tests.json is from https://github.com/networknt/json-schema-validator/tree/master/src/test/resources/schema/unevaluatedTests Apache-2.0 license jsoncons-1.3.2/test/jsonschema/more_tests/draft2020-12/unevaluated-tests.json000066400000000000000000001405401477700171100270530ustar00rootroot00000000000000[ { "description": "schema with a $ref", "schema": { "title": "Person", "type": "object", "definitions": { "address": { "properties": { "residence": { "$ref": "#/definitions/residence", "description": "Residence details where the person lives" }, "city": { "type": "string", "description": "City where the person lives." }, "street": { "type": "string", "description": "street where the person lives." }, "pinCode": { "type": "number", "description": "pincode of street" } }, "unevaluatedProperties": false }, "residence": { "properties": { "flatNumber": { "type": "string" }, "flatName": { "type": "string" }, "landmark": { "type": "string" } }, "unevaluatedProperties": false } }, "properties": { "firstName": { "type": "string", "description": "The person's first name." }, "lastName": { "type": "string", "description": "The person's last name." }, "age": { "description": "Age in years which must be equal to or greater than zero.", "type": "integer", "minimum": 0 }, "address": { "description": "Address of the person.", "$ref": "#/definitions/address" } }, "unevaluatedProperties": false }, "tests": [ { "description": "Basic Success Test", "data": { "firstName": "First Name", "age": 18, "lastName": "Last Name", "address": { "city": "Hyderabad", "pinCode": 500025 } }, "valid": true }, { "description": "Unevaluated Property - Outside $ref", "data": { "firstName": "First Name", "invalid": 18, "lastName": "Last Name", "address": { "city": "Hyderabad", "pinCode": 500025 } }, "valid": false, "validationMessages": [ "$: property 'invalid' is not evaluated and the schema does not allow unevaluated properties" ] }, { "description": "Unevaluated Property - inside $ref", "data": { "firstName": "First Name", "age": 18, "lastName": "Last Name", "address": { "city": "Hyderabad", "pinCode": 500025, "invalid": "invalid" } }, "valid": false, "validationMessages": [ "$.address: property 'invalid' is not evaluated and the schema does not allow unevaluated properties" ] }, { "description": "Unevaluated - multiple properties", "data": { "invalid1": "First Name", "age": 18, "lastName": "Last Name", "address": { "city": "Hyderabad", "pinCode": 500025, "invalid2": "invalid" } }, "valid": false, "validationMessages": [ "$.address: property 'invalid2' is not evaluated and the schema does not allow unevaluated properties" ] }, { "description": "Inside nested $ref", "data": { "firstName": "First Name", "age": 18, "lastName": "Last Name", "address": { "city": "Hyderabad", "pinCode": 500025, "residence": { "invalid": "" } } }, "valid": false, "validationMessages": [ "$.address.residence: property 'invalid' is not evaluated and the schema does not allow unevaluated properties" ] } ] }, { "description": "schema with a oneOf", "schema": { "title": "Person", "type": "object", "properties": { "firstName": { "type": "string", "description": "The person's first name." }, "lastName": { "type": "string", "description": "The person's last name." }, "age": { "description": "Age in years which must be equal to or greater than zero.", "type": "integer", "minimum": 0 }, "vehicle": { "oneOf": [ { "title": "Car", "required": [ "wheels", "headlights" ], "properties": { "wheels": { "type": "string" }, "headlights": { "type": "string" } } }, { "title": "Boat", "required": [ "pontoons" ], "properties": { "pontoons": { "type": "string" } } }, { "title": "Plane", "required": [ "wings" ], "properties": { "wings": { "type": "string" } } } ], "unevaluatedProperties": false }, "unevaluatedProperties": false } }, "tests": [ { "description": "Data with oneOf and one property", "data": { "firstName": "First Name", "age": 18, "lastName": "Last Name", "vehicle": { "pontoons": "pontoons" } }, "valid": true }, { "description": "Data which satisfies 1 oneOf schemas, but fails due to unevaluated prop", "data": { "firstName": "First Name", "age": 18, "lastName": "Last Name", "vehicle": { "pontoons": "pontoons", "wheels": "wheels" } }, "valid": false, "validationMessages": [ "$.vehicle: property 'wheels' is not evaluated and the schema does not allow unevaluated properties" ] }, { "description": "Data which satisfies 2 oneOf schemas", "data": { "firstName": "First Name", "age": 18, "lastName": "Last Name", "vehicle": { "pontoons": "pontoons", "wings": "wings" } }, "valid": false, "validationMessages": [ "$.vehicle: must be valid to one and only one schema, but 2 are valid with indexes '1, 2'", "$.vehicle: required property 'wheels' not found", "$.vehicle: required property 'headlights' not found" ] }, { "description": "Data which satisfies 2 oneOf schemas and an invalid prop", "data": { "firstName": "First Name", "age": 18, "lastName": "Last Name", "vehicle": { "pontoons": "pontoons", "wings": "wings", "invalid": "invalid" } }, "valid": false, "validationMessages": [ "$.vehicle: must be valid to one and only one schema, but 2 are valid with indexes '1, 2'", "$.vehicle: property 'invalid' is not evaluated and the schema does not allow unevaluated properties", "$.vehicle: required property 'wheels' not found", "$.vehicle: required property 'headlights' not found" ] }, { "description": "Data which doesn't satisfy any of oneOf schemas but having an invalid prop", "data": { "firstName": "First Name", "age": 18, "lastName": "Last Name", "vehicle": { "invalid": "invalid" } }, "valid": false, "validationMessages": [ "$.vehicle: must be valid to one and only one schema, but 0 are valid", "$.vehicle: property 'invalid' is not evaluated and the schema does not allow unevaluated properties" ] } ] }, { "description": "schema with a anyOf", "schema": { "title": "Person", "type": "object", "properties": { "firstName": { "type": "string", "description": "The person's first name." }, "lastName": { "type": "string", "description": "The person's last name." }, "age": { "description": "Age in years which must be equal to or greater than zero.", "type": "integer", "minimum": 0 }, "vehicle": { "anyOf": [ { "title": "Car", "required": [ "wheels", "headlights" ], "properties": { "wheels": { "type": "string" }, "headlights": { "type": "string" } } }, { "title": "Boat", "required": [ "pontoons" ], "properties": { "pontoons": { "type": "string" } } }, { "title": "Plane", "required": [ "wings" ], "properties": { "wings": { "type": "string" } } } ], "unevaluatedProperties": false }, "unevaluatedProperties": false } }, "tests": [ { "description": "Data with 1 valid AnyOf", "data": { "firstName": "First Name", "age": 18, "lastName": "Last Name", "vehicle": { "pontoons": "pontoons" } }, "valid": true }, { "description": "Data with 1 AnyOf and 1 unevaluated property", "data": { "firstName": "First Name", "age": 18, "lastName": "Last Name", "vehicle": { "pontoons": "pontoons", "unevaluated": true } }, "valid": false, "validationMessages": [ "$.vehicle: property 'unevaluated' is not evaluated and the schema does not allow unevaluated properties" ] }, { "description": "Data with just unevaluated property", "data": { "firstName": "First Name", "age": 18, "lastName": "Last Name", "vehicle": { "unevaluated": true } }, "valid": false, "validationMessages": [ "$.vehicle: property 'unevaluated' is not evaluated and the schema does not allow unevaluated properties" ] }, { "description": "Data with 2 valid AnyOf and 1 unevaluated property", "data": { "firstName": "First Name", "age": 18, "lastName": "Last Name", "vehicle": { "pontoons": "pontoons", "wings": "wings", "unevaluated": true } }, "valid": false, "validationMessages": [ "$.vehicle: property 'unevaluated' is not evaluated and the schema does not allow unevaluated properties" ] } ] }, { "description": "schema with a allOf", "schema": { "title": "Person", "type": "object", "properties": { "firstName": { "type": "string", "description": "The person's first name." }, "lastName": { "type": "string", "description": "The person's last name." }, "age": { "description": "Age in years which must be equal to or greater than zero.", "type": "integer", "minimum": 0 }, "vehicle": { "allOf": [ { "title": "Car", "required": [ "wheels" ], "properties": { "wheels": { "type": "string" }, "headlights": { "type": "string" } } }, { "title": "Boat", "required": [ "pontoons" ], "properties": { "pontoons": { "type": "string" } } }, { "title": "Plane", "required": [ "wings" ], "properties": { "wings": { "type": "string" } } } ], "unevaluatedProperties": false }, "unevaluatedProperties": false } }, "tests": [ { "description": "Data with allOf", "data": { "firstName": "First Name", "age": 18, "lastName": "Last Name", "vehicle": { "wheels": "wheels", "pontoons": "pontoons", "wings": "wings" } }, "valid": true }, { "description": "Data with invalid allOf and one unevaluated property", "data": { "firstName": "First Name", "age": 18, "lastName": "Last Name", "vehicle": { "wheels": "wheels", "pontoons": "pontoons", "unevaluated": true } }, "valid": false, "validationMessages": [ "$.vehicle: required property 'wings' not found", "$.vehicle: property 'unevaluated' is not evaluated and the schema does not allow unevaluated properties" ] } ] }, { "description": "schema with if then and else", "schema": { "title": "Person", "type": "object", "if": { "properties": { "firstName": { "type": "string", "description": "The person's first name." }, "age": { "description": "Age in years which must be equal to or greater than zero.", "type": "integer", "minimum": 0 } }, "required": [ "firstName" ] }, "then": { "properties": { "lastName": { "type": "string", "description": "The person's last name." } } }, "else": { "properties": { "surName": { "type": "string", "description": "The person's sur name." } } }, "unevaluatedProperties": false }, "tests": [ { "description": "Data with if then and else", "data": { "age": 18, "surName": "Sur Name" }, "valid": false }, { "description": "Data - else schema with one unevaluated property", "data": { "age": 18, "surName": "Sur Name", "unevaluated": true }, "valid": false, "validationMessages": [ "$: property 'age' is not evaluated and the schema does not allow unevaluated properties", "$: property 'unevaluated' is not evaluated and the schema does not allow unevaluated properties" ] } ] }, { "description": "schema with additional properties as object", "schema": { "title": "Person", "type": "object", "properties": { "firstName": { "type": "string", "description": "The person's first name." }, "lastName": { "type": "string", "description": "The person's last name." }, "age": { "description": "Age in years which must be equal to or greater than zero.", "type": "integer", "minimum": 0 } }, "additionalProperties": { "properties": { "location": { "type": "string", "description": "The person's location." } } }, "unevaluatedProperties": false }, "tests": [ { "description": "Data with additional properties as object", "data": { "age": 18, "otherProperty": { "location": "hello" } }, "valid": true } ] }, { "description": "schema with additional properties as type", "schema": { "title": "Person", "type": "object", "properties": { "firstName": { "type": "string", "description": "The person's first name." }, "lastName": { "type": "string", "description": "The person's last name." }, "age": { "description": "Age in years which must be equal to or greater than zero.", "type": "integer", "minimum": 0 } }, "additionalProperties": { "type": "string" }, "unevaluatedProperties": false }, "tests": [ { "description": "Data with additional properties as type", "data": { "age": 18, "otherProperty": "test" }, "valid": true } ] }, { "description": "unevaluatedProperties should not affect sub-schemas", "schema": { "properties": { "foo": {} }, "unevaluatedProperties": false }, "tests": [ { "description": "unevaluated property bar is in sub-schema", "data": { "foo": { "bar": "baz" } }, "valid": true } ] }, { "description": "unevaluatedProperties true", "schema": { "type": "object", "unevaluatedProperties": true }, "tests": [ { "description": "with no unevaluated properties", "data": {}, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo" }, "valid": true } ] }, { "description": "unevaluatedProperties false", "schema": { "type": "object", "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": {}, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo" }, "valid": false } ] }, { "description": "unevaluatedProperties with adjacent properties", "schema": { "type": "object", "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "unevaluatedProperties with adjacent patternProperties", "schema": { "type": "object", "patternProperties": { "^foo": { "type": "string" } }, "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "unevaluatedProperties with adjacent additionalProperties", "schema": { "type": "object", "properties": { "foo": { "type": "string" } }, "additionalProperties": true, "unevaluatedProperties": false }, "tests": [ { "description": "with no additional properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with additional properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true } ] }, { "description": "unevaluatedProperties with nested properties", "schema": { "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "properties": { "bar": { "type": "string" } } } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no additional properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with additional properties", "data": { "foo": "foo", "bar": "bar", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with nested patternProperties", "schema": { "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "patternProperties": { "^bar": { "type": "string" } } } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no additional properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with additional properties", "data": { "foo": "foo", "bar": "bar", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with nested additionalProperties", "schema": { "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "additionalProperties": true } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no additional properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with additional properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true } ] }, { "description": "unevaluatedProperties with nested unevaluatedProperties", "schema": { "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "unevaluatedProperties": true } ], "unevaluatedProperties": { "type": "string", "maxLength": 2 } }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true } ] }, { "description": "unevaluatedProperties with anyOf", "schema": { "type": "object", "properties": { "foo": { "type": "string" } }, "anyOf": [ { "properties": { "bar": { "const": "bar" } }, "required": [ "bar" ] }, { "properties": { "baz": { "const": "baz" } }, "required": [ "baz" ] }, { "properties": { "quux": { "const": "quux" } }, "required": [ "quux" ] } ], "unevaluatedProperties": false }, "tests": [ { "description": "when one matches and has no unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "when one matches and has unevaluated properties", "data": { "foo": "foo", "bar": "bar", "baz": "not-baz" }, "valid": false }, { "description": "when two match and has unevaluated properties", "data": { "foo": "foo", "bar": "bar", "baz": "baz", "quux": "not-quux" }, "valid": false } ] }, { "description": "unevaluatedProperties with oneOf", "schema": { "type": "object", "properties": { "foo": { "type": "string" } }, "oneOf": [ { "properties": { "bar": { "const": "bar" } }, "required": [ "bar" ] }, { "properties": { "baz": { "const": "baz" } }, "required": [ "baz" ] } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar", "quux": "quux" }, "valid": false } ] }, { "description": "unevaluatedProperties with not", "schema": { "type": "object", "properties": { "foo": { "type": "string" } }, "not": { "not": { "properties": { "bar": { "const": "bar" } }, "required": [ "bar" ] } }, "unevaluatedProperties": false }, "tests": [ { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "unevaluatedProperties with if/then/else", "schema": { "type": "object", "if": { "properties": { "foo": { "const": "then" } }, "required": [ "foo" ] }, "then": { "properties": { "bar": { "type": "string" } }, "required": [ "bar" ] }, "else": { "properties": { "baz": { "type": "string" } }, "required": [ "baz" ] }, "unevaluatedProperties": false }, "tests": [ { "description": "when if is true and has no unevaluated properties", "data": { "foo": "then", "bar": "bar" }, "valid": true }, { "description": "when if is true and has unevaluated properties", "data": { "foo": "then", "bar": "bar", "baz": "baz" }, "valid": false }, { "description": "when if is false and has no unevaluated properties", "data": { "baz": "baz" }, "valid": true }, { "description": "when if is false and has unevaluated properties", "data": { "foo": "else", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with if/then/else, then not defined", "schema": { "type": "object", "if": { "properties": { "foo": { "const": "then" } }, "required": [ "foo" ] }, "else": { "properties": { "baz": { "type": "string" } }, "required": [ "baz" ] }, "unevaluatedProperties": false }, "tests": [ { "description": "when if is true and has no unevaluated properties", "data": { "foo": "then", "bar": "bar" }, "valid": false }, { "description": "when if is true and has unevaluated properties", "data": { "foo": "then", "bar": "bar", "baz": "baz" }, "valid": false }, { "description": "when if is false and has no unevaluated properties", "data": { "baz": "baz" }, "valid": true }, { "description": "when if is false and has unevaluated properties", "data": { "foo": "else", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with if/then/else, else not defined", "schema": { "type": "object", "if": { "properties": { "foo": { "const": "then" } }, "required": [ "foo" ] }, "then": { "properties": { "bar": { "type": "string" } }, "required": [ "bar" ] }, "unevaluatedProperties": false }, "tests": [ { "description": "when if is true and has no unevaluated properties", "data": { "foo": "then", "bar": "bar" }, "valid": true }, { "description": "when if is true and has unevaluated properties", "data": { "foo": "then", "bar": "bar", "baz": "baz" }, "valid": false }, { "description": "when if is false and has no unevaluated properties", "data": { "baz": "baz" }, "valid": false }, { "description": "when if is false and has unevaluated properties", "data": { "foo": "else", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties with dependentSchemas", "schema": { "type": "object", "properties": { "foo": { "type": "string" } }, "dependentSchemas": { "foo": { "properties": { "bar": { "const": "bar" } }, "required": [ "bar" ] } }, "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with unevaluated properties", "data": { "bar": "bar" }, "valid": false } ] }, { "description": "unevaluatedProperties with boolean schemas", "schema": { "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ true ], "unevaluatedProperties": false }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with unevaluated properties", "data": { "bar": "bar" }, "valid": false } ] }, { "description": "unevaluatedProperties with $ref", "schema": { "type": "object", "$ref": "#/$defs/bar", "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": false, "$defs": { "bar": { "properties": { "bar": { "type": "string" } } } } }, "tests": [ { "description": "with no unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true }, { "description": "with unevaluated properties", "data": { "foo": "foo", "bar": "bar", "baz": "baz" }, "valid": false } ] }, { "description": "unevaluatedProperties can't see inside cousins", "schema": { "allOf": [ { "properties": { "foo": true } }, { "unevaluatedProperties": false } ] }, "tests": [ { "description": "always fails", "data": { "foo": 1 }, "valid": false } ] }, { "description": "nested unevaluatedProperties, outer false, inner true, properties outside", "schema": { "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "unevaluatedProperties": true } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true } ] }, { "description": "nested unevaluatedProperties, outer false, inner true, properties inside", "schema": { "type": "object", "allOf": [ { "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": true } ], "unevaluatedProperties": false }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": true } ] }, { "description": "nested unevaluatedProperties, outer true, inner false, properties outside", "schema": { "type": "object", "properties": { "foo": { "type": "string" } }, "allOf": [ { "unevaluatedProperties": false } ], "unevaluatedProperties": true }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": false }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "nested unevaluatedProperties, outer true, inner false, properties inside", "schema": { "type": "object", "allOf": [ { "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": false } ], "unevaluatedProperties": true }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "cousin unevaluatedProperties, true and false, true with properties", "schema": { "type": "object", "allOf": [ { "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": true }, { "unevaluatedProperties": false } ] }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": false }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "cousin unevaluatedProperties, true and false, false with properties", "schema": { "type": "object", "allOf": [ { "unevaluatedProperties": true }, { "properties": { "foo": { "type": "string" } }, "unevaluatedProperties": false } ] }, "tests": [ { "description": "with no nested unevaluated properties", "data": { "foo": "foo" }, "valid": true }, { "description": "with nested unevaluated properties", "data": { "foo": "foo", "bar": "bar" }, "valid": false } ] }, { "description": "property is evaluated in an uncle schema to unevaluatedProperties", "comment": "see https://stackoverflow.com/questions/66936884/deeply-nested-unevaluatedproperties-and-their-expectations", "schema": { "type": "object", "properties": { "foo": { "type": "object", "properties": { "bar": { "type": "string" } }, "unevaluatedProperties": false } }, "anyOf": [ { "properties": { "foo": { "properties": { "faz": { "type": "string" } } } } } ] }, "tests": [ { "description": "no extra properties", "data": { "foo": { "bar": "test" } }, "valid": true }, { "description": "uncle keyword evaluation is not significant", "data": { "foo": { "bar": "test", "faz": "test" } }, "valid": false } ] }, { "description": "in-place applicator siblings, allOf has unevaluated", "schema": { "type": "object", "allOf": [ { "properties": { "foo": true }, "unevaluatedProperties": false } ], "anyOf": [ { "properties": { "bar": true } } ] }, "tests": [ { "description": "base case: both properties present", "data": { "foo": 1, "bar": 1 }, "valid": false }, { "description": "in place applicator siblings, bar is missing", "data": { "foo": 1 }, "valid": true }, { "description": "in place applicator siblings, foo is missing", "data": { "bar": 1 }, "valid": false } ] }, { "description": "in-place applicator siblings, anyOf has unevaluated", "schema": { "type": "object", "allOf": [ { "properties": { "foo": true } } ], "anyOf": [ { "properties": { "bar": true }, "unevaluatedProperties": false } ] }, "tests": [ { "description": "base case: both properties present", "data": { "foo": 1, "bar": 1 }, "valid": false }, { "description": "in place applicator siblings, bar is missing", "data": { "foo": 1 }, "valid": false }, { "description": "in place applicator siblings, foo is missing", "data": { "bar": 1 }, "valid": true } ] }, { "description": "unevaluatedProperties + single cyclic ref", "schema": { "type": "object", "properties": { "x": { "$ref": "#" } }, "unevaluatedProperties": false }, "tests": [ { "description": "Empty is valid", "data": {}, "valid": true }, { "description": "Single is valid", "data": { "x": {} }, "valid": true }, { "description": "Unevaluated on 1st level is invalid", "data": { "x": {}, "y": {} }, "valid": false }, { "description": "Nested is valid", "data": { "x": { "x": {} } }, "valid": true }, { "description": "Unevaluated on 2nd level is invalid", "data": { "x": { "x": {}, "y": {} } }, "valid": false }, { "description": "Deep nested is valid", "data": { "x": { "x": { "x": {} } } }, "valid": true }, { "description": "Unevaluated on 3rd level is invalid", "data": { "x": { "x": { "x": {}, "y": {} } } }, "valid": false } ] }, { "description": "unevaluatedProperties + ref inside allOf / oneOf", "schema": { "$defs": { "one": { "properties": { "a": true } }, "two": { "required": [ "x" ], "properties": { "x": true } } }, "allOf": [ { "$ref": "#/$defs/one" }, { "properties": { "b": true } }, { "oneOf": [ { "$ref": "#/$defs/two" }, { "required": [ "y" ], "properties": { "y": true } } ] } ], "unevaluatedProperties": false }, "tests": [ { "description": "Empty is invalid (no x or y)", "data": {}, "valid": false }, { "description": "a and b are invalid (no x or y)", "data": { "a": 1, "b": 1 }, "valid": false }, { "description": "x and y are invalid", "data": { "x": 1, "y": 1 }, "valid": false }, { "description": "a and x are valid", "data": { "a": 1, "x": 1 }, "valid": true }, { "description": "a and y are valid", "data": { "a": 1, "y": 1 }, "valid": true }, { "description": "a and b and x are valid", "data": { "a": 1, "b": 1, "x": 1 }, "valid": true }, { "description": "a and b and y are valid", "data": { "a": 1, "b": 1, "y": 1 }, "valid": true }, { "description": "a and b and x and y are invalid", "data": { "a": 1, "b": 1, "x": 1, "y": 1 }, "valid": false } ] }, { "description": "dynamic evalation inside nested refs", "schema": { "$defs": { "one": { "oneOf": [ { "$ref": "#/$defs/two" }, { "required": [ "b" ], "properties": { "b": true } }, { "required": [ "xx" ], "patternProperties": { "x": true } }, { "required": [ "all" ], "unevaluatedProperties": true } ] }, "two": { "oneOf": [ { "required": [ "c" ], "properties": { "c": true } }, { "required": [ "d" ], "properties": { "d": true } } ] } }, "oneOf": [ { "$ref": "#/$defs/one" }, { "required": [ "a" ], "properties": { "a": true } } ], "unevaluatedProperties": false }, "tests": [ { "description": "Empty is invalid", "data": {}, "valid": false }, { "description": "a is valid", "data": { "a": 1 }, "valid": true }, { "description": "b is valid", "data": { "b": 1 }, "valid": true }, { "description": "c is valid", "data": { "c": 1 }, "valid": true }, { "description": "d is valid", "data": { "d": 1 }, "valid": true }, { "description": "a + b is invalid", "data": { "a": 1, "b": 1 }, "valid": false }, { "description": "a + c is invalid", "data": { "a": 1, "c": 1 }, "valid": false }, { "description": "a + d is invalid", "data": { "a": 1, "d": 1 }, "valid": false }, { "description": "b + c is invalid", "data": { "b": 1, "c": 1 }, "valid": false }, { "description": "b + d is invalid", "data": { "b": 1, "d": 1 }, "valid": false }, { "description": "c + d is invalid", "data": { "c": 1, "d": 1 }, "valid": false }, { "description": "xx + a is invalid", "data": { "xx": 1, "a": 1 }, "valid": false }, { "description": "xx + b is invalid", "data": { "xx": 1, "b": 1 }, "valid": false }, { "description": "xx + c is invalid", "data": { "xx": 1, "c": 1 }, "valid": false }, { "description": "xx + d is invalid", "data": { "xx": 1, "d": 1 }, "valid": false }, { "description": "all is valid", "data": { "all": 1 }, "valid": true }, { "description": "all + foo is valid", "data": { "all": 1, "foo": 1 }, "valid": true }, { "description": "all + a is invalid", "data": { "all": 1, "a": 1 }, "valid": false } ] }, { "description": "unevaluatedProperties with patternProperties and type union", "schema": { "type": "object", "patternProperties": { "^valid_": { "type": ["array", "string"], "items": { "type": "string" } } }, "unevaluatedProperties": false }, "tests": [ { "description": "Not valid key against pattern", "data": { "valid_array": ["array1_value", "array2_value"], "valid_string": "string_value", "invalid_key": "this is an unevaluated properties due to key not matching the pattern" }, "valid": false }, { "description": "Not valid type", "data": { "valid_array": ["array1_value", "array2_value"], "valid_string": "string_value", "valid_key": 5 }, "valid": false }, { "description": "Valid", "data": { "valid_array": ["array1_value", "array2_value"], "valid_string": "string_value" }, "valid": true } ] } ]jsoncons-1.3.2/test/jsonschema/src/000077500000000000000000000000001477700171100172565ustar00rootroot00000000000000jsoncons-1.3.2/test/jsonschema/src/abort_early_tests.cpp000066400000000000000000000063441477700171100235160ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #include #include #include #include using jsoncons::ojson; namespace jsonschema = jsoncons::jsonschema; TEST_CASE("jsonschema stop early tests") { std::string schema_str = R"( { "$id": "https://example.com/arrays.schema.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "description": "A representation of a person, company, organization, or place", "type": "object", "properties": { "fruits": { "type": "array", "items": { "type": "string" } }, "vegetables": { "type": "array", "items": { "$ref": "#/$defs/veggie" } } }, "$defs": { "veggie": { "type": "object", "required": [ "veggieName", "veggieLike" ], "properties": { "veggieName": { "type": "string", "description": "The name of the vegetable." }, "veggieLike": { "type": "boolean", "description": "Do I like this vegetable?" } } } } } )"; std::string data_str = R"( { "fruits": [ "apple", "orange", "pear" ], "vegetables": [ { "veggieName": "potato", "veggieLike": true }, { "veggieName": "broccoli", "veggieLike": "false" }, { "veggieName": "carrot", "veggieLike": false }, { "veggieName": "Swiss Chard" } ] } )"; ojson schema = ojson::parse(schema_str); jsonschema::json_schema compiled = jsonschema::make_json_schema(std::move(schema)); ojson data = ojson::parse(data_str); SECTION("test 1") { std::string expected_str = R"( { "/vegetables/1/veggieLike": "Expected boolean, found string", "/vegetables/3": "Required property 'veggieLike' not found." } )"; ojson expected = ojson::parse(expected_str); ojson results{ jsoncons::json_object_arg }; auto reporter = [&](const jsonschema::validation_message& message) -> jsonschema::walk_result { results.try_emplace(message.instance_location().string(), message.message()); return jsonschema::walk_result::advance; }; compiled.validate(data, reporter); CHECK(expected == results); //std::cout << pretty_print(results) << "\n"; } SECTION("test 2") { std::string expected_str = R"( { "/vegetables/1/veggieLike": "Expected boolean, found string" } )"; ojson expected = ojson::parse(expected_str); ojson results{jsoncons::json_object_arg}; auto reporter = [&](const jsonschema::validation_message& message) -> jsonschema::walk_result { results.try_emplace(message.instance_location().string(), message.message()); return jsonschema::walk_result::abort; }; compiled.validate(data, reporter); CHECK(expected == results); //std::cout << pretty_print(results) << "\n"; } } jsoncons-1.3.2/test/jsonschema/src/custom_message_tests.cpp000066400000000000000000000133521477700171100242260ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #include #include #include #include #include #include #include #include namespace jsonschema = jsoncons::jsonschema; namespace jsonpatch = jsoncons::jsonpatch; TEST_CASE("jsonschema custom message tests") { std::string schema_str = R"( { "type": "object", "properties": { "date": { "type": "string", "format": "date" }, "foo": { "type": "array", "maxItems": 3, "items" : { "type" : "number" }, "errorMessage" : { "maxItems" : "At most 3 numbers are allowed in 'foo'", "type" : "Only numbers are allowed in 'foo'" } }, "bar": { "type": "string", "errorMessage" : "Type of `bar` must be string" } }, "errorMessage": { "format.date": "Date format must be YYYY-MM-DD" } } )"; auto options = jsonschema::evaluation_options{} .enable_custom_error_message(true) .require_format_validation(true); auto schema = jsoncons::json::parse(schema_str); auto compiled = jsonschema::make_json_schema(schema, options); SECTION("test 1") { std::string data_str = R"( { "foo": [1, 2, "three"], "bar": 123, "date": "05-13-1955" } )"; auto data = jsoncons::json::parse(data_str); std::vector messages; auto reporter = [&](const jsonschema::validation_message& msg) -> jsonschema::walk_result { messages.push_back(msg.message()); return jsonschema::walk_result::advance; }; compiled.validate(data, reporter); REQUIRE(3 == messages.size()); CHECK("Type of `bar` must be string" == messages[0]); CHECK("Date format must be YYYY-MM-DD" == messages[1]); CHECK("Only numbers are allowed in 'foo'" == messages[2]); } SECTION("test 2") { std::string data_str = R"( { "foo": [1, 2, "text"], "bar": "Bar 1" } )"; auto data = jsoncons::json::parse(data_str); std::vector messages; auto reporter = [&](const jsonschema::validation_message& msg) -> jsonschema::walk_result { messages.push_back(msg.message()); return jsonschema::walk_result::advance; }; compiled.validate(data, reporter); REQUIRE(1 == messages.size()); CHECK("Only numbers are allowed in 'foo'" == messages[0]); } SECTION("test 3") { std::string data_str = R"( { "foo": [1, 2, "text"], "bar": 123 } )"; auto data = jsoncons::json::parse(data_str); std::vector messages; auto reporter = [&](const jsonschema::validation_message& msg) -> jsonschema::walk_result { messages.push_back(msg.message()); return jsonschema::walk_result::advance; }; compiled.validate(data, reporter); REQUIRE(2 == messages.size()); CHECK("Type of `bar` must be string" == messages[0]); CHECK("Only numbers are allowed in 'foo'" == messages[1]); } SECTION("test 4") { std::string data_str = R"( { "foo": [1, 2, "text", 3], "bar": 123 } )"; auto data = jsoncons::json::parse(data_str); std::vector messages; auto reporter = [&](const jsonschema::validation_message& msg) -> jsonschema::walk_result { messages.push_back(msg.message()); return jsonschema::walk_result::advance; }; compiled.validate(data, reporter); REQUIRE(3 == messages.size()); CHECK("Type of `bar` must be string" == messages[0]); CHECK("Only numbers are allowed in 'foo'" == messages[1]); CHECK("At most 3 numbers are allowed in 'foo'" == messages[2]); } } TEST_CASE("jsonschema custom message with format keyword") { std::string schema_str = R"( { "type": "object", "properties": { "date": { "type": "string", "format": "date" }, "date-time": { "type": "string", "format": "date-time", "errorMessage": "Date-time format must be YYYY-MM-DDThh:mmTZD" } }, "errorMessage": { "format.date": "Date format must be YYYY-MM-DD" } } )"; auto options = jsonschema::evaluation_options{} .enable_custom_error_message(true) .require_format_validation(true); auto schema = jsoncons::json::parse(schema_str); auto compiled = jsonschema::make_json_schema(schema, options); SECTION("test 1") { std::string data_str = R"( { "date": "05-13-1955", "date-time": "1955-05-13" } )"; auto data = jsoncons::json::parse(data_str); std::vector messages; auto reporter = [&](const jsonschema::validation_message& msg) -> jsonschema::walk_result { messages.push_back(msg.message()); return jsonschema::walk_result::advance; }; compiled.validate(data, reporter); REQUIRE(2 == messages.size()); CHECK("Date format must be YYYY-MM-DD" == messages[0]); CHECK("Date-time format must be YYYY-MM-DDThh:mmTZD" == messages[1]); } } jsoncons-1.3.2/test/jsonschema/src/dynamic_ref_tests.cpp000066400000000000000000000201771477700171100234730ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #include #include #include #include #include #include #include #include using jsoncons::json; namespace jsonschema = jsoncons::jsonschema; namespace jsonpatch = jsoncons::jsonpatch; TEST_CASE("jsonschema $recursiveRef tests") { std::string tree_schema_str = R"( { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://example.com/tree", "$recursiveAnchor": true, "type": "object", "properties": { "data": true, "children": { "type": "array", "items": { "$recursiveRef": "#" } } } } )"; std::string strict_tree_schema_str = R"( { "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://example.com/strict-tree", "$recursiveAnchor": true, "$ref": "tree", "unevaluatedProperties": false } )"; json tree_schema = json::parse(tree_schema_str); json strict_tree_schema = json::parse(strict_tree_schema_str); auto resolver = [tree_schema](const jsoncons::uri& uri) { //std::cout << "resolve: " << uri.string() << "\n"; if (uri.string() == "https://example.com/tree") { return tree_schema; } else { return json::null(); } }; jsonschema::json_schema compiled = jsonschema::make_json_schema(strict_tree_schema, resolver); SECTION("instance with misspelled field") { std::string data_str = R"( { "children": [ { "daat": 1 } ] } )"; try { // will throw schema_error if JSON Schema compilation fails // Data json data = json::parse(data_str); std::size_t error_count = 0; auto reporter = [&](const jsonschema::validation_message& /*msg*/) -> jsonschema::walk_result { //std::cout << " Failed: " << "eval_path: " << msg.eval_path().string() << ", schema_location: " << msg.schema_location().string() << ", " << msg.instance_location().string() << ": " << msg.message() << "\n"; //for (const auto& err : msg.nested_errors()) //{ //std::cout << " Nested error: " << err.instance_location().string() << ": " << err.message() << "\n"; //} ++error_count; return jsonschema::walk_result::advance; }; compiled.validate(data, reporter); CHECK(error_count > 0); //std::cout << "error_count: " << error_count << "\n"; } catch (const std::exception& e) { std::cout << e.what() << "\n"; } } } TEST_CASE("jsonschema $dynamicRef tests") { std::string tree_schema_str = R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://example.com/tree", "$dynamicAnchor": "node", "type": "object", "properties": { "data": true, "children": { "type": "array", "items": { "$dynamicRef": "#node" } } } } )"; std::string strict_tree_schema_str = R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://example.com/strict-tree", "$dynamicAnchor": "node", "$ref": "tree", "unevaluatedProperties": false } )"; json tree_schema = json::parse(tree_schema_str); json strict_tree_schema = json::parse(strict_tree_schema_str); auto resolver = [tree_schema](const jsoncons::uri& uri) { //std::cout << "resolve: " << uri.string() << "\n"; if (uri.string() == "https://example.com/tree") { return tree_schema; } else { return json::null(); } }; jsonschema::json_schema compiled = jsonschema::make_json_schema(strict_tree_schema, resolver); SECTION("instance with misspelled field") { std::string data_str = R"( { "children": [ { "daat": 1 } ] } )"; try { // will throw schema_error if JSON Schema compilation fails // Data json data = json::parse(data_str); std::size_t error_count = 0; auto reporter = [&](const jsonschema::validation_message& /*msg*/) -> jsonschema::walk_result { //std::cout << " Failed: " << "eval_path: " << msg.eval_path().string() << ", schema_location: " << msg.schema_location().string() << ", " << msg.instance_location().string() << ": " << msg.message() << "\n"; //for (const auto& err : msg.nested_errors()) //{ //std::cout << " Nested error: " << err.instance_location().string() << ": " << err.message() << "\n"; //} ++error_count; return jsonschema::walk_result::advance; }; compiled.validate(data, reporter); CHECK(error_count > 0); //std::cout << "error_count: " << error_count << "\n"; } catch (const std::exception& e) { std::cout << e.what() << "\n"; } } } TEST_CASE("jsonschema $dynamicRef tests 2") { std::string schema_str = R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://test.json-schema.org/dynamic-ref-leaving-dynamic-scope/main", "if": { "$id": "first_scope", "$defs": { "thingy": { "$comment": "this is first_scope#thingy", "$dynamicAnchor": "thingy", "type": "number" } } }, "then": { "$id": "second_scope", "$ref": "start", "$defs": { "thingy": { "$comment": "this is second_scope#thingy, the final destination of the $dynamicRef", "$dynamicAnchor": "thingy", "type": "null" } } }, "$defs": { "start": { "$comment": "this is the landing spot from $ref", "$id": "start", "$dynamicRef": "inner_scope#thingy" }, "thingy": { "$comment": "this is the first stop for the $dynamicRef", "$id": "inner_scope", "$dynamicAnchor": "thingy", "type": "string" } } } )"; json schema = json::parse(schema_str); jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); SECTION("/then/$defs/thingy is the final stop for the $dynamicRef") { try { // will throw schema_error if JSON Schema compilation fails // Data json data(jsoncons::null_type{}); std::size_t error_count = 0; auto reporter = [&](const jsonschema::validation_message& msg) -> jsonschema::walk_result { std::cout << " Failed: " << "eval_path: " << msg.eval_path().string() << ", schema_location: " << msg.schema_location().string() << ", " << msg.instance_location().string() << ": " << msg.message() << "\n"; for (const auto& err : msg.details()) { std::cout << " Nested error: " << err.instance_location().string() << ": " << err.message() << "\n"; } ++error_count; return jsonschema::walk_result::advance; }; compiled.validate(data, reporter); CHECK(0 == error_count); //std::cout << "error_count: " << error_count << "\n"; } catch (const std::exception& e) { std::cout << e.what() << "\n"; } } } jsoncons-1.3.2/test/jsonschema/src/format_validator_tests.cpp000066400000000000000000000114131477700171100245410ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #include #include #include #include #include #include #include #include namespace jsonschema = jsoncons::jsonschema; TEST_CASE("IP4 format checker tests") { SECTION("dotted quod tests") { CHECK(jsonschema::validate_ipv4_rfc2673(R"(208.116.0.0)")); CHECK(jsonschema::validate_ipv4_rfc2673(R"(208.116.0.0)")); CHECK_FALSE(jsonschema::validate_ipv4_rfc2673(R"(208.116.0)")); } SECTION("b tests") { CHECK(jsonschema::validate_ipv4_rfc2673(R"(b11010000011101)")); } SECTION("o tests") { CHECK(jsonschema::validate_ipv4_rfc2673(R"(064072)")); } SECTION("x tests") { CHECK(jsonschema::validate_ipv4_rfc2673(R"(xd074)")); } } TEST_CASE("IP6 format checker tests") { SECTION("x:x:x:x:x:x:x:x") { CHECK(jsonschema::validate_ipv6_rfc2373(R"(FEDC:BA98:7654:3210:FEDC:BA98:7654:3210)")); CHECK(jsonschema::validate_ipv6_rfc2373(R"(1080:0:0:0:8:800:200C:417A)")); CHECK(jsonschema::validate_ipv6_rfc2373(R"(FF01:0:0:0:0:0:0:101)")); CHECK(jsonschema::validate_ipv6_rfc2373(R"(0:0:0:0:0:0:0:1)")); CHECK(jsonschema::validate_ipv6_rfc2373(R"(0:0:0:0:0:0:0:0)")); } SECTION("compressed") { CHECK(jsonschema::validate_ipv6_rfc2373(R"(1080::8:800:200C:417A)")); CHECK(jsonschema::validate_ipv6_rfc2373(R"(FF01::101)")); CHECK(jsonschema::validate_ipv6_rfc2373(R"(::1)")); CHECK(jsonschema::validate_ipv6_rfc2373(R"(::)")); } SECTION("x:x:x:x:x:x.d.d.d.d") { CHECK(jsonschema::validate_ipv6_rfc2373(R"(0:0:0:0:0:0:13.1.68.3)")); CHECK(jsonschema::validate_ipv6_rfc2373(R"(0:0:0:0:0:FFFF:129.144.52.38)")); } SECTION("compressed d.d.d.d") { CHECK(jsonschema::validate_ipv6_rfc2373(R"(::13.1.68.3)")); CHECK(jsonschema::validate_ipv6_rfc2373(R"(::FFFF:129.144.52.38)")); } } TEST_CASE("time tests") { SECTION("full-time") { CHECK(jsonschema::validate_date_time_rfc3339("23:20:50.52Z", jsonschema::date_time_type::time)); CHECK(jsonschema::validate_date_time_rfc3339("16:39:57-08:00", jsonschema::date_time_type::time)); CHECK(jsonschema::validate_date_time_rfc3339("23:59:60Z", jsonschema::date_time_type::time)); CHECK(jsonschema::validate_date_time_rfc3339("15:59:60-08:00", jsonschema::date_time_type::time)); CHECK(jsonschema::validate_date_time_rfc3339("12:00:27.87+00:20", jsonschema::date_time_type::time)); CHECK(jsonschema::validate_date_time_rfc3339("08:30:06.283185Z", jsonschema::date_time_type::time)); } } TEST_CASE("date tests") { SECTION("dates") { CHECK(jsonschema::validate_date_time_rfc3339("1985-04-12", jsonschema::date_time_type::date)); CHECK(jsonschema::validate_date_time_rfc3339("1996-12-19", jsonschema::date_time_type::date)); CHECK(jsonschema::validate_date_time_rfc3339("1990-12-31", jsonschema::date_time_type::date)); CHECK(jsonschema::validate_date_time_rfc3339("2019-02-28", jsonschema::date_time_type::date)); CHECK(jsonschema::validate_date_time_rfc3339("2020-02-28", jsonschema::date_time_type::date)); // 2020 not a leap year CHECK(jsonschema::is_leap_year(2024)); CHECK(jsonschema::validate_date_time_rfc3339("2024-02-29", jsonschema::date_time_type::date)); CHECK(jsonschema::validate_date_time_rfc3339("1937-01-01", jsonschema::date_time_type::date)); } } TEST_CASE("date-time tests") { SECTION("dates") { CHECK(jsonschema::validate_date_time_rfc3339("1985-04-12T23:20:50.52Z", jsonschema::date_time_type::date_time)); CHECK(jsonschema::validate_date_time_rfc3339("1996-12-19T16:39:57-08:00", jsonschema::date_time_type::date_time)); CHECK(jsonschema::validate_date_time_rfc3339("1990-12-31T23:59:60Z", jsonschema::date_time_type::date_time)); CHECK(jsonschema::validate_date_time_rfc3339("1990-12-31T15:59:60-08:00", jsonschema::date_time_type::date_time)); CHECK(jsonschema::validate_date_time_rfc3339("1937-01-01T12:00:27.87+00:20", jsonschema::date_time_type::date_time)); } } TEST_CASE("email tests") { SECTION("email") { //CHECK(jsonschema::validate_email_rfc5322("pete@silly.test")); CHECK(jsonschema::validate_email_rfc5322("joe.bloggs@example.com")); CHECK_FALSE(jsonschema::validate_email_rfc5322("te..st@example.com")); } } jsoncons-1.3.2/test/jsonschema/src/json_schema_walk_tests.cpp000066400000000000000000000567271477700171100245340ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #include #include #include #include #include #include #include #include using jsoncons::json; using jsoncons::ojson; namespace jsonschema = jsoncons::jsonschema; TEST_CASE("jsonschema walk tests") { std::string schema_str = R"( { "$id": "https://example.com/arrays.schema.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "description": "A representation of a person, company, organization, or place", "type": "object", "properties": { "fruits": { "type": "array", "items": { "type": "string" } }, "vegetables": { "type": "array", "items": { "$ref": "#/$defs/veggie" } } }, "$defs": { "veggie": { "type": "object", "required": [ "veggieName", "veggieLike" ], "properties": { "veggieName": { "type": "string", "description": "The name of the vegetable." }, "veggieLike": { "type": "boolean", "description": "Do I like this vegetable?" } } } } } )"; ojson schema = ojson::parse(schema_str); jsonschema::json_schema compiled = jsonschema::make_json_schema(std::move(schema)); SECTION("walk") { std::string data_str = R"( { "fruits": [ "apple", "orange", "pear" ], "vegetables": [ { "veggieName": "potato", "veggieLike": true }, { "veggieName": "broccoli", "veggieLike": false } ] } )"; // Data ojson data = ojson::parse(data_str); ojson expected = ojson::parse(R"( { "/fruits/0": "string", "/fruits/1": "string", "/fruits/2": "string", "/fruits": "array", "/vegetables/0/veggieName": "string", "/vegetables/0/veggieLike": "boolean", "/vegetables/0": "object", "/vegetables/1/veggieName": "string", "/vegetables/1/veggieLike": "boolean", "/vegetables/1": "object", "/vegetables": "array", "": "object" } )"); ojson result(jsoncons::json_object_arg); auto reporter = [&](const std::string& keyword, const ojson& schema, const jsoncons::uri& /*schema_location*/, const ojson& /*instance*/, const jsoncons::jsonpointer::json_pointer& instance_location) -> jsonschema::walk_result { if (keyword == "type" && schema.is_object()) { auto it = schema.find("type"); if (it != schema.object_range().end()) { result.try_emplace(instance_location.string(), it->value()); //std::cout << instance_location.string() << ": " << it->value() << "\n"; } } return jsonschema::walk_result::advance; }; compiled.walk(data, reporter); CHECK(expected == result); //std::cout << pretty_print(result) << "\n"; } } TEST_CASE("jsonschema with $dynamicRef walk test") { std::string schema_str = R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://test.json-schema.org/dynamic-ref-leaving-dynamic-scope/main", "if": { "$id": "first_scope", "$defs": { "thingy": { "$comment": "this is first_scope#thingy", "$dynamicAnchor": "thingy", "type": "number" } } }, "then": { "$id": "second_scope", "$ref": "start", "$defs": { "thingy": { "$comment": "this is second_scope#thingy, the final destination of the $dynamicRef", "$dynamicAnchor": "thingy", "type": "null" } } }, "$defs": { "start": { "$comment": "this is the landing spot from $ref", "$id": "start", "$dynamicRef": "inner_scope#thingy" }, "thingy": { "$comment": "this is the first stop for the $dynamicRef", "$id": "inner_scope", "$dynamicAnchor": "thingy", "type": "string" } } } )"; ojson schema = ojson::parse(schema_str); jsonschema::json_schema compiled = jsonschema::make_json_schema(std::move(schema)); SECTION("walk") { std::string data_str = R"(null)"; try { // Data ojson data = ojson::parse(data_str); ojson expected = ojson::parse(R"( { "" : "null" } )"); ojson result(jsoncons::json_object_arg); auto reporter = [&](const std::string& keyword, const ojson& schema, const jsoncons::uri& /*schema_location*/, const ojson& /*instance*/, const jsoncons::jsonpointer::json_pointer& instance_location) -> jsonschema::walk_result { if (keyword == "type" && schema.is_object()) { auto it = schema.find("type"); if (it != schema.object_range().end()) { result.try_emplace(instance_location.string(), it->value()); //std::cout << instance_location.string() << ": " << it->value() << "\n"; } } return jsonschema::walk_result::advance; }; compiled.walk(data, reporter); CHECK(expected == result); } catch (const std::exception& e) { std::cout << e.what() << "\n"; } } } TEST_CASE("jsonschema walk keyword test") { SECTION("prefixItems") { try { ojson schema = ojson::parse(R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [ {"type": "integer"}, {"type": "string"} ] } )"); jsonschema::json_schema compiled = jsonschema::make_json_schema(std::move(schema)); ojson data = ojson::parse(R"( [ 1, "foo" ] )"); ojson expected = ojson::parse(R"( { "/0": "integer", "/1": "string" } )"); ojson result(jsoncons::json_object_arg); auto reporter = [&](const std::string& keyword, const ojson& schema, const jsoncons::uri& /*schema_location*/, const ojson& /*instance*/, const jsoncons::jsonpointer::json_pointer& instance_location) -> jsonschema::walk_result { if (keyword == "type") { REQUIRE(schema.is_object()); auto it = schema.find("type"); if (it != schema.object_range().end()) { result.try_emplace(instance_location.string(), it->value()); } } return jsonschema::walk_result::advance; }; compiled.walk(data, reporter); CHECK(expected == result); } catch (const std::exception& e) { std::cout << e.what() << "\n"; } } SECTION("dependentRequired") { try { ojson schema = ojson::parse(R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "dependentRequired": {"bar": ["foo"]} } )"); jsonschema::json_schema compiled = jsonschema::make_json_schema(std::move(schema)); ojson data = ojson::parse(R"( {"foo": 1, "bar": 2} )"); ojson expected = ojson::parse(R"( {"":{"bar":["foo"]}} )"); ojson result(jsoncons::json_object_arg); auto reporter = [&](const std::string& keyword, const ojson& schema, const jsoncons::uri& /*schema_location*/, const ojson& /*instance*/, const jsoncons::jsonpointer::json_pointer& instance_location) -> jsonschema::walk_result { //std::cout << "keyword: " << keyword << "\n"; if (keyword == "dependentRequired") { REQUIRE(schema.is_object()); auto it = schema.find("dependentRequired"); if (it != schema.object_range().end()) { result.try_emplace(instance_location.string(), it->value()); } } return jsonschema::walk_result::advance; }; compiled.walk(data, reporter); CHECK(expected == result); //std::cout << result << "\n"; } catch (const std::exception& e) { std::cout << e.what() << "\n"; } } SECTION("dependentSchemas") { try { ojson schema = ojson::parse(R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "dependentSchemas": { "bar": { "properties": { "foo": {"type": "integer"}, "bar": {"type": "integer"} } } } } )"); jsonschema::json_schema compiled = jsonschema::make_json_schema(std::move(schema)); ojson data = ojson::parse(R"( {"foo": 1, "bar": 2} )"); ojson expected = ojson::parse(R"( {"/bar/foo":"integer","/bar/bar":"integer"} )"); ojson result(jsoncons::json_object_arg); auto reporter = [&](const std::string& keyword, const ojson& schema, const jsoncons::uri& /*schema_location*/, const ojson& /*instance*/, const jsoncons::jsonpointer::json_pointer& instance_location) -> jsonschema::walk_result { //std::cout << "keyword: " << keyword << "\n"; if (keyword == "type") { REQUIRE(schema.is_object()); auto it = schema.find("type"); if (it != schema.object_range().end()) { result.try_emplace(instance_location.string(), it->value()); } } return jsonschema::walk_result::advance; }; compiled.walk(data, reporter); CHECK(expected == result); //std::cout << result << "\n"; } catch (const std::exception& e) { std::cout << e.what() << "\n"; } } SECTION("propertyNames") { try { ojson schema = ojson::parse(R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "propertyNames": {"maxLength": 3} } )"); jsonschema::json_schema compiled = jsonschema::make_json_schema(std::move(schema)); ojson data = ojson::parse(R"( { "f": {}, "foo": {} } )"); ojson expected = ojson::parse(R"( {"/f":3,"/foo":3} )"); ojson result(jsoncons::json_object_arg); auto reporter = [&](const std::string& keyword, const ojson& schema, const jsoncons::uri& /*schema_location*/, const ojson& /*instance*/, const jsoncons::jsonpointer::json_pointer& instance_location) -> jsonschema::walk_result { //std::cout << "keyword: " << keyword << "\n"; if (keyword == "maxLength") { REQUIRE(schema.is_object()); auto it = schema.find("maxLength"); if (it != schema.object_range().end()) { result.try_emplace(instance_location.string(), it->value()); } } return jsonschema::walk_result::advance; }; compiled.walk(data, reporter); CHECK(expected == result); //std::cout << result << "\n"; } catch (const std::exception& e) { std::cout << e.what() << "\n"; } } SECTION("contains") { try { ojson schema = ojson::parse(R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "contains": {"minimum": 5} } )"); jsonschema::json_schema compiled = jsonschema::make_json_schema(std::move(schema)); ojson data = ojson::parse(R"( [3, 4, 5] )"); ojson expected = ojson::parse(R"( {"/0":5,"/1":5,"/2":5} )"); ojson result(jsoncons::json_object_arg); auto reporter = [&](const std::string& keyword, const ojson& schema, const jsoncons::uri& /*schema_location*/, const ojson& /*instance*/, const jsoncons::jsonpointer::json_pointer& instance_location) -> jsonschema::walk_result { //std::cout << "keyword: " << keyword << "\n"; if (keyword == "minimum") { REQUIRE(schema.is_object()); auto it = schema.find("minimum"); if (it != schema.object_range().end()) { result.try_emplace(instance_location.string(), it->value()); } } return jsonschema::walk_result::advance; }; compiled.walk(data, reporter); CHECK(expected == result); //std::cout << result << "\n"; } catch (const std::exception& e) { std::cout << e.what() << "\n"; } } SECTION("patternProperties") { try { ojson schema = ojson::parse(R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "patternProperties": { "f.*o": {"type": "integer"} } } )"); jsonschema::json_schema compiled = jsonschema::make_json_schema(std::move(schema)); ojson data = ojson::parse(R"( {"foo": 1, "foooooo" : 2} )"); ojson expected = ojson::parse(R"( {"/foo":"integer","/foooooo":"integer"} )"); ojson result(jsoncons::json_object_arg); auto reporter = [&](const std::string& keyword, const ojson& schema, const jsoncons::uri& /*schema_location*/, const ojson& /*instance*/, const jsoncons::jsonpointer::json_pointer& instance_location) -> jsonschema::walk_result { //std::cout << "keyword: " << keyword << "\n"; if (keyword == "type") { REQUIRE(schema.is_object()); auto it = schema.find("type"); if (it != schema.object_range().end()) { result.try_emplace(instance_location.string(), it->value()); } } return jsonschema::walk_result::advance; }; compiled.walk(data, reporter); CHECK(expected == result); //std::cout << result << "\n"; } catch (const std::exception& e) { std::cout << e.what() << "\n"; } } SECTION("additionalProperties") { try { ojson schema = ojson::parse(R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": {"type": "boolean"} } )"); jsonschema::json_schema compiled = jsonschema::make_json_schema(std::move(schema)); ojson data = ojson::parse(R"( {"foo" : true} )"); ojson expected = ojson::parse(R"( {"/foo":"boolean"} )"); ojson result(jsoncons::json_object_arg); auto reporter = [&](const std::string& keyword, const ojson& schema, const jsoncons::uri& /*schema_location*/, const ojson& /*instance*/, const jsoncons::jsonpointer::json_pointer& instance_location) -> jsonschema::walk_result { //std::cout << "keyword: " << keyword << "\n"; if (keyword == "type") { REQUIRE(schema.is_object()); auto it = schema.find("type"); if (it != schema.object_range().end()) { result.try_emplace(instance_location.string(), it->value()); } } return jsonschema::walk_result::advance; }; compiled.walk(data, reporter); CHECK(expected == result); //std::cout << result << "\n"; } catch (const std::exception& e) { std::cout << e.what() << "\n"; } } SECTION("additionalItems") { try { ojson schema = ojson::parse(R"( { "$schema": "https://json-schema.org/draft/2019-09/schema", "items": [{}], "additionalItems": {"type": "integer"} } )"); jsonschema::json_schema compiled = jsonschema::make_json_schema(std::move(schema)); ojson data = ojson::parse(R"( [ null, 2, 3, 4 ] )"); ojson expected = ojson::parse(R"( {"/1":"integer","/2":"integer","/3":"integer"} )"); ojson result(jsoncons::json_object_arg); auto reporter = [&](const std::string& keyword, const ojson& schema, const jsoncons::uri& /*schema_location*/, const ojson& /*instance*/, const jsoncons::jsonpointer::json_pointer& instance_location) -> jsonschema::walk_result { //std::cout << "keyword: " << keyword << "\n"; if (keyword == "type") { REQUIRE(schema.is_object()); auto it = schema.find("type"); if (it != schema.object_range().end()) { result.try_emplace(instance_location.string(), it->value()); } } return jsonschema::walk_result::advance; }; compiled.walk(data, reporter); CHECK(expected == result); //std::cout << result << "\n"; } catch (const std::exception& e) { std::cout << e.what() << "\n"; } } SECTION("oneOf") { try { ojson schema = ojson::parse(R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "oneOf": [ { "type": "integer" }, { "minimum": 2 } ] } )"); jsonschema::json_schema compiled = jsonschema::make_json_schema(std::move(schema)); ojson data = ojson::parse(R"( 1 )"); ojson expected = ojson::parse(R"( {"":"integer"} )"); ojson result(jsoncons::json_object_arg); auto reporter = [&](const std::string& keyword, const ojson& schema, const jsoncons::uri& /*schema_location*/, const ojson& /*instance*/, const jsoncons::jsonpointer::json_pointer& instance_location) -> jsonschema::walk_result { //std::cout << "keyword: " << keyword << "\n"; if (keyword == "type") { REQUIRE(schema.is_object()); auto it = schema.find("type"); if (it != schema.object_range().end()) { result.try_emplace(instance_location.string(), it->value()); } } return jsonschema::walk_result::advance; }; compiled.walk(data, reporter); CHECK(expected == result); //std::cout << result << "\n"; } catch (const std::exception& e) { std::cout << e.what() << "\n"; } } SECTION("anyOf") { try { ojson schema = ojson::parse(R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "anyOf": [ { "type": "integer" }, { "minimum": 2 } ] } )"); jsonschema::json_schema compiled = jsonschema::make_json_schema(std::move(schema)); ojson data = ojson::parse(R"( 1 )"); ojson expected = ojson::parse(R"( {"":"integer"} )"); ojson result(jsoncons::json_object_arg); auto reporter = [&](const std::string& keyword, const ojson& schema, const jsoncons::uri& /*schema_location*/, const ojson& /*instance*/, const jsoncons::jsonpointer::json_pointer& instance_location) -> jsonschema::walk_result { //std::cout << "keyword: " << keyword << "\n"; if (keyword == "type") { REQUIRE(schema.is_object()); auto it = schema.find("type"); if (it != schema.object_range().end()) { result.try_emplace(instance_location.string(), it->value()); } } return jsonschema::walk_result::advance; }; compiled.walk(data, reporter); CHECK(expected == result); //std::cout << result << "\n"; } catch (const std::exception& e) { std::cout << e.what() << "\n"; } } SECTION("allOf") { try { ojson schema = ojson::parse(R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "anyOf": [ { "type": "integer" }, { "minimum": 2 } ] } )"); jsonschema::json_schema compiled = jsonschema::make_json_schema(std::move(schema)); ojson data = ojson::parse(R"( 1 )"); ojson expected = ojson::parse(R"( {"":"integer"} )"); ojson result(jsoncons::json_object_arg); auto reporter = [&](const std::string& keyword, const ojson& schema, const jsoncons::uri& /*schema_location*/, const ojson& /*instance*/, const jsoncons::jsonpointer::json_pointer& instance_location) -> jsonschema::walk_result { //std::cout << "keyword: " << keyword << "\n"; if (keyword == "type") { REQUIRE(schema.is_object()); auto it = schema.find("type"); if (it != schema.object_range().end()) { result.try_emplace(instance_location.string(), it->value()); } } return jsonschema::walk_result::advance; }; compiled.walk(data, reporter); CHECK(expected == result); //std::cout << result << "\n"; } catch (const std::exception& e) { std::cout << e.what() << "\n"; } } } jsoncons-1.3.2/test/jsonschema/src/jsonschema_defaults_tests.cpp000066400000000000000000000031431477700171100252260ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #include #include #include #include #include #include #include #include using jsoncons::json; namespace jsonschema = jsoncons::jsonschema; namespace jsonpatch = jsoncons::jsonpatch; TEST_CASE("jsonschema defaults tests") { SECTION("Basic") { json schema = json::parse(R"( { "properties": { "bar": { "type": "string", "minLength": 4, "default": "bad" } } } )"); try { // Data json data = json::parse("{}"); // will throw schema_error if JSON Schema compilation fails jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); // will throw a validation_error when a schema violation happens json patch; compiled.validate(data, patch); std::cout << "patch:\n" << pretty_print(patch) << "\n"; jsonpatch::apply_patch(data, patch); json expected = json::parse(R"( {"bar":"bad"} )"); CHECK(expected == data); } catch (const std::exception& e) { std::cout << e.what() << "\n"; } } } jsoncons-1.3.2/test/jsonschema/src/jsonschema_draft201909_tests.cpp000066400000000000000000000272111477700171100252060ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #include #include #include #include #include #include #include using jsoncons::json; namespace jsonschema = jsoncons::jsonschema; namespace { json resolver(const jsoncons::uri& uri) { //std::cout << uri.string() << ", " << uri.path() << "\n"; std::string pathname = "./jsonschema/JSON-Schema-Test-Suite/remotes"; pathname += std::string(uri.path()); std::fstream is(pathname.c_str()); if (!is) { return json::null(); } return json::parse(is); } void jsonschema_tests(const std::string& fpath, jsonschema::evaluation_options options = jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft201909())) { std::fstream is(fpath); if (!is) { std::cout << "Cannot open file: " << fpath << "\n"; return; } json tests = json::parse(is); //std::cout << pretty_print(tests) << "\n"; int count = 0; for (const auto& test_group : tests.array_range()) { ++count; try { jsonschema::json_schema compiled = jsonschema::make_json_schema(test_group.at("schema"), resolver, options); int count_test = 0; for (const auto& test_case : test_group["tests"].array_range()) { //std::cout << " Test case " << count << "." << count_test << ": " << test_case["description"] << "\n"; ++count_test; std::size_t errors = 0; auto reporter = [&](const jsonschema::validation_message& msg) -> jsonschema::walk_result { ++errors; CHECK_FALSE(test_case["valid"].as()); if (test_case["valid"].as()) { std::cout << " File: " << fpath << "\n"; std::cout << " Test case " << count << "." << count_test << ": " << test_case["description"] << "\n"; std::cout << " Failed: " << msg.instance_location().string() << ": " << msg.message() << "\n"; for (const auto& err : msg.details()) { std::cout << " Nested error: " << err.instance_location().string() << ": " << err.message() << "\n"; } } return jsonschema::walk_result::advance; }; compiled.validate(test_case.at("data"), reporter); if (errors == 0) { CHECK(test_case["valid"].as()); if (!test_case["valid"].as()) { std::cout << " File: " << fpath << "\n"; std::cout << " Test case " << count << "." << count_test << ": " << test_case["description"] << "\n"; } } } } catch (const std::exception& e) { std::cout << " File: " << fpath << " " << count << "\n"; std::cout << e.what() << "\n\n"; CHECK(false); } } } } TEST_CASE("jsonschema draft2019-09 tests") { SECTION("issues") { //jsonschema_tests("./jsonschema/issues/draft2019-09/issue-anchor.json"); //jsonschema_tests("./jsonschema/issues/draft2019-09/issue-not.json"); //jsonschema_tests("./jsonschema/issues/draft2019-09/issue-unevaluatedProperties.json"); //jsonschema_tests("./jsonschema/issues/draft2019-09/issue-ref.json"); //jsonschema_tests("./jsonschema/issues/draft2019-09/issue-recursiveRef.json"); } //#if 0 SECTION("tests") { jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/anchor.json"); // UNCOMMENT METASCHEMA jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/additionalItems.json"); #ifdef JSONCONS_HAS_STD_REGEX jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/additionalProperties.json"); #endif jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/allOf.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/anyOf.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/boolean_schema.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/const.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/contains.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/default.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/defs.json"); // METASCHEMA jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/enum.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/exclusiveMaximum.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/exclusiveMinimum.json"); #ifdef JSONCONS_HAS_STD_REGEX jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/format.json"); #endif jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/if-then-else.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/items.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/infinite-loop-detection.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/maximum.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/maxItems.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/maxLength.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/maxProperties.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/minimum.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/minItems.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/minLength.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/minProperties.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/multipleOf.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/not.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/oneOf.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/recursiveRef.json"); #ifdef JSONCONS_HAS_STD_REGEX jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/pattern.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/patternProperties.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/properties.json"); #endif jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/propertyNames.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/ref.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/refRemote.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/required.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/type.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/unevaluatedProperties.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/unevaluatedItems.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/uniqueItems.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/vocabulary.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/dependencies-compatibility.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft201909()). compatibility_mode(true)); // format tests jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/date.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft201909()). require_format_validation(true)); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/date-time.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft201909()). require_format_validation(true)); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/ecmascript-regex.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/email.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft201909()). require_format_validation(true)); /*jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/hostname.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/idn-email.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/idn-hostname.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/ipv4.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/ipv6.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/iri.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/iri-reference.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/json-pointer.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/regex.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/relative-json-pointer.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/time.json"); */ jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/uri.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft202012()). require_format_validation(true)); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/uri-reference.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft202012()). require_format_validation(true)); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/optional/format/uri-template.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2019-09/content.json"); } //#endif } jsoncons-1.3.2/test/jsonschema/src/jsonschema_draft202012_tests.cpp000066400000000000000000000321241477700171100251670ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #include #include #include #include #include #include #include using jsoncons::json; namespace jsonschema = jsoncons::jsonschema; namespace { json resolver(const jsoncons::uri& uri) { //std::cout << uri.string() << ", " << uri.path() << "\n"; std::string pathname = "./jsonschema/JSON-Schema-Test-Suite/remotes"; pathname += std::string(uri.path()); std::fstream is(pathname.c_str()); if (!is) { return json::null(); } return json::parse(is); } void jsonschema_tests(const std::string& fpath, jsonschema::evaluation_options options = jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft202012())) { std::fstream is(fpath); if (!is) { std::cout << "Cannot open file: " << fpath << "\n"; return; } json tests = json::parse(is); //std::cout << pretty_print(tests) << "\n"; int count = 0; for (const auto& test_group : tests.array_range()) { ++count; try { jsonschema::json_schema compiled = jsonschema::make_json_schema(test_group.at("schema"), resolver, options); int count_test = 0; for (const auto& test_case : test_group["tests"].array_range()) { //std::cout << " Test case " << count << "." << count_test << ": " << test_case["description"] << "\n"; ++count_test; std::size_t errors = 0; auto reporter = [&](const jsonschema::validation_message& msg) -> jsonschema::walk_result { ++errors; CHECK_FALSE(test_case["valid"].as()); if (test_case["valid"].as()) { std::cout << " File: " << fpath << "\n"; std::cout << " Test case " << count << "." << count_test << ": " << test_case["description"] << "\n"; std::cout << " Failed: " << msg.instance_location().string() << ": " << msg.message() << "\n"; for (const auto& err : msg.details()) { std::cout << " Nested error: " << err.instance_location().string() << ": " << err.message() << "\n"; } } return jsonschema::walk_result::advance; }; compiled.validate(test_case.at("data"), reporter); if (errors == 0) { CHECK(test_case["valid"].as()); if (!test_case["valid"].as()) { std::cout << " File: " << fpath << "\n"; std::cout << " Test case " << count << "." << count_test << ": " << test_case["description"] << "\n"; } } } } catch (const std::exception& e) { std::cout << " File: " << fpath << " " << count << "\n"; std::cout << e.what() << "\n\n"; CHECK(false); } } } } TEST_CASE("jsonschema draft2020-12 tests") { SECTION("issues") { //jsonschema_tests("./jsonschema/issues/draft2020-12/issue-uri.json", // jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft202012()). // require_format_validation(true)); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/uri.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft202012()). require_format_validation(true)); } SECTION("more_tests") { // unevaluated-tests.json is from https://github.com/networknt/json-schema-validator/tree/master/src/test/resources/schema/unevaluatedTests //jsonschema_tests("./jsonschema/more_tests/draft2020-12/unevaluated-tests.json", // jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft202012()). // compatibility_mode(true)); } SECTION("tests") { jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/anchor.json"); #ifdef JSONCONS_HAS_STD_REGEX jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/additionalProperties.json"); #endif jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/allOf.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/anyOf.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/boolean_schema.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/const.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/contains.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/default.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/defs.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/dynamicRef.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/enum.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/exclusiveMaximum.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/exclusiveMinimum.json"); #ifdef JSONCONS_HAS_STD_REGEX jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/format.json"); #endif jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/if-then-else.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/infinite-loop-detection.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/items.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/maximum.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/maxItems.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/maxLength.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/maxProperties.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/minimum.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/minItems.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/minLength.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/minProperties.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/multipleOf.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/not.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/oneOf.json"); #ifdef JSONCONS_HAS_STD_REGEX jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/pattern.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/patternProperties.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/properties.json"); #endif jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/propertyNames.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/ref.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/refRemote.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/required.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/type.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/unevaluatedProperties.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/unevaluatedItems.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/uniqueItems.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/vocabulary.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/dependencies-compatibility.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft202012()). compatibility_mode(true)); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/bignum.json"); // format tests jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/date.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft202012()). require_format_validation(true)); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/date-time.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft202012()). require_format_validation(true)); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/ecmascript-regex.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/email.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft202012()). require_format_validation(true)); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/hostname.json", // jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft202012()). // require_format_validation(true)); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/idn-email.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/idn-hostname.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/ipv4.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft202012()). require_format_validation(true)); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/ipv6.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft202012()). require_format_validation(true)); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/iri.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/iri-reference.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/json-pointer.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft202012()). require_format_validation(true)); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/regex.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft202012()). require_format_validation(true)); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/relative-json-pointer.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/time.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft202012()). require_format_validation(true)); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/uri.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft202012()). require_format_validation(true)); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/uri-reference.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft202012()). require_format_validation(true)); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/uri-reference.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/optional/format/uri-template.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft2020-12/content.json"); } } jsoncons-1.3.2/test/jsonschema/src/jsonschema_draft4_tests.cpp000066400000000000000000000223651477700171100246120ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #include #include #include #include #include #include #include using jsoncons::json; namespace jsonschema = jsoncons::jsonschema; namespace { json resolver(const jsoncons::uri& uri) { //std::cout << uri.string() << ", " << uri.path() << "\n"; std::string pathname = "./jsonschema/JSON-Schema-Test-Suite/remotes"; pathname += std::string(uri.path()); std::fstream is(pathname.c_str()); if (!is) { return json::null(); } return json::parse(is); } void jsonschema_tests(const std::string& fpath) { std::fstream is(fpath); if (!is) { std::cout << "Cannot open file: " << fpath << "\n"; return; } json tests = json::parse(is); //std::cout << pretty_print(tests) << "\n"; int count = 0; for (const auto& test_group : tests.array_range()) { ++count; try { jsonschema::json_schema compiled = jsonschema::make_json_schema(test_group.at("schema"), resolver, jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft4()) .require_format_validation(true)); int count_test = 0; for (const auto& test_case : test_group["tests"].array_range()) { //std::cout << " Test case " << count << "." << count_test << ": " << test_case["description"] << "\n"; ++count_test; std::size_t errors = 0; auto reporter = [&](const jsonschema::validation_message& msg) -> jsonschema::walk_result { ++errors; CHECK_FALSE(test_case["valid"].as()); if (test_case["valid"].as()) { std::cout << " File: " << fpath << "\n"; std::cout << " Test case " << count << "." << count_test << ": " << test_case["description"] << "\n"; std::cout << " Failed: " << msg.instance_location().string() << ": " << msg.message() << "\n"; for (const auto& err : msg.details()) { std::cout << " Nested error: " << err.instance_location().string() << ": " << err.message() << "\n"; } } return jsonschema::walk_result::advance; }; compiled.validate(test_case.at("data"), reporter); if (errors == 0) { CHECK(test_case["valid"].as()); if (!test_case["valid"].as()) { std::cout << " File: " << fpath << "\n"; std::cout << " Test case " << count << "." << count_test << ": " << test_case["description"] << "\n"; } } } } catch (const std::exception& e) { std::cout << " File: " << fpath << " " << count << "\n"; std::cout << e.what() << "\n\n"; CHECK(false); } } } } TEST_CASE("jsonschema draft4 tests") { SECTION("issues") { //jsonschema_tests("./jsonschema/issues/draft4/issue-content.json"); } SECTION("tests") { jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/additionalItems.json"); #ifdef JSONCONS_HAS_STD_REGEX jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/additionalProperties.json"); #endif jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/allOf.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/anyOf.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/default.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/definitions.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/dependencies.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/enum.json"); #ifdef JSONCONS_HAS_STD_REGEX //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/format.json"); #endif jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/items.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/maximum.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/maxItems.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/maxLength.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/maxProperties.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/minimum.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/minItems.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/minLength.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/minProperties.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/multipleOf.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/not.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/oneOf.json"); #ifdef JSONCONS_HAS_STD_REGEX jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/pattern.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/patternProperties.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/properties.json"); #endif jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/ref.json"); // * jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/refRemote.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/required.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/type.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/uniqueItems.json"); // format tests jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/date-time.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/ecmascript-regex.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/email.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/hostname.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/idn-email.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/idn-hostname.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/ipv4.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/ipv6.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/iri.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/iri-reference.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/regex.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/relative-json-pointer.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/uri.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/uri-reference.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft4/optional/format/uri-template.json"); } SECTION("#417") { jsoncons::json schema = jsoncons::json::parse(R"( { "$id": "https://example.com/polygon", "$schema": "http://json-schema.org/draft-04/schema#", "unknown-keyword": { "point": { "type": "object", "properties": { "x": { "type": "number" }, "y": { "type": "number" } }, "additionalProperties": false, "required": [ "x", "y" ] } }, "type": "array", "items": { "$ref": "#/unknown-keyword/point" }, "minItems": 3, "maxItems": 1 } )"); jsoncons::json instance = jsoncons::json::parse(R"( [ { "x": 2.5, "y": 1.3 }, { "x": 1, "z": 6.7 } ] )"); jsonschema::json_schema compiled = jsoncons::jsonschema::make_json_schema(schema); CHECK_FALSE(compiled.is_valid(instance)); } } jsoncons-1.3.2/test/jsonschema/src/jsonschema_draft6_tests.cpp000066400000000000000000000236451477700171100246160ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #include #include #include #include #include #include #include using jsoncons::json; namespace jsonschema = jsoncons::jsonschema; namespace { json resolver(const jsoncons::uri& uri) { //std::cout << uri.string() << ", " << uri.path() << "\n"; std::string pathname = "./jsonschema/JSON-Schema-Test-Suite/remotes"; pathname += std::string(uri.path()); std::fstream is(pathname.c_str()); if (!is) { return json::null(); } return json::parse(is); } void jsonschema_tests(const std::string& fpath) { std::fstream is(fpath); if (!is) { std::cout << "Cannot open file: " << fpath << "\n"; return; } json tests = json::parse(is); //std::cout << pretty_print(tests) << "\n"; int count = 0; for (const auto& test_group : tests.array_range()) { ++count; try { jsonschema::json_schema compiled = jsonschema::make_json_schema(test_group.at("schema"), resolver, jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft6()) .require_format_validation(true)); int count_test = 0; for (const auto& test_case : test_group["tests"].array_range()) { //std::cout << " Test case " << count << "." << count_test << ": " << test_case["description"] << "\n"; ++count_test; std::size_t errors = 0; auto reporter = [&](const jsonschema::validation_message& msg) -> jsonschema::walk_result { ++errors; CHECK_FALSE(test_case["valid"].as()); if (test_case["valid"].as()) { std::cout << " File: " << fpath << "\n"; std::cout << " Test case " << count << "." << count_test << ": " << test_case["description"] << "\n"; std::cout << " Failed: " << msg.instance_location().string() << ": " << msg.message() << "\n"; for (const auto& err : msg.details()) { std::cout << " Nested error: " << err.instance_location().string() << ": " << err.message() << "\n"; } } return jsonschema::walk_result::advance; }; compiled.validate(test_case.at("data"), reporter); if (errors == 0) { CHECK(test_case["valid"].as()); if (!test_case["valid"].as()) { std::cout << " File: " << fpath << "\n"; std::cout << " Test case " << count << "." << count_test << ": " << test_case["description"] << "\n"; } } } } catch (const std::exception& e) { std::cout << " File: " << fpath << " " << count << "\n"; std::cout << e.what() << "\n\n"; CHECK(false); } } } } TEST_CASE("jsonschema draft6 tests") { SECTION("issues") { //jsonschema_tests("./jsonschema/issues/draft6/issue-content.json"); } SECTION("tests") { jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/additionalItems.json"); #ifdef JSONCONS_HAS_STD_REGEX jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/additionalProperties.json"); #endif jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/allOf.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/anyOf.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/boolean_schema.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/const.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/contains.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/default.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/definitions.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/dependencies.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/enum.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/exclusiveMaximum.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/exclusiveMinimum.json"); #ifdef JSONCONS_HAS_STD_REGEX //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/format.json"); #endif jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/items.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/maximum.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/maxItems.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/maxLength.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/maxProperties.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/minimum.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/minItems.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/minLength.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/minProperties.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/multipleOf.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/not.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/oneOf.json"); #ifdef JSONCONS_HAS_STD_REGEX jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/pattern.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/patternProperties.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/properties.json"); #endif jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/propertyNames.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/ref.json"); // * jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/refRemote.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/required.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/type.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/uniqueItems.json"); // format tests jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/date-time.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/ecmascript-regex.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/email.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/hostname.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/idn-email.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/idn-hostname.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/ipv4.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/ipv6.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/iri.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/iri-reference.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/json-pointer.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/regex.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/relative-json-pointer.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/uri.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/uri-reference.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft6/optional/format/uri-template.json"); } SECTION("#417") { jsoncons::json schema = jsoncons::json::parse(R"( { "$id": "https://example.com/polygon", "$schema": "http://json-schema.org/draft-06/schema#", "unknown-keyword": { "point": { "type": "object", "properties": { "x": { "type": "number" }, "y": { "type": "number" } }, "additionalProperties": false, "required": [ "x", "y" ] } }, "type": "array", "items": { "$ref": "#/unknown-keyword/point" }, "minItems": 3, "maxItems": 1 } )"); jsoncons::json instance = jsoncons::json::parse(R"( [ { "x": 2.5, "y": 1.3 }, { "x": 1, "z": 6.7 } ] )"); jsonschema::json_schema compiled = jsoncons::jsonschema::make_json_schema(schema); CHECK_FALSE(compiled.is_valid(instance)); } } jsoncons-1.3.2/test/jsonschema/src/jsonschema_draft7_tests.cpp000066400000000000000000000273551477700171100246210ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #include #include #include #include #include #include #include using jsoncons::json; namespace jsonschema = jsoncons::jsonschema; namespace { json resolver(const jsoncons::uri& uri) { //std::cout << uri.string() << ", " << uri.path() << "\n"; std::string pathname = "./jsonschema/JSON-Schema-Test-Suite/remotes"; pathname += std::string(uri.path()); std::fstream is(pathname.c_str()); if (!is) { return json::null(); } return json::parse(is); } void jsonschema_tests(const std::string& fpath, jsonschema::evaluation_options options = jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft7())) { std::fstream is(fpath); if (!is) { std::cout << "Cannot open file: " << fpath << "\n"; return; } json tests = json::parse(is); //std::cout << pretty_print(tests) << "\n"; int count = 0; for (const auto& test_group : tests.array_range()) { ++count; try { jsonschema::json_schema compiled = jsonschema::make_json_schema(test_group.at("schema"), resolver, options); int count_test = 0; for (const auto& test_case : test_group["tests"].array_range()) { //std::cout << " Test case " << count << "." << count_test << ": " << test_case["description"] << "\n"; ++count_test; std::size_t errors = 0; auto reporter = [&](const jsonschema::validation_message& msg) -> jsonschema::walk_result { ++errors; CHECK_FALSE(test_case["valid"].as()); if (test_case["valid"].as()) { std::cout << " File: " << fpath << "\n"; std::cout << " Test case " << count << "." << count_test << ": " << test_case["description"] << "\n"; std::cout << " Failed: " << msg.instance_location().string() << ": " << msg.message() << "\n"; for (const auto& err : msg.details()) { std::cout << " Nested error: " << err.instance_location().string() << ": " << err.message() << "\n"; } } return jsonschema::walk_result::advance; }; compiled.validate(test_case.at("data"), reporter); if (errors == 0) { CHECK(test_case["valid"].as()); if (!test_case["valid"].as()) { std::cout << " File: " << fpath << "\n"; std::cout << " Test case " << count << "." << count_test << ": " << test_case["description"] << "\n"; } } } } catch (const std::exception& e) { std::cout << " File: " << fpath << " " << count << "\n"; std::cout << e.what() << "\n\n"; CHECK(false); } } } } TEST_CASE("jsonschema draft7 tests") { SECTION("issues") { jsonschema_tests("./jsonschema/issues/draft7/issue-520.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft7()). require_format_validation(true)); } SECTION("tests") { jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/additionalItems.json"); #ifdef JSONCONS_HAS_STD_REGEX jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/additionalProperties.json"); #endif jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/allOf.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/anyOf.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/boolean_schema.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/const.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/contains.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/default.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/definitions.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/dependencies.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/enum.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/exclusiveMaximum.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/exclusiveMinimum.json"); #ifdef JSONCONS_HAS_STD_REGEX //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/format.json"); #endif jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/if-then-else.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/items.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/maximum.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/maxItems.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/maxLength.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/maxProperties.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/minimum.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/minItems.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/minLength.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/minProperties.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/multipleOf.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/not.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/oneOf.json"); #ifdef JSONCONS_HAS_STD_REGEX jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/pattern.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/patternProperties.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/properties.json"); #endif jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/propertyNames.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/ref.json"); // * jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/refRemote.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/required.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/type.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/uniqueItems.json"); // format tests jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/date.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft7()). require_format_validation(true)); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/date-time.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft7()). require_format_validation(true)); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/ecmascript-regex.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/email.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft7()). require_format_validation(true)); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/hostname.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft7()). require_format_validation(true)); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/idn-email.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/idn-hostname.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/ipv4.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft7()). require_format_validation(true)); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/ipv6.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft7()). require_format_validation(true)); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/iri.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/iri-reference.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/json-pointer.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft7()). require_format_validation(true)); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/regex.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/relative-json-pointer.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/time.json", jsonschema::evaluation_options{}.default_version(jsonschema::schema_version::draft7()). require_format_validation(true)); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/uri.json"); // REVISIT //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/uri.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/uri-reference.json"); //jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/format/uri-template.json"); jsonschema_tests("./jsonschema/JSON-Schema-Test-Suite/tests/draft7/optional/content.json"); } SECTION("#417") { jsoncons::json schema = jsoncons::json::parse(R"( { "$id": "https://example.com/polygon", "$schema": "http://json-schema.org/draft-07/schema#", "unknown-keyword": { "point": { "type": "object", "properties": { "x": { "type": "number" }, "y": { "type": "number" } }, "additionalProperties": false, "required": [ "x", "y" ] } }, "type": "array", "items": { "$ref": "#/unknown-keyword/point" }, "minItems": 3, "maxItems": 1 } )"); jsoncons::json instance = jsoncons::json::parse(R"( [ { "x": 2.5, "y": 1.3 }, { "x": 1, "z": 6.7 } ] )"); jsonschema::json_schema compiled = jsoncons::jsonschema::make_json_schema(schema); CHECK_FALSE(compiled.is_valid(instance)); } } jsoncons-1.3.2/test/jsonschema/src/jsonschema_validator_tests.cpp000066400000000000000000000027371477700171100254140ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #include #include #include #include #include #include #include using jsoncons::json; namespace jsonschema = jsoncons::jsonschema; TEST_CASE("jsonschema validator tests") { SECTION("Basic") { json schema = json::parse(R"( { "$id": "https://example.com/polygon", "$schema": "http://json-schema.org/draft-07/schema#", "$defs": { "point": { "type": "object", "properties": { "x": { "type": "number" }, "y": { "type": "number" } }, "additionalProperties": false, "required": [ "x", "y" ] } }, "type": "array", "items": { "$ref": "#/$defs/point" }, "minItems": 3, "maxItems": 1 } )"); json instance = json::parse(R"( [ { "x": 2.5, "y": 1.3 }, { "x": 1, "z": 6.7 } ] )"); jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); CHECK_FALSE(compiled.is_valid(instance)); } } /* : Expected minimum item count: 3, found: 2 /1: Required key "y" not found /1: Validation failed for additional property "z". False schema always fails */ jsoncons-1.3.2/test/jsonschema/src/range_collection_tests.cpp000066400000000000000000000027441477700171100245220ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #include #include #include #include #include #include using jsoncons::jsonschema::range; using jsoncons::jsonschema::range_collection; TEST_CASE("jsonschema range collection tests") { range_collection ranges; ranges.insert(range{0,5}); ranges.insert(range{10,15}); ranges.insert(range{7,8}); SECTION("test 1") { CHECK(ranges.contains(0)); CHECK(ranges.contains(1)); CHECK(ranges.contains(2)); CHECK(ranges.contains(3)); CHECK(ranges.contains(4)); CHECK_FALSE(ranges.contains(5)); CHECK_FALSE(ranges.contains(6)); CHECK(ranges.contains(7)); CHECK_FALSE(ranges.contains(8)); CHECK_FALSE(ranges.contains(9)); CHECK(ranges.contains(10)); CHECK(ranges.contains(11)); CHECK(ranges.contains(12)); CHECK(ranges.contains(13)); CHECK(ranges.contains(14)); } SECTION("test 2") { range_collection coll2; for (auto range : ranges) { coll2.insert(range); } } } jsoncons-1.3.2/test/jsonschema/src/schema_version_tests.cpp000066400000000000000000000045431477700171100242170ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #include #include #include #include #include #include using jsoncons::json; namespace jsonschema = jsoncons::jsonschema; TEST_CASE("jsonschema version tests") { json schema_03 = json::parse(R"( { "$schema": "http://json-schema.org/draft-03/schema#", "description": "A product from Acme's catalog", "properties": { "id": { "description": "The unique identifier for a product", "type": "integer" }, "name": { "description": "Name of the product", "type": "string" }, "price": { "exclusiveMinimum": true, "minimum": 0, "type": "number" }, "tags": { "items": { "type": "string" }, "minItems": 1, "type": "array", "uniqueItems": true } }, "required": ["id", "name", "price"], "title": "Product", "type": "object" } )"); json schema_07 = json::parse(R"( { "$schema": "http://json-schema.org/draft-07/schema#", "description": "A product from Acme's catalog", "properties": { "id": { "description": "The unique identifier for a product", "type": "integer" }, "name": { "description": "Name of the product", "type": "string" }, "price": { "exclusiveMinimum": true, "minimum": 0, "type": "number" }, "tags": { "items": { "type": "string" }, "minItems": 1, "type": "array", "uniqueItems": true } }, "required": ["id", "name", "price"], "title": "Product", "type": "object" } )"); SECTION("test 3") { REQUIRE_THROWS_WITH(jsonschema::make_json_schema(schema_03), "Unsupported schema version http://json-schema.org/draft-03/schema#"); } SECTION("test 7") { REQUIRE_THROWS_WITH(jsonschema::make_json_schema(schema_07), "https://jsoncons.com#/properties/price/exclusiveMinimum: exclusiveMinimum must be a number value"); } } jsoncons-1.3.2/test/jsonschema/src/validation_report_tests.cpp000066400000000000000000000576231477700171100247460ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #include #include #include #include #include #include #include using jsoncons::json; using jsoncons::ojson; namespace jsonschema = jsoncons::jsonschema; TEST_CASE("jsonschema validation report tests") { json schema = json::parse(R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://test.com/schema", "$defs": { "integer": { "type": "integer" }, "minimum": { "minimum": 5 } }, "type" : "object", "properties" : { "passes" : true, "fails" : false, "refs" : {"$ref" : "#/$defs/integer"}, "multi" : { "allOf" : [{"$ref" : "#/$defs/integer"},{"$ref" : "#/$defs/minimum"}] } } } )"); SECTION("Test 1") { ojson expected = ojson::parse(R"( [ { "valid": false, "evaluationPath": "/properties/fails", "schemaLocation": "https://test.com/schema#/properties/fails", "instanceLocation": "/fails", "error": "False schema always fails" } ] )"); jsoncons::json_decoder decoder; jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); json data = json::parse(R"({"fails":"value"})"); compiled.validate(data, decoder); ojson output = decoder.get_result(); CHECK(expected == output); //std::cout << pretty_print(output) << "\n"; } SECTION("Test 2") { ojson expected = ojson::parse(R"( [ { "valid": false, "evaluationPath": "/properties/multi/allOf", "schemaLocation": "https://test.com/schema#/properties/multi/allOf", "instanceLocation": "/multi", "error": "Must be valid against all schemas, but found unmatched schemas", "details": [ { "valid": false, "evaluationPath": "/properties/multi/allOf/0/$ref/type", "schemaLocation": "https://test.com/schema#/$defs/integer", "instanceLocation": "/multi", "error": "Expected integer, found number" }, { "valid": false, "evaluationPath": "/properties/multi/allOf/1/$ref/minimum", "schemaLocation": "https://test.com/schema#/$defs/minimum/minimum", "instanceLocation": "/multi", "error": "Minimum value is 5 but found 3.5" } ] } ] )"); jsoncons::json_decoder decoder; jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); json data = json::parse(R"({"multi":3.5})"); compiled.validate(data, decoder); ojson output = decoder.get_result(); CHECK(expected == output); //std::cout << pretty_print(output) << "\n"; } } TEST_CASE("jsonschema prefixItems report tests") { json schema = json::parse(R"( { "type": "array", "prefixItems": [ { "type": "number" }, { "type": "string" }, { "enum": ["Street", "Avenue", "Boulevard"] }, { "enum": ["NW", "NE", "SW", "SE"] } ], "items": false } )"); SECTION("Test 1") { ojson expected = ojson::parse(R"( [ { "valid": false, "evaluationPath": "/items", "schemaLocation": "https://jsoncons.com#/items", "instanceLocation": "/4", "error": "Extra item at index '4' but the schema does not allow extra items." } ] )"); jsoncons::json_decoder decoder; jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); json data = json::parse(R"( [1600, "Pennsylvania", "Avenue", "NW", "Washington"] )"); compiled.validate(data, decoder); ojson output = decoder.get_result(); CHECK(expected == output); //std::cout << pretty_print(output) << "\n"; } } TEST_CASE("jsonschema items-additionalItems report tests") { json schema = json::parse(R"( { "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "array", "items": [ { "type": "number" }, { "type": "string" }, { "enum": ["Street", "Avenue", "Boulevard"] }, { "enum": ["NW", "NE", "SW", "SE"] } ], "additionalItems": false } )"); SECTION("Test 1") { ojson expected = ojson::parse(R"( [ { "valid": false, "evaluationPath": "/additionalItems", "schemaLocation": "https://jsoncons.com#/additionalItems", "instanceLocation": "/4", "error": "Extra item at index '4' but the schema does not allow extra items." } ] )"); jsoncons::json_decoder decoder; jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); json data = json::parse(R"( [1600, "Pennsylvania", "Avenue", "NW", "Washington"] )"); compiled.validate(data, decoder); ojson output = decoder.get_result(); CHECK(expected == output); //std::cout << pretty_print(output) << "\n"; } } TEST_CASE("jsonschema additionalProperties output tests") { json schema = json::parse(R"( { "type": "object", "properties": { "number": { "type": "number" }, "street_name": { "type": "string" }, "street_type": { "enum": ["Street", "Avenue", "Boulevard"] } }, "additionalProperties": false } )"); SECTION("Test 1") { ojson expected = ojson::parse(R"( [ { "valid": false, "evaluationPath": "/additionalProperties/direction", "schemaLocation": "https://jsoncons.com#/additionalProperties", "instanceLocation": "/direction", "error": "Additional property 'direction' not allowed by schema." } ] )"); jsoncons::json_decoder decoder; jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); json data = json::parse(R"( { "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue", "direction": "NW" } )"); compiled.validate(data, decoder); ojson output = decoder.get_result(); CHECK(expected == output); //std::cout << pretty_print(output) << "\n"; } } TEST_CASE("jsonschema unevaluatedProperties output tests") { json schema = json::parse(R"( { "allOf": [ { "type": "object", "properties": { "street_address": { "type": "string" }, "city": { "type": "string" }, "state": { "type": "string" } }, "required": ["street_address", "city", "state"] } ], "properties": { "type": { "enum": ["residential", "business"] } }, "required": ["type"], "unevaluatedProperties": false } )"); SECTION("Test 1") { ojson expected = ojson::parse(R"( [ { "valid": false, "evaluationPath": "/unevaluatedProperties/something that doesn't belong", "schemaLocation": "https://jsoncons.com", "instanceLocation": "/something that doesn't belong", "error": "Unevaluated property 'something that doesn't belong' but the schema does not allow unevaluated properties." } ] )"); jsoncons::json_decoder decoder; jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); json data = json::parse(R"( { "street_address": "1600 Pennsylvania Avenue NW", "city": "Washington", "state": "DC", "type": "business", "something that doesn't belong": "hi!" } )"); compiled.validate(data, decoder); ojson output = decoder.get_result(); CHECK(expected == output); } } TEST_CASE("jsonschema unevaluatedItems output tests") { json schema = json::parse(R"( { "prefixItems": [ { "type": "string" }, { "type": "number" } ], "unevaluatedItems": false } )"); SECTION("Test 1") { ojson expected = ojson::parse(R"( [ { "valid": false, "evaluationPath": "/unevaluatedProperties/2", "schemaLocation": "https://jsoncons.com", "instanceLocation": "/2", "error": "Unevaluated item at index '2' but the schema does not allow unevaluated items." } ] )"); jsoncons::json_decoder decoder; jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); json data = json::parse(R"( ["foo", 42, null] )"); compiled.validate(data, decoder); ojson output = decoder.get_result(); CHECK(expected == output); //std::cout << pretty_print(output) << "\n"; } } TEST_CASE("jsonschema items output tests") { std::string schema_str = R"( { "$schema": "http://json-schema.org/draft-04/schema#", "definitions": { "path": { "description": "A JSON Pointer path.", "type": "string" } }, "id": "https://json.schemastore.org/json-patch.json", "items": { "oneOf": [ { "additionalProperties": false, "required": ["value", "op", "path"], "properties": { "path": { "$ref": "#/definitions/path" }, "op": { "description": "The operation to perform.", "type": "string", "enum": ["add", "replace", "test"] }, "value": { "description": "The value to add, replace or test." } } }, { "additionalProperties": false, "required": ["op", "path"], "properties": { "path": { "$ref": "#/definitions/path" }, "op": { "description": "The operation to perform.", "type": "string", "enum": ["remove"] } } }, { "additionalProperties": false, "required": ["from", "op", "path"], "properties": { "path": { "$ref": "#/definitions/path" }, "op": { "description": "The operation to perform.", "type": "string", "enum": ["move", "copy"] }, "from": { "$ref": "#/definitions/path", "description": "A JSON Pointer path pointing to the location to move/copy from." } } } ] }, "title": "JSON schema for JSONPatch files", "type": "array" } )"; SECTION("Test 1") { ojson expected = ojson::parse(R"( [ { "valid": false, "evaluationPath": "/items/oneOf", "schemaLocation": "https://json.schemastore.org/json-patch.json#/items/oneOf", "instanceLocation": "/0", "error": "Must be valid against exactly one schema, but found no matching schemas", "details": [ { "valid": false, "evaluationPath": "/items/oneOf/0/properties/op/enum", "schemaLocation": "https://json.schemastore.org/json-patch.json#/items/oneOf/0/properties/op/enum", "instanceLocation": "/0/op", "error": "'invalid_op' is not a valid enum value." }, { "valid": false, "evaluationPath": "/items/oneOf/1/properties/op/enum", "schemaLocation": "https://json.schemastore.org/json-patch.json#/items/oneOf/1/properties/op/enum", "instanceLocation": "/0/op", "error": "'invalid_op' is not a valid enum value." }, { "valid": false, "evaluationPath": "/items/oneOf/1/additionalProperties/value", "schemaLocation": "https://json.schemastore.org/json-patch.json#/items/oneOf/1/additionalProperties", "instanceLocation": "/0/value", "error": "Additional property 'value' not allowed by schema." }, { "valid": false, "evaluationPath": "/items/oneOf/2/required", "schemaLocation": "https://json.schemastore.org/json-patch.json#/items/oneOf/2/required", "instanceLocation": "/0", "error": "Required property 'from' not found." }, { "valid": false, "evaluationPath": "/items/oneOf/2/properties/op/enum", "schemaLocation": "https://json.schemastore.org/json-patch.json#/items/oneOf/2/properties/op/enum", "instanceLocation": "/0/op", "error": "'invalid_op' is not a valid enum value." }, { "valid": false, "evaluationPath": "/items/oneOf/2/additionalProperties/value", "schemaLocation": "https://json.schemastore.org/json-patch.json#/items/oneOf/2/additionalProperties", "instanceLocation": "/0/value", "error": "Additional property 'value' not allowed by schema." } ] } ] )"); std::string data_str = R"( [ { "op": "invalid_op", "path": "/biscuits/1", "value":{"name":"Ginger Nut" } } ] )"; auto schema_ = jsoncons::ojson::parse(schema_str); auto data_ = jsoncons::ojson::parse(data_str); auto compiled = jsoncons::jsonschema::make_json_schema(schema_); jsoncons::json_decoder decoder; compiled.validate(data_, decoder); auto output = decoder.get_result(); CHECK(expected == output); //std::cout << pretty_print(output) << "\n"; } } TEST_CASE("jsonschema more output tests 2") { json schema = json::parse(R"( { "$id":"http://schemarepo.org/schemas/user.json", "$schema":"http://json-schema.org/draft-07/schema#", "type":"object", "definitions":{ "min18":{ "type":"integer", "minimum":18 }, "username":{ "type":"string", "minLength":8 }, "member":{ "type":"object", "properties":{ "age":{"$ref":"#/definitions/min18"}, "username":{"$ref":"#/definitions/username"} } }, "membershipTypes":{"enum":["admin","user"]} }, "oneOf":[ { "properties":{ "member":{"$ref":"#/definitions/member"}, "membershipType":{"$ref":"#/definitions/membershipTypes"} } }, { "properties":{ "membershipType":{"const":"guest"}, "firstName":{"type":"string"}, "lastName":{"type":"string"} }, "additionalProperties":false } ] } )"); SECTION("With ref") { json data = json::parse(R"( { "member":{ "age":5, // doesn't meet minimum "username":"aName" // doesn't meet minLength }, "membershipType":"user" } )"); ojson expected = ojson::parse(R"( [ { "valid": false, "evaluationPath": "/oneOf", "schemaLocation": "http://schemarepo.org/schemas/user.json#/oneOf", "instanceLocation": "", "error": "Must be valid against exactly one schema, but found no matching schemas", "details": [ { "valid": false, "evaluationPath": "/oneOf/0/properties/member/$ref/properties/age/$ref/minimum", "schemaLocation": "http://schemarepo.org/schemas/user.json#/definitions/min18/minimum", "instanceLocation": "/member/age", "error": "Minimum value is 18 but found 5" }, { "valid": false, "evaluationPath": "/oneOf/0/properties/member/$ref/properties/username/$ref/minLength", "schemaLocation": "http://schemarepo.org/schemas/user.json#/definitions/username/minLength", "instanceLocation": "/member/username", "error": "Number of characters must be at least 8" }, { "valid": false, "evaluationPath": "/oneOf/1/properties/membershipType/const", "schemaLocation": "http://schemarepo.org/schemas/user.json#/oneOf/1/properties/membershipType/const", "instanceLocation": "/membershipType", "error": "Instance is not const" }, { "valid": false, "evaluationPath": "/oneOf/1/additionalProperties/member", "schemaLocation": "http://schemarepo.org/schemas/user.json#/oneOf/1/additionalProperties", "instanceLocation": "/member", "error": "Additional property 'member' not allowed by schema." } ] } ] )"); auto compiled = jsoncons::jsonschema::make_json_schema(schema); jsoncons::json_decoder decoder; compiled.validate(data, decoder); auto output = decoder.get_result(); CHECK(expected == output); //std::cout << pretty_print(output) << "\n"; } } TEST_CASE("jsonschema more output tests 3") { json schema = json::parse(R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "example-schema", "type": "object", "title": "foo object schema", "properties": { "foo": { "title": "foo's title", "description": "foo's description", "type": "string", "pattern": "^foo ", "minLength": 10 } }, "required": [ "foo" ], "additionalProperties": false } )"); SECTION("With ref") { json data = json::parse(R"( { "baz": 42 } )"); ojson expected = ojson::parse(R"( [ { "valid": false, "evaluationPath": "/additionalProperties/baz", "schemaLocation": "https://jsoncons.com/example-schema#/additionalProperties", "instanceLocation": "/baz", "error": "Additional property 'baz' not allowed by schema." }, { "valid": false, "evaluationPath": "/required", "schemaLocation": "https://jsoncons.com/example-schema#/required", "instanceLocation": "", "error": "Required property 'foo' not found." } ] )"); auto compiled = jsoncons::jsonschema::make_json_schema(schema); jsoncons::json_decoder decoder; compiled.validate(data, decoder); auto output = decoder.get_result(); CHECK(expected == output); //std::cout << pretty_print(output) << "\n"; } } TEST_CASE("jsonschema more output tests") { json schema = json::parse(R"( { "$id": "https://example.com/polygon", "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "point": { "type": "object", "properties": { "x": { "type": "number" }, "y": { "type": "number" } }, "additionalProperties": false, "required": [ "x", "y" ] } }, "type": "array", "items": { "$ref": "#/$defs/point" }, "minItems": 3 } )"); SECTION("Test 1") { ojson expected = ojson::parse(R"( [ { "valid": false, "evaluationPath": "/items/$ref/additionalProperties/z", "schemaLocation": "https://example.com/polygon#/$defs/point/additionalProperties", "instanceLocation": "/1/z", "error": "Additional property 'z' not allowed by schema." }, { "valid": false, "evaluationPath": "/items/$ref/required", "schemaLocation": "https://example.com/polygon#/$defs/point/required", "instanceLocation": "/1", "error": "Required property 'y' not found." }, { "valid": false, "evaluationPath": "/minItems", "schemaLocation": "https://example.com/polygon#/minItems", "instanceLocation": "", "error": "Minimum number of items is 3 but found 2" } ] )"); json data = json::parse(R"( [ { "x": 2.5, "y": 1.3 }, { "x": 1, "z": 6.7 } ] )"); auto compiled = jsoncons::jsonschema::make_json_schema(schema); jsoncons::json_decoder decoder; compiled.validate(data, decoder); auto output = decoder.get_result(); CHECK(expected == output); //std::cout << pretty_print(output) << "\n"; } } TEST_CASE("jsonschema additionalProperties with 'not true' output tests") { json schema = json::parse(R"( { "type": "object", "properties": { "number": { "type": "number" }, "street_name": { "type": "string" }, "street_type": { "enum": ["Street", "Avenue", "Boulevard"] } }, "additionalProperties": {"not" : true} } )"); SECTION("Test 1") { ojson expected = ojson::parse(R"( [ { "valid": false, "evaluationPath": "/additionalProperties/direction", "schemaLocation": "https://jsoncons.com#/additionalProperties", "instanceLocation": "/direction", "error": "Additional property 'direction' not allowed by schema." } ] )"); jsoncons::json_decoder decoder; jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); json data = json::parse(R"( { "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue", "direction": "NW" } )"); compiled.validate(data, decoder); ojson output = decoder.get_result(); CHECK(expected == output); //std::cout << pretty_print(output) << "\n"; } } TEST_CASE("jsonschema additionalProperties with 'not {}' output tests") { json schema = json::parse(R"( { "type": "object", "properties": { "number": { "type": "number" }, "street_name": { "type": "string" }, "street_type": { "enum": ["Street", "Avenue", "Boulevard"] } }, "additionalProperties": {"not" : {}} } )"); SECTION("Test 1") { ojson expected = ojson::parse(R"( [ { "valid": false, "evaluationPath": "/additionalProperties/direction", "schemaLocation": "https://jsoncons.com#/additionalProperties", "instanceLocation": "/direction", "error": "Additional property 'direction' not allowed by schema." } ] )"); jsoncons::json_decoder decoder; jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); json data = json::parse(R"( { "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue", "direction": "NW" } )"); compiled.validate(data, decoder); ojson output = decoder.get_result(); CHECK(expected == output); //std::cout << pretty_print(output) << "\n"; } } TEST_CASE("jsonschema with 'oneOf' output tests") { json schema = json::parse(R"( { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "/test_schema", "type": "object", "properties": { "One": { "type": "string" }, "Two" : { "type": "string" } }, "oneOf" : [ { "required" : ["One"] }, { "required" : ["Two"] } ], "unevaluatedProperties" : false } )"); SECTION("Test 1") { ojson expected = ojson::parse(R"( [ { "valid": false, "evaluationPath": "/oneOf", "schemaLocation": "https://jsoncons.com/test_schema#/oneOf", "instanceLocation": "", "error": "Must be valid against exactly one schema, but found 2 matching schemas at indices 0,1" } ] )"); jsoncons::json_decoder decoder; jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); json data = json::parse(R"( { "One" : "test", "Two" : "test" } )"); compiled.validate(data, decoder); ojson output = decoder.get_result(); CHECK(expected == output); //std::cout << pretty_print(output) << "\n"; } } jsoncons-1.3.2/test/mergepatch/000077500000000000000000000000001477700171100164545ustar00rootroot00000000000000jsoncons-1.3.2/test/mergepatch/input/000077500000000000000000000000001477700171100176135ustar00rootroot00000000000000jsoncons-1.3.2/test/mergepatch/input/compliance/000077500000000000000000000000001477700171100217255ustar00rootroot00000000000000jsoncons-1.3.2/test/mergepatch/input/compliance/rfc7396-test-cases.json000066400000000000000000000114161477700171100257770ustar00rootroot00000000000000[ { "source" : "https://datatracker.ietf.org/doc/html/rfc7396 Appendix A. Example Test Cases", "given": {"a":"b"}, "cases": [ { "patch": {"a":"c"}, "result": {"a":"c"} } ] }, { "source" : "https://datatracker.ietf.org/doc/html/rfc7396 Appendix A. Example Test Cases", "given": {"a":"b"}, "cases": [ { "patch": {"b":"c"}, "result": {"a":"b", "b":"c"} } ] }, { "source" : "https://datatracker.ietf.org/doc/html/rfc7396 Appendix A. Example Test Cases", "given": {"a":"b"}, "cases": [ { "patch": {"a":null}, "result": {} } ] }, { "source" : "https://datatracker.ietf.org/doc/html/rfc7396 Appendix A. Example Test Cases", "given": {"a":"b", "b":"c"}, "cases": [ { "patch": {"a":null}, "result": {"b":"c"} } ] }, { "source" : "https://datatracker.ietf.org/doc/html/rfc7396 Appendix A. Example Test Cases", "given": {"a":["b"]}, "cases": [ { "patch": {"a":"c"}, "result": {"a":"c"} } ] }, { "source" : "https://datatracker.ietf.org/doc/html/rfc7396 Appendix A. Example Test Cases", "given": {"a":"c"}, "cases": [ { "patch": {"a":["b"]}, "result": {"a":["b"]} } ] }, { "source" : "https://datatracker.ietf.org/doc/html/rfc7396 Appendix A. Example Test Cases", "given": {"a": { "b": "c"} }, "cases": [ { "patch": {"a": { "b": "d", "c": null} }, "result": {"a": { "b": "d" } } } ] }, { "source" : "https://datatracker.ietf.org/doc/html/rfc7396 Appendix A. Example Test Cases", "given": {"a": [ {"b":"c"} ] }, "cases": [ { "patch": {"a": [1]}, "result": {"a": [1]} } ] }, { "source" : "https://datatracker.ietf.org/doc/html/rfc7396 Appendix A. Example Test Cases", "given": ["a","b"], "cases": [ { "patch": ["c","d"], "result": ["c","d"] } ] }, { "source" : "https://datatracker.ietf.org/doc/html/rfc7396 Appendix A. Example Test Cases", "given": {"a":"b"}, "cases": [ { "patch": ["c"], "result": ["c"] } ] }, { "source" : "https://datatracker.ietf.org/doc/html/rfc7396 Appendix A. Example Test Cases", "given": {"a":"foo"}, "cases": [ { "patch": null, "result": null } ] }, { "source" : "https://datatracker.ietf.org/doc/html/rfc7396 Appendix A. Example Test Cases", "given": {"a":"foo"}, "cases": [ { "patch": "bar", "result": "bar" } ] }, { "source" : "https://datatracker.ietf.org/doc/html/rfc7396 Appendix A. Example Test Cases", "given": {"e":null}, "cases": [ { "patch": {"a":1}, "result": {"e":null, "a":1} } ] }, { "source" : "https://datatracker.ietf.org/doc/html/rfc7396 Appendix A. Example Test Cases", "given": [1,2], "cases": [ { "patch": {"a":"b", "c":null}, "result": {"a":"b"} } ] }, { "source" : "https://datatracker.ietf.org/doc/html/rfc7396 Appendix A. Example Test Cases", "given": {}, "cases": [ { "patch": {"a": {"bb": {"ccc": null}}}, "result": {"a": {"bb": {}}} } ] } ] jsoncons-1.3.2/test/mergepatch/src/000077500000000000000000000000001477700171100172435ustar00rootroot00000000000000jsoncons-1.3.2/test/mergepatch/src/mergepatch_test_suite.cpp000066400000000000000000000057111477700171100243420ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include #include #include // std::unordered_set #include #include #include using namespace jsoncons; void json_merge_patch_tests(const std::string& fpath) { std::fstream is(fpath); if (!is) { std::cerr << "Cannot open " << fpath << "\n"; exit(1); } json tests = json::parse(is); for (const auto& test_group : tests.array_range()) { for (const auto& test_case : test_group["cases"].array_range()) { const json& patch = test_case["patch"]; if (test_case.contains("result")) { json target = test_group.at("given"); mergepatch::apply_merge_patch(target, patch); const json& expected = test_case["result"]; if (target == expected) { json target2 = test_group.at("given"); json patch2 = mergepatch::from_diff(target2, target); mergepatch::apply_merge_patch(target2, patch2); if (target2 != target) { if (test_case.contains("comment")) { std::cout << "\n" << test_case["comment"] << "\n"; } std::cout << "Source: " << pretty_print(test_group.at("given")) << "\n\n"; std::cout << "Target: " << pretty_print(target) << "\n\n"; std::cout << "Diff: " << pretty_print(patch2) << "\n\n"; std::cout << "Result: " << pretty_print(target2) << "\n\n"; } CHECK(target2 == target); } else { if (test_case.contains("comment")) { std::cout << "\n" << test_case["comment"] << "\n"; } std::cout << "Input: " << pretty_print(test_group.at("given")) << "\n\n"; std::cout << "Patch: " << pretty_print(patch) << "\n\n"; std::cout << "Target: " << pretty_print(target) << "\n\n"; std::cout << "Expected: " << pretty_print(expected) << "\n\n"; } CHECK(expected == target); //-V521 } } } } TEST_CASE("mergepatch tests") { SECTION("compliance") { json_merge_patch_tests("./mergepatch/input/compliance/rfc7396-test-cases.json"); //json_merge_patch_tests("./mergepatch/input/compliance/test.json"); } } jsoncons-1.3.2/test/msgpack/000077500000000000000000000000001477700171100157625ustar00rootroot00000000000000jsoncons-1.3.2/test/msgpack/src/000077500000000000000000000000001477700171100165515ustar00rootroot00000000000000jsoncons-1.3.2/test/msgpack/src/decode_msgpack_tests.cpp000066400000000000000000000213361477700171100234340ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include using jsoncons::json; namespace msgpack = jsoncons::msgpack; void check_decode_msgpack(const std::vector& v, const json& expected) { json result = msgpack::decode_msgpack(v); REQUIRE(result == expected); } TEST_CASE("decode_number_msgpack_test") { // positive fixint 0x00 - 0x7f check_decode_msgpack({0x00},json(0U)); check_decode_msgpack({0x01},json(1U)); check_decode_msgpack({0x0a},json(10U)); check_decode_msgpack({0x17},json(23U)); check_decode_msgpack({0x18},json(24U)); check_decode_msgpack({0x7f},json(127U)); check_decode_msgpack({0xcc,0xff},json(255U)); check_decode_msgpack({0xcd,0x01,0x00},json(256U)); check_decode_msgpack({0xcd,0xff,0xff},json(65535U)); check_decode_msgpack({0xce,0,1,0x00,0x00},json(65536U)); check_decode_msgpack({0xce,0xff,0xff,0xff,0xff},json(4294967295U)); check_decode_msgpack({0xcf,0,0,0,1,0,0,0,0},json(4294967296U)); check_decode_msgpack({0xcf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},json((std::numeric_limits::max)())); check_decode_msgpack({0x01},json(1)); check_decode_msgpack({0x0a},json(10)); check_decode_msgpack({0x17},json(23)); check_decode_msgpack({0x18},json(24)); check_decode_msgpack({0x7f},json(127)); check_decode_msgpack({0xcc,0xff},json(255)); check_decode_msgpack({0xcd,0x01,0x00},json(256)); check_decode_msgpack({0xcd,0xff,0xff},json(65535)); check_decode_msgpack({0xce,0,1,0x00,0x00},json(65536)); check_decode_msgpack({0xce,0xff,0xff,0xff,0xff},json(4294967295)); check_decode_msgpack({0xd3,0,0,0,1,0,0,0,0},json(4294967296)); check_decode_msgpack({0xd3,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff},json((std::numeric_limits::max)())); // negative fixint 0xe0 - 0xff check_decode_msgpack({0xe0},json(-32)); check_decode_msgpack({0xff},json(-1)); // // negative integers check_decode_msgpack({0xd1,0xff,0},json(-256)); check_decode_msgpack({0xd1,0xfe,0xff},json(-257)); check_decode_msgpack({0xd2,0xff,0xff,0,0},json(-65536)); check_decode_msgpack({0xd2,0xff,0xfe,0xff,0xff},json(-65537)); check_decode_msgpack({0xd3,0xff,0xff,0xff,0xff,0,0,0,0},json(-4294967296)); check_decode_msgpack({0xd3,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff},json(-4294967297)); // null, true, false check_decode_msgpack({0xc0},json::null()); // check_decode_msgpack({0xc3},json(true)); // check_decode_msgpack({0xc2},json(false)); // // floating point check_decode_msgpack({0xcb,0,0,0,0,0,0,0,0},json(0.0)); check_decode_msgpack({0xcb,0xbf,0xf0,0,0,0,0,0,0},json(-1.0)); check_decode_msgpack({0xcb,0xc1,0x6f,0xff,0xff,0xe0,0,0,0},json(-16777215.0)); // string check_decode_msgpack({0xa0},json("")); check_decode_msgpack({0xa1,' '},json(" ")); check_decode_msgpack({0xbf,'1','2','3','4','5','6','7','8','9','0', '1','2','3','4','5','6','7','8','9','0', '1','2','3','4','5','6','7','8','9','0', '1'}, json("1234567890123456789012345678901")); check_decode_msgpack({0xd9,0x20,'1','2','3','4','5','6','7','8','9','0', '1','2','3','4','5','6','7','8','9','0', '1','2','3','4','5','6','7','8','9','0', '1','2'}, json("12345678901234567890123456789012")); } TEST_CASE("decode_msgpack_arrays_and_maps") { // fixarray check_decode_msgpack({0x90}, json(jsoncons::json_array_arg)); check_decode_msgpack({0x80}, json(jsoncons::json_object_arg)); check_decode_msgpack({0x91,'\0'},json::parse("[0]")); check_decode_msgpack({0x92,'\0','\0'}, json(jsoncons::json_array_arg, {0,0})); check_decode_msgpack({0x92,0x91,'\0','\0'}, json::parse("[[0],0]")); check_decode_msgpack({0x91,0xa5,'H','e','l','l','o'},json::parse("[\"Hello\"]")); check_decode_msgpack({0x81,0xa2,'o','c',0x91,'\0'}, json::parse("{\"oc\": [0]}")); check_decode_msgpack({0x81,0xa2,'o','c',0x94,'\0','\1','\2','\3'}, json::parse("{\"oc\": [0, 1, 2, 3]}")); } TEST_CASE("Compare msgpack packed item and jsoncons item") { std::vector bytes; msgpack::msgpack_bytes_encoder encoder(bytes); encoder.begin_array(2); // Must be definite length array encoder.string_value("foo"); encoder.byte_string_value(jsoncons::byte_string{'b','a','r'}); encoder.end_array(); encoder.flush(); json expected(jsoncons::json_array_arg); expected.emplace_back("foo"); expected.emplace_back(jsoncons::byte_string{ 'b','a','r' }); json j = msgpack::decode_msgpack(bytes); REQUIRE(expected == j); } TEST_CASE("decode msgpack from source") { SECTION("from string") { std::vector v = {0x91,0xa5,'H','e','l','l','o'}; std::string s(reinterpret_cast(v.data()),v.size()); json j = msgpack::decode_msgpack(s); REQUIRE(1 == j.size()); CHECK(j[0].as() == std::string("Hello")); } SECTION("from string iterator pair") { std::vector v = {0x91,0xa5,'H','e','l','l','o'}; std::string s(reinterpret_cast(v.data()),v.size()); json j = msgpack::decode_msgpack(s.begin(), s.end()); REQUIRE(1 == j.size()); CHECK(j[0].as() == std::string("Hello")); } } TEST_CASE("decode msgpack str size tests") { SECTION("str8") { std::string input = R"( {"title": "Новое расписание на автобусных маршрутах №№8, 15, 64 будет действовать с 4.07.2016"} )"; json j = json::parse(input); std::vector buf; msgpack::encode_msgpack(j, buf); json other = msgpack::decode_msgpack(buf); CHECK(j == other); } SECTION("str8 0") { std::string input = "{\"\":\"\"}"; json j = json::parse(input); std::vector buf; msgpack::encode_msgpack(j, buf); json other = msgpack::decode_msgpack(buf); CHECK(j == other); } SECTION("str8 max") { std::string input = "{\""; input.append((std::numeric_limits::max)(), '0'); input.append("\":\""); input.append((std::numeric_limits::max)(), '0'); input.append("\"}"); json j = json::parse(input); std::vector buf; msgpack::encode_msgpack(j, buf); json other = msgpack::decode_msgpack(buf); CHECK(j == other); } SECTION("str16 max") { std::string input = "{\""; input.append((std::numeric_limits::max)(), '0'); input.append("\":\""); input.append((std::numeric_limits::max)(), '0'); input.append("\"}"); json j = json::parse(input); std::vector buf; msgpack::encode_msgpack(j, buf); json other = msgpack::decode_msgpack(buf); CHECK(j == other); } SECTION("str8 max (bytes)") { std::vector in = {0xd9,0xff}; in.insert(in.end(), (std::numeric_limits::max)(), ' '); std::vector out; msgpack::msgpack_bytes_encoder visitor(out); msgpack::msgpack_bytes_reader reader(in, visitor); reader.read(); CHECK(in == out); } SECTION("str16 max (bytes)") { std::vector in = {0xda,0xff,0xff}; in.insert(in.end(), (std::numeric_limits::max)(), ' '); std::vector out; msgpack::msgpack_bytes_encoder visitor(out); msgpack::msgpack_bytes_reader reader(in, visitor); reader.read(); CHECK(in == out); } SECTION("bin8 max (bytes)") { std::vector in = {0xc4,0xff}; in.insert(in.end(), (std::numeric_limits::max)(), ' '); std::vector out; msgpack::msgpack_bytes_encoder visitor(out); msgpack::msgpack_bytes_reader reader(in, visitor); reader.read(); CHECK(in == out); } SECTION("bin16 max (bytes)") { std::vector in = {0xc5,0xff,0xff}; in.insert(in.end(), (std::numeric_limits::max)(), ' '); std::vector out; msgpack::msgpack_bytes_encoder visitor(out); msgpack::msgpack_bytes_reader reader(in, visitor); reader.read(); CHECK(in == out); } } jsoncons-1.3.2/test/msgpack/src/encode_msgpack_tests.cpp000066400000000000000000000137501477700171100234470ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include using namespace jsoncons; void check_encode_msgpack(const std::vector& expected, const json& j) { std::vector result; msgpack::encode_msgpack(j, result); if (result.size() != expected.size()) { std::cout << std::hex << (int)expected[0] << " " << std::hex << (int)result[0] << '\n'; } REQUIRE(result.size() == expected.size()); for (std::size_t i = 0; i < expected.size(); ++i) { if (expected[i] != result[i]) { std::cout << "Different " << i << "\n"; for (std::size_t k = 0; k < expected.size(); ++k) { std::cout << std::hex << (int)expected[k] << " " << std::hex << (int)result[k] << '\n'; } } REQUIRE(result[i] == expected[i]); } } TEST_CASE("encode_msgpack_test") { // positive fixint 0x00 - 0x7f check_encode_msgpack({0x00},json(0U)); check_encode_msgpack({0x01},json(1U)); check_encode_msgpack({0x0a},json(10U)); check_encode_msgpack({0x17},json(23U)); check_encode_msgpack({0x18},json(24U)); check_encode_msgpack({0x7f},json(127U)); check_encode_msgpack({0xcc,0xff},json(255U)); check_encode_msgpack({0xcd,0x01,0x00},json(256U)); check_encode_msgpack({0xcd,0xff,0xff},json(65535U)); check_encode_msgpack({0xce,0,1,0x00,0x00},json(65536U)); check_encode_msgpack({0xce,0xff,0xff,0xff,0xff},json(4294967295U)); check_encode_msgpack({0xcf,0,0,0,1,0,0,0,0},json(4294967296U)); check_encode_msgpack({0xcf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},json((std::numeric_limits::max)())); check_encode_msgpack({0x01},json(1)); check_encode_msgpack({0x0a},json(10)); check_encode_msgpack({0x17},json(23)); check_encode_msgpack({0x18},json(24)); check_encode_msgpack({0x7f},json(127)); check_encode_msgpack({0xcc,0xff},json(255)); check_encode_msgpack({0xcd,0x01,0x00},json(256)); check_encode_msgpack({0xcd,0xff,0xff},json(65535)); check_encode_msgpack({0xce,0,1,0x00,0x00},json(65536)); check_encode_msgpack({0xce,0xff,0xff,0xff,0xff},json(4294967295)); check_encode_msgpack({0xcf,0,0,0,1,0,0,0,0},json(4294967296)); check_encode_msgpack({0xcf,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff},json((std::numeric_limits::max)())); // negative fixint 0xe0 - 0xff check_encode_msgpack({0xe0},json(-32)); check_encode_msgpack({0xff},json(-1)); // // negative integers check_encode_msgpack({0xd1,0xff,0},json(-256)); check_encode_msgpack({0xd1,0xfe,0xff},json(-257)); check_encode_msgpack({0xd2,0xff,0xff,0,0},json(-65536)); check_encode_msgpack({0xd2,0xff,0xfe,0xff,0xff},json(-65537)); check_encode_msgpack({0xd3,0xff,0xff,0xff,0xff,0,0,0,0},json(-4294967296)); check_encode_msgpack({0xd3,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff},json(-4294967297)); // null, true, false check_encode_msgpack({0xc0},json::null()); // check_encode_msgpack({0xc3},json(true)); // check_encode_msgpack({0xc2},json(false)); // // floating point check_encode_msgpack({0xca,0,0,0,0},json(0.0)); check_encode_msgpack({0xca,0xbf,0x80,0,0},json(-1.0)); check_encode_msgpack({0xca,0xcb,0x7f,0xff,0xff},json(-16777215.0)); // string check_encode_msgpack({0xa0},json("")); check_encode_msgpack({0xa1,' '},json(" ")); check_encode_msgpack({0xbf,'1','2','3','4','5','6','7','8','9','0', '1','2','3','4','5','6','7','8','9','0', '1','2','3','4','5','6','7','8','9','0', '1'}, json("1234567890123456789012345678901")); check_encode_msgpack({0xd9,0x20,'1','2','3','4','5','6','7','8','9','0', '1','2','3','4','5','6','7','8','9','0', '1','2','3','4','5','6','7','8','9','0', '1','2'}, json("12345678901234567890123456789012")); } TEST_CASE("encode_msgpack_arrays_and_maps") { // fixarray check_encode_msgpack({0x90}, json(json_array_arg)); check_encode_msgpack({0x80},json()); check_encode_msgpack({0x91,'\0'},json::parse("[0]")); check_encode_msgpack({0x92,'\0','\0'}, json(json_array_arg, {0,0})); check_encode_msgpack({0x92,0x91,'\0','\0'}, json::parse("[[0],0]")); check_encode_msgpack({0x91,0xa5,'H','e','l','l','o'},json::parse("[\"Hello\"]")); check_encode_msgpack({0x81,0xa2,'o','c',0x91,'\0'}, json::parse("{\"oc\": [0]}")); check_encode_msgpack({0x81,0xa2,'o','c',0x94,'\0','\1','\2','\3'}, json::parse("{\"oc\": [0, 1, 2, 3]}")); } namespace { namespace ns { struct Person { std::string name; }; }} JSONCONS_ALL_MEMBER_TRAITS(ns::Person, name) #if defined(JSONCONS_HAS_STATEFUL_ALLOCATOR) && JSONCONS_HAS_STATEFUL_ALLOCATOR == 1 #include #include template using MyScopedAllocator = std::scoped_allocator_adaptor>; TEST_CASE("encode_msgpack allocator_set overloads") { MyScopedAllocator temp_alloc(1); auto alloc_set = temp_allocator_only(temp_alloc); SECTION("json, stream") { json person; person.try_emplace("name", "John Smith"); std::string s; std::stringstream ss(s); msgpack::encode_msgpack(alloc_set, person, ss); json other = msgpack::decode_msgpack(alloc_set, ss); CHECK(other == person); } SECTION("custom, stream") { ns::Person person{"John Smith"}; std::string s; std::stringstream ss(s); msgpack::encode_msgpack(alloc_set, person, ss); ns::Person other = msgpack::decode_msgpack(alloc_set, ss); CHECK(other.name == person.name); } } #endif jsoncons-1.3.2/test/msgpack/src/msgpack_bitset_traits_tests.cpp000066400000000000000000000075111477700171100250700ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #include #include #include #include #include using namespace jsoncons; TEST_CASE("MessagePack std::bitset tests") { SECTION("low test") { std::bitset<32> i_bs32(0); std::string s32; msgpack::encode_msgpack(i_bs32, s32); auto o_bs32 = msgpack::decode_msgpack>(s32); CHECK(o_bs32 == i_bs32); std::bitset<64> i_bs64(0); std::string s64; msgpack::encode_msgpack(i_bs64, s64); auto o_bs64 = msgpack::decode_msgpack>(s64); CHECK(o_bs64 == i_bs64); } SECTION("high test") { std::bitset<32> i_bs32(0xffffffff); std::string s32; msgpack::encode_msgpack(i_bs32, s32); auto o_bs32 = msgpack::decode_msgpack>(s32); CHECK(o_bs32 == i_bs32); std::bitset<64> i_bs64(0xffffffffffffffff); std::string s64; msgpack::encode_msgpack(i_bs64, s64); auto o_bs64 = msgpack::decode_msgpack>(s64); CHECK(o_bs64 == i_bs64); } SECTION("random test") { std::random_device rd; std::mt19937 gen(rd()); auto rng32 = [&](){return random_binary_string(gen, 32);}; auto rng65 = [&](){return random_binary_string(gen, 65);}; auto rng128 = [&]() {return random_binary_string(gen, 128); }; auto rng129 = [&]() {return random_binary_string(gen, 129); }; auto rng256 = [&]() {return random_binary_string(gen, 256); }; auto rng257 = [&]() {return random_binary_string(gen, 257); }; auto rng512 = [&](){return random_binary_string(gen, 512);}; auto rng513 = [&](){return random_binary_string(gen, 513);}; for (std::size_t i = 0; i < 100; ++i) { std::bitset<32> i_bs32(rng32()); std::string s32; msgpack::encode_msgpack(i_bs32, s32); auto o_bs32 = msgpack::decode_msgpack>(s32); CHECK(o_bs32 == i_bs32); std::bitset<65> i_bs65(rng65()); std::string s65; msgpack::encode_msgpack(i_bs65, s65); auto o_bs65 = msgpack::decode_msgpack>(s65); CHECK(o_bs65 == i_bs65); std::bitset<128> i_bs128(rng128()); std::string s128; msgpack::encode_msgpack(i_bs128, s128); auto o_bs128 = msgpack::decode_msgpack>(s128); CHECK(o_bs128 == i_bs128); std::bitset<129> i_bs129(rng129()); std::string s129; msgpack::encode_msgpack(i_bs129, s129); auto o_bs129 = msgpack::decode_msgpack>(s129); CHECK(o_bs129 == i_bs129); std::bitset<256> i_bs256(rng256()); std::string s256; msgpack::encode_msgpack(i_bs256, s256); auto o_bs256 = msgpack::decode_msgpack>(s256); CHECK(o_bs256 == i_bs256); std::bitset<257> i_bs257(rng257()); std::string s257; msgpack::encode_msgpack(i_bs257, s257); auto o_bs257 = msgpack::decode_msgpack>(s257); CHECK(o_bs257 == i_bs257); std::bitset<512> i_bs512(rng512()); std::string s512; msgpack::encode_msgpack(i_bs512, s512); auto o_bs512 = msgpack::decode_msgpack>(s512); CHECK(o_bs512 == i_bs512); std::bitset<513> i_bs513(rng513()); std::string s513; msgpack::encode_msgpack(i_bs513, s513); auto o_bs513 = msgpack::decode_msgpack>(s513); CHECK(o_bs513 == i_bs513); } } } jsoncons-1.3.2/test/msgpack/src/msgpack_cursor_tests.cpp000066400000000000000000000320741477700171100235270ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("msgpack_cursor reputon test") { ojson j = ojson::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 } ] } )"); std::vector data; msgpack::encode_msgpack(j, data); SECTION("test 1") { msgpack::msgpack_bytes_cursor cursor(data); CHECK(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::begin_array == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::begin_object == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::string_value == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::key == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::double_value == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::end_array == cursor.current().event_type()); cursor.next(); CHECK(staj_event_type::end_object == cursor.current().event_type()); cursor.next(); CHECK(cursor.done()); } } struct remove_mark_msgpack_filter { bool reject_next_ = false; bool operator()(const staj_event& event, const ser_context&) { if (event.event_type() == staj_event_type::key && event.get() == "mark") { reject_next_ = true; return false; } else if (reject_next_) { reject_next_ = false; return false; } else { return true; } } }; TEST_CASE("msgpack_cursor with filter tests") { auto j = ojson::parse(R"( [ { "enrollmentNo" : 100, "firstName" : "Tom", "lastName" : "Cochrane", "mark" : 55 }, { "enrollmentNo" : 101, "firstName" : "Catherine", "lastName" : "Smith", "mark" : 95 }, { "enrollmentNo" : 102, "firstName" : "William", "lastName" : "Skeleton", "mark" : 60 } ] )"); std::vector data; msgpack::encode_msgpack(j, data); msgpack::msgpack_bytes_cursor cursor(data); auto filtered_c = cursor | remove_mark_msgpack_filter(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::begin_array); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::begin_object); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::uint64_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::string_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::string_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::end_object); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::begin_object); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::uint64_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::string_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::string_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::end_object); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::begin_object); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::uint64_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::string_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::key); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::string_value); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::end_object); filtered_c.next(); REQUIRE_FALSE(filtered_c.done()); CHECK(filtered_c.current().event_type() == staj_event_type::end_array); filtered_c.next(); CHECK(filtered_c.done()); } TEST_CASE("msgpack_parser reset", "") { std::vector input1 = { 0x92,0x01,0x02, // array(2), positive fixint(1), positive fixint(2) 0x81,0xa1,0x63,0x04, // map(1), text(1), "c", positive fixint(4) }; std::vector input2 = { 0x81,0xa1,0x65,0x06, // map(1), text(1), "e", positive fixint(6) }; json expected1 = json::parse(R"([1,2])"); json expected2 = json::parse(R"({"c":4})"); json expected3 = json::parse(R"({"e":6})"); json_decoder destination; item_event_visitor_to_visitor_adaptor visitor{destination}; msgpack::basic_msgpack_parser parser{ input1 }; std::error_code ec; SECTION("keeping same source") { parser.parse(visitor, ec); REQUIRE_FALSE(ec); CHECK(destination.get_result() == expected1); destination.reset(); parser.reset(); parser.parse(visitor, ec); CHECK_FALSE(ec); CHECK(parser.stopped()); // TODO: This fails: CHECK(parser.done()); CHECK(destination.get_result() == expected2); } SECTION("with different source") { parser.parse(visitor, ec); REQUIRE_FALSE(ec); CHECK(destination.get_result() == expected1); destination.reset(); parser.reset(input2); parser.parse(visitor, ec); CHECK_FALSE(ec); CHECK(parser.stopped()); // TODO: This fails: CHECK(parser.done()); CHECK(destination.get_result() == expected3); } } struct msgpack_bytes_cursor_reset_test_traits { using cursor_type = msgpack::msgpack_bytes_cursor; using input_type = std::vector; static void set_input(input_type& input, input_type bytes) {input = bytes;} }; struct msgpack_stream_cursor_reset_test_traits { using cursor_type = msgpack::msgpack_stream_cursor; // binary_stream_source::char_type is actually char, not uint8_t using input_type = std::istringstream; static void set_input(input_type& input, std::vector bytes) { auto data = reinterpret_cast(bytes.data()); std::string s(data, bytes.size()); input.str(s); } }; TEMPLATE_TEST_CASE("msgpack_cursor reset test", "", msgpack_bytes_cursor_reset_test_traits, msgpack_stream_cursor_reset_test_traits) { using traits = TestType; using input_type = typename traits::input_type; using cursor_type = typename traits::cursor_type; using source_type = typename cursor_type::source_type; SECTION("keeping same source") { std::error_code ec; input_type input; traits::set_input(input, { 0xa3, 0x54, 0x6f, 0x6d, // str(3), "Tom" 0xd0, 0x9c, // int8(-100) 0xc0 // nil }); source_type source(input); cursor_type cursor(std::move(source)); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::string_value == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); CHECK(std::string("Tom") == cursor.current().template get()); CHECK(cursor.current().template get() == jsoncons::string_view("Tom")); cursor.next(); CHECK(cursor.done()); cursor.reset(); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::int64_value == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); CHECK(-100 == cursor.current().template get()); cursor.next(); CHECK(cursor.done()); cursor.reset(ec); REQUIRE_FALSE(ec); REQUIRE_FALSE(cursor.done()); CHECK(staj_event_type::null_value == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); cursor.next(ec); REQUIRE_FALSE(ec); CHECK(cursor.done()); } SECTION("with another source") { std::error_code ec; input_type input0; input_type input1; input_type input2; input_type input3; traits::set_input(input0, {}); traits::set_input(input1, {0xa3, 0x54, 0x6f, 0x6d}); // str(3), "Tom" traits::set_input(input2, {0xc1}); // never used traits::set_input(input3, {0xd0, 0x9c}); // int8(-100) // Constructing cursor with blank input results in unexpected_eof // error because it eagerly parses the next event upon construction. cursor_type cursor(input0, ec); CHECK(ec == msgpack::msgpack_errc::unexpected_eof); CHECK_FALSE(cursor.done()); // Reset to valid input1 cursor.reset(input1); CHECK(staj_event_type::string_value == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); CHECK(std::string("Tom") == cursor.current().template get()); CHECK(cursor.current().template get() == jsoncons::string_view("Tom")); ec = msgpack::msgpack_errc::success; REQUIRE_FALSE(cursor.done()); cursor.next(ec); CHECK_FALSE(ec); CHECK(cursor.done()); // Reset to invalid input2 ec = msgpack::msgpack_errc::success; cursor.reset(input2, ec); CHECK(ec == msgpack::msgpack_errc::unknown_type); CHECK_FALSE(cursor.done()); // Reset to valid input3 ec = msgpack::msgpack_errc::success; cursor.reset(input3, ec); REQUIRE_FALSE(ec); CHECK(staj_event_type::int64_value == cursor.current().event_type()); CHECK(semantic_tag::none == cursor.current().tag()); CHECK(-100 == cursor.current().template get()); REQUIRE_FALSE(cursor.done()); cursor.next(ec); CHECK_FALSE(ec); CHECK(cursor.done()); } } jsoncons-1.3.2/test/msgpack/src/msgpack_encoder_tests.cpp000066400000000000000000000141351477700171100236270ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("serialize array to msgpack") { std::vector v; msgpack::msgpack_bytes_encoder encoder(v); //encoder.begin_object(1); encoder.begin_array(3); encoder.bool_value(true); encoder.bool_value(false); encoder.null_value(); encoder.end_array(); //encoder.end_object(); encoder.flush(); json result; REQUIRE_NOTHROW(result = msgpack::decode_msgpack(v)); } TEST_CASE("serialize object to msgpack") { SECTION("definite length") { std::vector v; msgpack::msgpack_bytes_encoder encoder(v); encoder.begin_object(2); encoder.uint64_value(1); encoder.string_value("value1"); encoder.uint64_value(2); encoder.string_value("value2"); REQUIRE_NOTHROW(encoder.end_object()); encoder.flush(); json result; REQUIRE_NOTHROW(result = msgpack::decode_msgpack(v)); } } TEST_CASE("Too many and too few items in MessagePack object or array") { std::vector v; msgpack::msgpack_bytes_encoder encoder(v); SECTION("Too many items in array") { encoder.begin_array(3); encoder.bool_value(true); encoder.bool_value(false); encoder.null_value(); encoder.begin_array(2); encoder.string_value("cat"); encoder.string_value("feline"); encoder.end_array(); REQUIRE_THROWS_WITH(encoder.end_array(), msgpack::msgpack_error_category_impl().message((int)msgpack::msgpack_errc::too_many_items).c_str()); encoder.flush(); } SECTION("Too few items in array") { encoder.begin_array(5); encoder.bool_value(true); encoder.bool_value(false); encoder.null_value(); encoder.begin_array(2); encoder.string_value("cat"); encoder.string_value("feline"); encoder.end_array(); REQUIRE_THROWS_WITH(encoder.end_array(), msgpack::msgpack_error_category_impl().message((int)msgpack::msgpack_errc::too_few_items).c_str()); encoder.flush(); } SECTION("Too many items in object") { encoder.begin_object(3); encoder.key("a"); encoder.bool_value(true); encoder.key("b"); encoder.bool_value(false); encoder.key("c"); encoder.null_value(); encoder.key("d"); encoder.begin_array(2); encoder.string_value("cat"); encoder.string_value("feline"); encoder.end_array(); REQUIRE_THROWS_WITH(encoder.end_object(), msgpack::msgpack_error_category_impl().message((int)msgpack::msgpack_errc::too_many_items).c_str()); encoder.flush(); } SECTION("Too few items in object") { encoder.begin_object(5); encoder.key("a"); encoder.bool_value(true); encoder.key("b"); encoder.bool_value(false); encoder.key("c"); encoder.null_value(); encoder.key("d"); encoder.begin_array(2); encoder.string_value("cat"); encoder.string_value("feline"); encoder.end_array(); REQUIRE_THROWS_WITH(encoder.end_object(), msgpack::msgpack_error_category_impl().message((int)msgpack::msgpack_errc::too_few_items).c_str()); encoder.flush(); } } struct msgpack_bytes_encoder_reset_test_fixture { std::vector output1; std::vector output2; msgpack::msgpack_bytes_encoder encoder; msgpack_bytes_encoder_reset_test_fixture() : encoder(output1) {} std::vector bytes1() const {return output1;} std::vector bytes2() const {return output2;} }; struct msgpack_stream_encoder_reset_test_fixture { std::ostringstream output1; std::ostringstream output2; msgpack::msgpack_stream_encoder encoder; msgpack_stream_encoder_reset_test_fixture() : encoder(output1) {} std::vector bytes1() const {return bytes_of(output1);} std::vector bytes2() const {return bytes_of(output2);} private: static std::vector bytes_of(const std::ostringstream& os) { auto str = os.str(); auto data = reinterpret_cast(str.data()); std::vector bytes(data, data + str.size()); return bytes; } }; TEMPLATE_TEST_CASE("test_msgpack_encoder_reset", "", msgpack_bytes_encoder_reset_test_fixture, msgpack_stream_encoder_reset_test_fixture) { using fixture_type = TestType; fixture_type f; std::vector expected_partial = { 0x92, // array(2) 0xa3, // fixstr(3) 0x66, 0x6F, 0x6F // "foo" // second element missing }; std::vector expected_full = { 0x92, // array(2) 0xa3, // fixstr(3) 0x66, 0x6F, 0x6F, // "foo" 0x2A // positive fixint(42) }; std::vector expected_partial_then_full(expected_partial); expected_partial_then_full.insert(expected_partial_then_full.end(), expected_full.begin(), expected_full.end()); // Parially encode, reset, then fully encode to same sink f.encoder.begin_array(2); f.encoder.string_value("foo"); f.encoder.flush(); CHECK(f.bytes1() == expected_partial); f.encoder.reset(); f.encoder.begin_array(2); f.encoder.string_value("foo"); f.encoder.uint64_value(42); f.encoder.end_array(); f.encoder.flush(); CHECK(f.bytes1() == expected_partial_then_full); // Reset and encode to different sink f.encoder.reset(f.output2); f.encoder.begin_array(2); f.encoder.string_value("foo"); f.encoder.uint64_value(42); f.encoder.end_array(); f.encoder.flush(); CHECK(f.bytes2() == expected_full); } jsoncons-1.3.2/test/msgpack/src/msgpack_event_reader_tests.cpp000066400000000000000000000160321477700171100246510ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include #include using namespace jsoncons; TEST_CASE("msgpack_event_reader reputon test") { ojson j = ojson::parse(R"( { "application": "hiking", "reputons": [ { "rater": "HikingAsylum", "assertion": "advanced", "rated": "Marilyn C", "rating": 0.90 } ] } )"); std::vector data; msgpack::encode_msgpack(j, data); SECTION("test 1") { msgpack::msgpack_event_reader reader(data); CHECK(reader.current().event_type() == staj_event_type::begin_object); reader.next(); CHECK(reader.current().event_type() == staj_event_type::string_value); // key reader.next(); CHECK(reader.current().event_type() == staj_event_type::string_value); reader.next(); CHECK(reader.current().event_type() == staj_event_type::string_value); // key reader.next(); CHECK(reader.current().event_type() == staj_event_type::begin_array); reader.next(); CHECK(reader.current().event_type() == staj_event_type::begin_object); reader.next(); CHECK(reader.current().event_type() == staj_event_type::string_value); // key reader.next(); CHECK(reader.current().event_type() == staj_event_type::string_value); reader.next(); CHECK(reader.current().event_type() == staj_event_type::string_value); // key reader.next(); CHECK(reader.current().event_type() == staj_event_type::string_value); reader.next(); CHECK(reader.current().event_type() == staj_event_type::string_value); // key reader.next(); CHECK(reader.current().event_type() == staj_event_type::string_value); reader.next(); CHECK(reader.current().event_type() == staj_event_type::string_value); // key reader.next(); CHECK(reader.current().event_type() == staj_event_type::double_value); reader.next(); CHECK(reader.current().event_type() == staj_event_type::end_object); reader.next(); CHECK(reader.current().event_type() == staj_event_type::end_array); reader.next(); CHECK(reader.current().event_type() == staj_event_type::end_object); reader.next(); CHECK(reader.done()); } } struct msgpack_bytes_cursor2_reset_test_traits { using event_reader_type = msgpack::msgpack_event_reader; using input_type = std::vector; static void set_input(input_type& input, input_type bytes) {input = bytes;} }; struct msgpack_stream_cursor2_reset_test_traits { using event_reader_type = msgpack::msgpack_event_reader; // binary_stream_source::char_type is actually char, not uint8_t using input_type = std::istringstream; static void set_input(input_type& input, std::vector bytes) { auto data = reinterpret_cast(bytes.data()); std::string s(data, bytes.size()); input.str(s); } }; TEMPLATE_TEST_CASE("msgpack_event_reader reset test", "", msgpack_bytes_cursor2_reset_test_traits, msgpack_stream_cursor2_reset_test_traits) { using traits = TestType; using input_type = typename traits::input_type; using event_reader_type = typename traits::event_reader_type; using source_type = typename event_reader_type::source_type; SECTION("keeping same source") { std::error_code ec; input_type input; traits::set_input(input, { 0xa3, 0x54, 0x6f, 0x6d, // str(3), "Tom" 0xd0, 0x9c, // int8(-100) 0xc0 // nil }); source_type source(input); event_reader_type reader(std::move(source)); REQUIRE_FALSE(reader.done()); CHECK(reader.current().event_type() == staj_event_type::string_value); CHECK(reader.current().tag() == semantic_tag::none); CHECK(reader.current().template get() == std::string("Tom")); CHECK(reader.current().template get() == jsoncons::string_view("Tom")); reader.next(); CHECK(reader.done()); reader.reset(); REQUIRE_FALSE(reader.done()); CHECK(reader.current().event_type() == staj_event_type::int64_value); CHECK(reader.current().tag() == semantic_tag::none); CHECK(reader.current().template get() == -100); reader.next(); CHECK(reader.done()); reader.reset(ec); REQUIRE_FALSE(ec); REQUIRE_FALSE(reader.done()); CHECK(reader.current().event_type() == staj_event_type::null_value); CHECK(reader.current().tag() == semantic_tag::none); reader.next(ec); REQUIRE_FALSE(ec); CHECK(reader.done()); } SECTION("with another source") { std::error_code ec; input_type input0; input_type input1; input_type input2; input_type input3; traits::set_input(input0, {}); traits::set_input(input1, {0xa3, 0x54, 0x6f, 0x6d}); // str(3), "Tom" traits::set_input(input2, {0xc1}); // never used traits::set_input(input3, {0xd0, 0x9c}); // int8(-100) // Constructing reader with blank input results in unexpected_eof // error because it eagerly parses the next event upon construction. event_reader_type reader(input0, ec); CHECK(ec == msgpack::msgpack_errc::unexpected_eof); CHECK_FALSE(reader.done()); // Reset to valid input1 reader.reset(input1); CHECK(reader.current().event_type() == staj_event_type::string_value); CHECK(reader.current().tag() == semantic_tag::none); CHECK(reader.current().template get() == std::string("Tom")); CHECK(reader.current().template get() == jsoncons::string_view("Tom")); ec = msgpack::msgpack_errc::success; REQUIRE_FALSE(reader.done()); reader.next(ec); CHECK_FALSE(ec); CHECK(reader.done()); // Reset to invalid input2 reader.reset(input2, ec); CHECK(ec == msgpack::msgpack_errc::unknown_type); CHECK_FALSE(reader.done()); // Reset to valid input3 ec = msgpack::msgpack_errc::success; reader.reset(input3, ec); REQUIRE_FALSE(ec); CHECK(reader.current().event_type() == staj_event_type::int64_value); CHECK(reader.current().tag() == semantic_tag::none); CHECK(reader.current().template get() == -100); REQUIRE_FALSE(reader.done()); reader.next(ec); CHECK_FALSE(ec); CHECK(reader.done()); } } jsoncons-1.3.2/test/msgpack/src/msgpack_tests.cpp000066400000000000000000000347571477700171100221440ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include using namespace jsoncons; using namespace jsoncons::msgpack; TEST_CASE("msgpack_test") { json j1; j1["zero"] = 0; j1["one"] = 1; j1["two"] = 2; j1["null"] = null_type(); j1["true"] = true; j1["false"] = false; j1["max int64_t"] = (std::numeric_limits::max)(); j1["max uint64_t"] = (std::numeric_limits::max)(); j1["min int64_t"] = (std::numeric_limits::lowest)(); j1["max int32_t"] = (std::numeric_limits::max)(); j1["max uint32_t"] = (std::numeric_limits::max)(); j1["min int32_t"] = (std::numeric_limits::lowest)(); j1["max int16_t"] = (std::numeric_limits::max)(); j1["max uint16_t"] = (std::numeric_limits::max)(); j1["min int16_t"] = (std::numeric_limits::lowest)(); j1["max int8_t"] = (std::numeric_limits::max)(); j1["max uint8_t"] = (std::numeric_limits::max)(); j1["min int8_t"] = (std::numeric_limits::lowest)(); j1["max double"] = (std::numeric_limits::max)(); j1["min double"] = (std::numeric_limits::lowest)(); j1["max float"] = (std::numeric_limits::max)(); j1["zero float"] = 0.0; j1["min float"] = (std::numeric_limits::lowest)(); j1["String too long for small string optimization"] = "String too long for small string optimization"; json ja(json_array_arg); ja.push_back(0); ja.push_back(1); ja.push_back(2); ja.push_back(null_type()); ja.push_back(true); ja.push_back(false); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::lowest)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::lowest)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::lowest)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::lowest)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::lowest)()); ja.push_back((std::numeric_limits::max)()); ja.push_back(0.0); ja.push_back((std::numeric_limits::lowest)()); ja.push_back("String too long for small string optimization"); j1["An array"] = ja; std::vector v; encode_msgpack(j1, v); // from bytes json j2 = decode_msgpack(v); CHECK(j2 == j1); // from pair of iterators json j3 = decode_msgpack(v.begin(), v.end()); CHECK(j3 == j1); } TEST_CASE("msgpack_test2") { wjson j1; j1[L"zero"] = 0; j1[L"one"] = 1; j1[L"two"] = 2; j1[L"null"] = null_type(); j1[L"true"] = true; j1[L"false"] = false; j1[L"max int64_t"] = (std::numeric_limits::max)(); j1[L"max uint64_t"] = (std::numeric_limits::max)(); j1[L"min int64_t"] = (std::numeric_limits::lowest)(); j1[L"max int32_t"] = (std::numeric_limits::max)(); j1[L"max uint32_t"] = (std::numeric_limits::max)(); j1[L"min int32_t"] = (std::numeric_limits::lowest)(); j1[L"max int16_t"] = (std::numeric_limits::max)(); j1[L"max uint16_t"] = (std::numeric_limits::max)(); j1[L"min int16_t"] = (std::numeric_limits::lowest)(); j1[L"max int8_t"] = (std::numeric_limits::max)(); j1[L"max uint8_t"] = (std::numeric_limits::max)(); j1[L"min int8_t"] = (std::numeric_limits::lowest)(); j1[L"max double"] = (std::numeric_limits::max)(); j1[L"min double"] = (std::numeric_limits::lowest)(); j1[L"max float"] = (std::numeric_limits::max)(); j1[L"zero float"] = 0.0; j1[L"min float"] = (std::numeric_limits::lowest)(); j1[L"S"] = L"S"; j1[L"String too long for small string optimization"] = L"String too long for small string optimization"; wjson ja(json_array_arg); ja.push_back(0); ja.push_back(1); ja.push_back(2); ja.push_back(null_type()); ja.push_back(true); ja.push_back(false); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::lowest)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::lowest)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::lowest)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::lowest)()); ja.push_back((std::numeric_limits::max)()); ja.push_back((std::numeric_limits::lowest)()); ja.push_back((std::numeric_limits::max)()); ja.push_back(0.0); ja.push_back((std::numeric_limits::lowest)()); ja.push_back(L"S"); ja.push_back(L"String too long for small string optimization"); j1[L"An array"] = ja; std::vector v; encode_msgpack(j1, v); //wjson j2 = decode_msgpack(v); //CHECK(j2 == j1); } // Includes test cases from https://github.com/kawanet/msgpack-test-suite, MIT license TEST_CASE("msgpack bin tests") { SECTION("[]") { std::vector expected; std::vector input1 = {0xc4,0x00}; auto v1 = decode_msgpack>(input1); CHECK(expected == v1); std::vector input2 = {0xc5,0x00,0x00}; auto v2 = decode_msgpack>(input2); CHECK(expected == v2); std::vector input3 = {0xc6,0x00,0x00,0x00,0x00}; auto v3 = decode_msgpack>(input3); CHECK(expected == v3); std::vector output1; encode_msgpack(byte_string_view(v1),output1); CHECK(output1 == input1); } SECTION("[1]") { std::vector expected = {1}; std::vector input1 = {0xc4,0x01,0x01}; auto v1 = decode_msgpack>(input1); CHECK(expected == v1); std::vector input2 = {0xc5,0x00,0x01,0x01}; auto v2 = decode_msgpack>(input2); CHECK(expected == v2); std::vector input3 = {0xc6,0x00,0x00,0x00,0x01,0x01}; auto v3 = decode_msgpack>(input3); CHECK(expected == v3); std::vector output1; encode_msgpack(byte_string_view(v1),output1); CHECK(output1 == input1); } SECTION("[0,255]") { std::vector expected = {0,255}; std::vector input1 = {0xc4,0x02,0x00,0xff}; auto v1 = decode_msgpack>(input1); CHECK(expected == v1); std::vector input2 = {0xc5,0x00,0x02,0x00,0xff}; auto v2 = decode_msgpack>(input2); CHECK(expected == v2); std::vector input3 = {0xc6,0x00,0x00,0x00,0x02,0x00,0xff}; auto v3 = decode_msgpack>(input3); CHECK(expected == v3); std::vector output1; encode_msgpack(byte_string_view(v1),output1); CHECK(output1 == input1); } } TEST_CASE("msgpack ext tests") { SECTION("fixext1, 1, [0x10]") { std::vector expected = {0x10}; std::vector input = {0xd4,0x01,0x10}; auto v = decode_msgpack>(input); CHECK(expected == v); auto j = decode_msgpack(input); std::vector output; encode_msgpack(j, output); CHECK(output == input); } SECTION("fixext2, 2, [20,21]") { std::vector expected = {0x20,0x21}; std::vector input = {0xd5,0x02,0x20,0x21}; auto v = decode_msgpack>(input); CHECK(expected == (v)); auto j = decode_msgpack(input); std::vector output; encode_msgpack(j, output); CHECK(output == input); } SECTION("fixext4, 3, [0x30,0x31,0x32,0x33]") { std::vector expected = {0x30,0x31,0x32,0x33}; std::vector input = {0xd6,0x03,0x30,0x31,0x32,0x33}; auto v = decode_msgpack>(input); CHECK(expected == v); auto j = decode_msgpack(input); std::vector output; encode_msgpack(j, output); CHECK(output == input); } SECTION("fixext8, 4, [0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47]") { std::vector expected = {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47}; std::vector input = {0xd7,0x04,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47}; auto v = decode_msgpack>(input); CHECK(expected == v); auto j = decode_msgpack(input); std::vector output; encode_msgpack(j, output); CHECK(output == input); } SECTION("fixext16, 5, [0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f]") { std::vector expected = {0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f}; std::vector input = {0xd8,0x05,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f}; auto v = decode_msgpack>(input); CHECK(expected == v); auto j = decode_msgpack(input); std::vector output; encode_msgpack(j, output); CHECK(output == input); } SECTION("ext, size 0") { std::vector expected = {}; // ext8 std::vector input1 = {0xc7,0x00,0x06}; auto v = decode_msgpack>(input1); CHECK(expected == v); auto j1 = decode_msgpack(input1); std::vector output1; encode_msgpack(j1, output1); CHECK(output1 == input1); // ext16 std::vector input2 = {0xc8,0x00,0x00,0x06}; auto v2 = decode_msgpack>(input2); CHECK(expected == v2); auto j2 = decode_msgpack(input2); std::vector output2; encode_msgpack(j2, output2); CHECK(output2 == input1); // ext32 std::vector input3 = {0xc9,0x00,0x00,0x00,0x00,0x06}; auto v3 = decode_msgpack>(input3); CHECK(expected == v3); auto j3 = decode_msgpack(input3); std::vector output3; encode_msgpack(j3, output3); CHECK(output3 == input1); } SECTION("ext, size 3") { std::vector expected = {0x70,0x71,0x72}; // ext8 std::vector input1 = {0xc7,0x03,0x07,0x70,0x71,0x72}; auto v = decode_msgpack>(input1); CHECK(expected == v); auto j1 = decode_msgpack(input1); std::vector output1; encode_msgpack(j1, output1); CHECK(output1 == input1); // ext16 std::vector input2 = {0xc8,0x00,0x03,0x07,0x70,0x71,0x72}; auto v2 = decode_msgpack>(input2); CHECK(expected == v2); auto j2 = decode_msgpack(input2); std::vector output2; encode_msgpack(j2, output2); CHECK(output2 == input1); // ext32 std::vector input3 = {0xc9,0x00,0x00,0x00,0x03,0x07,0x70,0x71,0x72}; auto v3 = decode_msgpack>(input3); CHECK(expected == v3); auto j3 = decode_msgpack(input3); std::vector output3; encode_msgpack(j3, output3); CHECK(output3 == input1); } } namespace { namespace ns { struct Person { std::string name; }; }} JSONCONS_ALL_MEMBER_TRAITS(ns::Person, name) TEST_CASE("encode_msgpack overloads") { SECTION("json, stream") { json person; person.try_emplace("name", "John Smith"); std::string s; std::stringstream ss(s); msgpack::encode_msgpack(person, ss); json other = msgpack::decode_msgpack(ss); CHECK(other == person); } SECTION("custom, stream") { ns::Person person{"John Smith"}; std::string s; std::stringstream ss(s); msgpack::encode_msgpack(person, ss); ns::Person other = msgpack::decode_msgpack(ss); CHECK(other.name == person.name); } } #if (defined(__GNUC__) || defined(__clang__)) && defined(JSONCONS_HAS_INT128) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" TEST_CASE("msgpack json constructor __int64 tests") { SECTION("test 1") { json j1("-18446744073709551617", semantic_tag::bigint); __int128 val1 = j1.as<__int128>(); std::vector expected = {0xb5,0x2d,0x31,0x38,0x34,0x34,0x36,0x37,0x34,0x34,0x30,0x37,0x33,0x37,0x30,0x39,0x35,0x35,0x31,0x36,0x31,0x37}; std::vector data; msgpack::encode_msgpack(val1, data); CHECK(expected == data); auto val2 = msgpack::decode_msgpack<__int128>(data); CHECK((val2 == val1)); } } TEST_CASE("msgpack json constructor unsigned __int64 tests") { SECTION("test 1") { json j1("18446744073709551616", semantic_tag::bigint); auto val1 = j1.as(); std::vector expected = {0xb4,0x31,0x38,0x34,0x34,0x36,0x37,0x34,0x34,0x30,0x37,0x33,0x37,0x30,0x39,0x35,0x35,0x31,0x36,0x31,0x36}; std::vector data; msgpack::encode_msgpack(val1, data); CHECK(expected == data); auto val2 = msgpack::decode_msgpack(data); CHECK((val2 == val1)); } } #pragma GCC diagnostic pop #endif jsoncons-1.3.2/test/msgpack/src/msgpack_timestamp_tests.cpp000066400000000000000000000061131477700171100242100ustar00rootroot00000000000000// Copyright 2013-2025 Daniel Parker // Distributed under Boost license #if defined(_MSC_VER) #include "windows.h" // test no inadvertant macro expansions #endif #include #include #include #include #include #include #include #include using namespace jsoncons; using namespace jsoncons::msgpack; TEST_CASE("msgpack timestamp tests") { SECTION("test 1") { std::vector u = {0xce,0x5a,0x4a,0xf6,0xa5}; uint64_t expected = decode_msgpack(u); CHECK(expected == 1514862245); std::vector input = {0xd6,0xff,0x5a,0x4a,0xf6,0xa5}; auto r = decode_msgpack(input); CHECK(expected == r); std::vector output; json j = decode_msgpack(input); encode_msgpack(j,output); CHECK(output == input); } SECTION("test 2") { std::vector expected = {1514862245,678901234}; std::vector input = {0xd7,0xff,0xa1,0xdc,0xd7,0xc8,0x5a,0x4a,0xf6,0xa5}; auto r = decode_msgpack(input); std::cout << pretty_print(r) << "\n\n"; //CHECK(expected == r); } SECTION("test 3") { std::vector expected = {-int64_t(2208988801),999999999}; std::vector input = {0xc7,0x0c,0xff,0x3b,0x9a,0xc9,0xff,0xff,0xff,0xff,0xff,0x7c,0x55,0x81,0x7f}; auto r = decode_msgpack(input); std::cout << pretty_print(r) << "\n\n"; //CHECK(expected == r); //std::vector output; //json j = decode_msgpack(input); //encode_msgpack(j,output); //CHECK(output == input); } SECTION("test 4") { std::vector expected = {2147483648,1}; std::vector input = {0xd7,0xff,0x00,0x00,0x00,0x04,0x80,0x00,0x00,0x00}; auto r = decode_msgpack(input); std::cout << r << "\n\n"; //CHECK(expected == r); //std::vector output; //json j = decode_msgpack(input); //encode_msgpack(j,output); //CHECK(output == input); } SECTION("test 5") { std::vector expected = {-int64_t(2208988801),999999999}; std::vector input = { 0xc7,0x0c,0xff, // timestamp 96 0x3b,0x9a,0xc9,0xff, // 999999999 nanoseconds in 32-bit unsigned int 0xff,0xff,0xff,0xff,0x7c,0x55,0x81,0x7f // -2208988801 seconds in 64-bit signed int }; auto j = decode_msgpack(input); std::cout << "j: " << j << "\n\n"; auto milliseconds = j.as(); std::cout << "milliseconds elapsed since 1970-01-01 00:00:00 UTC: " << milliseconds.count() << "\n"; std::vector data; msgpack::encode_msgpack(milliseconds, data); std::cout << "MessagePack bytes:\n" << jsoncons::byte_string_view(data) << "\n\n"; auto j2 = decode_msgpack(data); std::cout << "j2: " << j2 << "\n\n"; } } jsoncons-1.3.2/test/thirdparty/000077500000000000000000000000001477700171100165275ustar00rootroot00000000000000jsoncons-1.3.2/test/thirdparty/catch/000077500000000000000000000000001477700171100176115ustar00rootroot00000000000000jsoncons-1.3.2/test/thirdparty/catch/catch.hpp000066400000000000000000024100321477700171100214060ustar00rootroot00000000000000/* * Catch v2.13.10 * Generated: 2022-10-16 11:01:23.452308 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly * Copyright (c) 2022 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED // start catch.hpp #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 13 #define CATCH_VERSION_PATCH 10 #ifdef __clang__ # pragma clang system_header #elif defined __GNUC__ # pragma GCC system_header #endif // start catch_suppress_warnings.h #ifdef __clang__ # ifdef __ICC // icpc defines the __clang__ macro # pragma warning(push) # pragma warning(disable: 161 1682) # else // __ICC # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wpadded" # pragma clang diagnostic ignored "-Wswitch-enum" # pragma clang diagnostic ignored "-Wcovered-switch-default" # endif #elif defined __GNUC__ // Because REQUIREs trigger GCC's -Wparentheses, and because still // supported version of g++ have only buggy support for _Pragmas, // Wparentheses have to be suppressed globally. # pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wunused-variable" # pragma GCC diagnostic ignored "-Wpadded" #endif // end catch_suppress_warnings.h #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) # define CATCH_IMPL # define CATCH_CONFIG_ALL_PARTS #endif // In the impl file, we want to have access to all parts of the headers // Can also be used to sanely support PCHs #if defined(CATCH_CONFIG_ALL_PARTS) # define CATCH_CONFIG_EXTERNAL_INTERFACES # if defined(CATCH_CONFIG_DISABLE_MATCHERS) # undef CATCH_CONFIG_DISABLE_MATCHERS # endif # if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) # define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER # endif #endif #if !defined(CATCH_CONFIG_IMPL_ONLY) // start catch_platform.h // See e.g.: // https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html #ifdef __APPLE__ # include # if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \ (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1) # define CATCH_PLATFORM_MAC # elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1) # define CATCH_PLATFORM_IPHONE # endif #elif defined(linux) || defined(__linux) || defined(__linux__) # define CATCH_PLATFORM_LINUX #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) # define CATCH_PLATFORM_WINDOWS #endif // end catch_platform.h #ifdef CATCH_IMPL # ifndef CLARA_CONFIG_MAIN # define CLARA_CONFIG_MAIN_NOT_DEFINED # define CLARA_CONFIG_MAIN # endif #endif // start catch_user_interfaces.h namespace Catch { unsigned int rngSeed(); } // end catch_user_interfaces.h // start catch_tag_alias_autoregistrar.h // start catch_common.h // start catch_compiler_capabilities.h // Detect a number of compiler features - by compiler // The following features are defined: // // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? // CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled? // **************** // Note to maintainers: if new toggles are added please document them // in configuration.md, too // **************** // In general each macro has a _NO_ form // (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature. // Many features, at point of detection, define an _INTERNAL_ macro, so they // can be combined, en-mass, with the _NO_ forms later. #ifdef __cplusplus # if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) # define CATCH_CPP14_OR_GREATER # endif # if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) # define CATCH_CPP17_OR_GREATER # endif #endif // Only GCC compiler should be used in this block, so other compilers trying to // mask themselves as GCC should be ignored. #if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__) # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) # define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) #endif #if defined(__clang__) # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) // As of this writing, IBM XL's implementation of __builtin_constant_p has a bug // which results in calls to destructors being emitted for each temporary, // without a matching initialization. In practice, this can result in something // like `std::string::~string` being called on an uninitialized value. // // For example, this code will likely segfault under IBM XL: // ``` // REQUIRE(std::string("12") + "34" == "1234") // ``` // // Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. # if !defined(__ibmxl__) && !defined(__CUDACC__) # define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ # endif # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) # define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) # define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ _Pragma( "clang diagnostic ignored \"-Wunused-template\"" ) #endif // __clang__ //////////////////////////////////////////////////////////////////////////////// // Assume that non-Windows platforms support posix signals by default #if !defined(CATCH_PLATFORM_WINDOWS) #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS #endif //////////////////////////////////////////////////////////////////////////////// // We know some environments not to support full POSIX signals #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS #endif #ifdef __OS400__ # define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS # define CATCH_CONFIG_COLOUR_NONE #endif //////////////////////////////////////////////////////////////////////////////// // Android somehow still does not support std::to_string #if defined(__ANDROID__) # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING # define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE #endif //////////////////////////////////////////////////////////////////////////////// // Not all Windows environments support SEH properly #if defined(__MINGW32__) # define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH #endif //////////////////////////////////////////////////////////////////////////////// // PS4 #if defined(__ORBIS__) # define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE #endif //////////////////////////////////////////////////////////////////////////////// // Cygwin #ifdef __CYGWIN__ // Required for some versions of Cygwin to declare gettimeofday // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin # define _BSD_SOURCE // some versions of cygwin (most) do not support std::to_string. Use the libstd check. // https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813 # if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \ && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING # endif #endif // __CYGWIN__ //////////////////////////////////////////////////////////////////////////////// // Visual C++ #if defined(_MSC_VER) // Universal Windows platform does not support SEH // Or console colours (or console at all...) # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) # define CATCH_CONFIG_COLOUR_NONE # else # define CATCH_INTERNAL_CONFIG_WINDOWS_SEH # endif # if !defined(__clang__) // Handle Clang masquerading for msvc // MSVC traditional preprocessor needs some workaround for __VA_ARGS__ // _MSVC_TRADITIONAL == 0 means new conformant preprocessor // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor # if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) # define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR # endif // MSVC_TRADITIONAL // Only do this if we're not using clang on Windows, which uses `diagnostic push` & `diagnostic pop` # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) # endif // __clang__ #endif // _MSC_VER #if defined(_REENTRANT) || defined(_MSC_VER) // Enable async processing, as -pthread is specified or no additional linking is required # define CATCH_INTERNAL_CONFIG_USE_ASYNC #endif // _MSC_VER //////////////////////////////////////////////////////////////////////////////// // Check if we are compiled with -fno-exceptions or equivalent #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND) # define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED #endif //////////////////////////////////////////////////////////////////////////////// // DJGPP #ifdef __DJGPP__ # define CATCH_INTERNAL_CONFIG_NO_WCHAR #endif // __DJGPP__ //////////////////////////////////////////////////////////////////////////////// // Embarcadero C++Build #if defined(__BORLANDC__) #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN #endif //////////////////////////////////////////////////////////////////////////////// // Use of __COUNTER__ is suppressed during code analysis in // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly // handled by it. // Otherwise all supported compilers support COUNTER macro, // but user still might want to turn it off #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L ) #define CATCH_INTERNAL_CONFIG_COUNTER #endif //////////////////////////////////////////////////////////////////////////////// // RTX is a special version of Windows that is real time. // This means that it is detected as Windows, but does not provide // the same set of capabilities as real Windows does. #if defined(UNDER_RTSS) || defined(RTX64_BUILD) #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH #define CATCH_INTERNAL_CONFIG_NO_ASYNC #define CATCH_CONFIG_COLOUR_NONE #endif #if !defined(_GLIBCXX_USE_C99_MATH_TR1) #define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER #endif // Various stdlib support checks that require __has_include #if defined(__has_include) // Check if string_view is available and usable #if __has_include() && defined(CATCH_CPP17_OR_GREATER) # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW #endif // Check if optional is available and usable # if __has_include() && defined(CATCH_CPP17_OR_GREATER) # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) // Check if byte is available and usable # if __has_include() && defined(CATCH_CPP17_OR_GREATER) # include # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0) # define CATCH_INTERNAL_CONFIG_CPP17_BYTE # endif # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) // Check if variant is available and usable # if __has_include() && defined(CATCH_CPP17_OR_GREATER) # if defined(__clang__) && (__clang_major__ < 8) // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852 // fix should be in clang 8, workaround in libstdc++ 8.2 # include # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) # define CATCH_CONFIG_NO_CPP17_VARIANT # else # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) # else # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT # endif // defined(__clang__) && (__clang_major__ < 8) # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) #endif // defined(__has_include) #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) # define CATCH_CONFIG_COUNTER #endif #if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) # define CATCH_CONFIG_WINDOWS_SEH #endif // This is set by default, because we assume that unix compilers are posix-signal-compatible by default. #if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) # define CATCH_CONFIG_POSIX_SIGNALS #endif // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions. #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) # define CATCH_CONFIG_WCHAR #endif #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) # define CATCH_CONFIG_CPP11_TO_STRING #endif #if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL) # define CATCH_CONFIG_CPP17_OPTIONAL #endif #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) # define CATCH_CONFIG_CPP17_STRING_VIEW #endif #if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT) # define CATCH_CONFIG_CPP17_VARIANT #endif #if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE) # define CATCH_CONFIG_CPP17_BYTE #endif #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) # define CATCH_INTERNAL_CONFIG_NEW_CAPTURE #endif #if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE) # define CATCH_CONFIG_NEW_CAPTURE #endif #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) # define CATCH_CONFIG_DISABLE_EXCEPTIONS #endif #if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN) # define CATCH_CONFIG_POLYFILL_ISNAN #endif #if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) # define CATCH_CONFIG_USE_ASYNC #endif #if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE) # define CATCH_CONFIG_ANDROID_LOGWRITE #endif #if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) # define CATCH_CONFIG_GLOBAL_NEXTAFTER #endif // Even if we do not think the compiler has that warning, we still have // to provide a macro that can be used by the code. #if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION #endif #if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION) # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION #endif #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS #endif #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS #endif #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS #endif #if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) # define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS #endif // The goal of this macro is to avoid evaluation of the arguments, but // still have the compiler warn on problems inside... #if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN) # define CATCH_INTERNAL_IGNORE_BUT_WARN(...) #endif #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) # undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS #elif defined(__clang__) && (__clang_major__ < 5) # undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS #endif #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS) # define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS #endif #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) #define CATCH_TRY if ((true)) #define CATCH_CATCH_ALL if ((false)) #define CATCH_CATCH_ANON(type) if ((false)) #else #define CATCH_TRY try #define CATCH_CATCH_ALL catch (...) #define CATCH_CATCH_ANON(type) catch (type) #endif #if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) #define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #endif // end catch_compiler_capabilities.h #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) #ifdef CATCH_CONFIG_COUNTER # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) #else # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) #endif #include #include #include // We need a dummy global operator<< so we can bring it into Catch namespace later struct Catch_global_namespace_dummy {}; std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy); namespace Catch { struct CaseSensitive { enum Choice { Yes, No }; }; class NonCopyable { NonCopyable( NonCopyable const& ) = delete; NonCopyable( NonCopyable && ) = delete; NonCopyable& operator = ( NonCopyable const& ) = delete; NonCopyable& operator = ( NonCopyable && ) = delete; protected: NonCopyable(); virtual ~NonCopyable(); }; struct SourceLineInfo { SourceLineInfo() = delete; SourceLineInfo( char const* _file, std::size_t _line ) noexcept : file( _file ), line( _line ) {} SourceLineInfo( SourceLineInfo const& other ) = default; SourceLineInfo& operator = ( SourceLineInfo const& ) = default; SourceLineInfo( SourceLineInfo&& ) = default; SourceLineInfo& operator = ( SourceLineInfo&& ) = default; bool empty() const noexcept { return file[0] == '\0'; } bool operator == ( SourceLineInfo const& other ) const noexcept; bool operator < ( SourceLineInfo const& other ) const noexcept; char const* file; std::size_t line; }; std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); // Bring in operator<< from global namespace into Catch namespace // This is necessary because the overload of operator<< above makes // lookup stop at namespace Catch using ::operator<<; // Use this in variadic streaming macros to allow // >> +StreamEndStop // as well as // >> stuff +StreamEndStop struct StreamEndStop { std::string operator+() const; }; template T const& operator + ( T const& value, StreamEndStop ) { return value; } } #define CATCH_INTERNAL_LINEINFO \ ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) // end catch_common.h namespace Catch { struct RegistrarForTagAliases { RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); }; } // end namespace Catch #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION // end catch_tag_alias_autoregistrar.h // start catch_test_registry.h // start catch_interfaces_testcase.h #include namespace Catch { class TestSpec; struct ITestInvoker { virtual void invoke () const = 0; virtual ~ITestInvoker(); }; class TestCase; struct IConfig; struct ITestCaseRegistry { virtual ~ITestCaseRegistry(); virtual std::vector const& getAllTests() const = 0; virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; }; bool isThrowSafe( TestCase const& testCase, IConfig const& config ); bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); std::vector const& getAllTestCasesSorted( IConfig const& config ); } // end catch_interfaces_testcase.h // start catch_stringref.h #include #include #include #include namespace Catch { /// A non-owning string class (similar to the forthcoming std::string_view) /// Note that, because a StringRef may be a substring of another string, /// it may not be null terminated. class StringRef { public: using size_type = std::size_t; using const_iterator = const char*; private: static constexpr char const* const s_empty = ""; char const* m_start = s_empty; size_type m_size = 0; public: // construction constexpr StringRef() = default; StringRef( char const* rawChars ) noexcept; constexpr StringRef( char const* rawChars, size_type size ) noexcept : m_start( rawChars ), m_size( size ) {} StringRef( std::string const& stdString ) noexcept : m_start( stdString.c_str() ), m_size( stdString.size() ) {} explicit operator std::string() const { return std::string(m_start, m_size); } public: // operators auto operator == ( StringRef const& other ) const noexcept -> bool; auto operator != (StringRef const& other) const noexcept -> bool { return !(*this == other); } auto operator[] ( size_type index ) const noexcept -> char { assert(index < m_size); return m_start[index]; } public: // named queries constexpr auto empty() const noexcept -> bool { return m_size == 0; } constexpr auto size() const noexcept -> size_type { return m_size; } // Returns the current start pointer. If the StringRef is not // null-terminated, throws std::domain_exception auto c_str() const -> char const*; public: // substrings and searches // Returns a substring of [start, start + length). // If start + length > size(), then the substring is [start, size()). // If start > size(), then the substring is empty. auto substr( size_type start, size_type length ) const noexcept -> StringRef; // Returns the current start pointer. May not be null-terminated. auto data() const noexcept -> char const*; constexpr auto isNullTerminated() const noexcept -> bool { return m_start[m_size] == '\0'; } public: // iterators constexpr const_iterator begin() const { return m_start; } constexpr const_iterator end() const { return m_start + m_size; } }; auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&; auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&; constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { return StringRef( rawChars, size ); } } // namespace Catch constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef { return Catch::StringRef( rawChars, size ); } // end catch_stringref.h // start catch_preprocessor.hpp #define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__ #define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__))) #define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__))) #define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__))) #define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__))) #define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__))) #ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__ // MSVC needs more evaluations #define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__))) #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__)) #else #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__) #endif #define CATCH_REC_END(...) #define CATCH_REC_OUT #define CATCH_EMPTY() #define CATCH_DEFER(id) id CATCH_EMPTY() #define CATCH_REC_GET_END2() 0, CATCH_REC_END #define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2 #define CATCH_REC_GET_END(...) CATCH_REC_GET_END1 #define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT #define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0) #define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next) #define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) #define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ ) #define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) #define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) #define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ ) #define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) // Applies the function macro `f` to each of the remaining parameters, inserts commas between the results, // and passes userdata as the first parameter to each invocation, // e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c) #define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) #define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF #define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__) #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__ #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) #else // MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF #define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__) #define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__ #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1) #endif #define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__ #define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name) #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__) #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper()) #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)) #else #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper())) #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) #endif #define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\ CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__) #define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0) #define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1) #define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2) #define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) #define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) #define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) #define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6) #define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) #define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) #define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) #define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) #define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N #define INTERNAL_CATCH_TYPE_GEN\ template struct TypeList {};\ template\ constexpr auto get_wrapper() noexcept -> TypeList { return {}; }\ template class...> struct TemplateTypeList{};\ template class...Cs>\ constexpr auto get_wrapper() noexcept -> TemplateTypeList { return {}; }\ template\ struct append;\ template\ struct rewrap;\ template class, typename...>\ struct create;\ template class, typename>\ struct convert;\ \ template \ struct append { using type = T; };\ template< template class L1, typename...E1, template class L2, typename...E2, typename...Rest>\ struct append, L2, Rest...> { using type = typename append, Rest...>::type; };\ template< template class L1, typename...E1, typename...Rest>\ struct append, TypeList, Rest...> { using type = L1; };\ \ template< template class Container, template class List, typename...elems>\ struct rewrap, List> { using type = TypeList>; };\ template< template class Container, template class List, class...Elems, typename...Elements>\ struct rewrap, List, Elements...> { using type = typename append>, typename rewrap, Elements...>::type>::type; };\ \ template